Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/i915/i915_state_derived.c
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2003 VMware, Inc.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
#include "draw/draw_context.h"
29
#include "draw/draw_vertex.h"
30
#include "pipe/p_shader_tokens.h"
31
#include "util/u_memory.h"
32
#include "i915_context.h"
33
#include "i915_debug.h"
34
#include "i915_fpc.h"
35
#include "i915_reg.h"
36
#include "i915_state.h"
37
38
static uint32_t
39
find_mapping(const struct i915_fragment_shader *fs, int unit)
40
{
41
int i;
42
for (i = 0; i < I915_TEX_UNITS; i++) {
43
if (fs->generic_mapping[i] == unit)
44
return i;
45
}
46
debug_printf("Mapping not found\n");
47
return 0;
48
}
49
50
/***********************************************************************
51
* Determine the hardware vertex layout.
52
* Depends on vertex/fragment shader state.
53
*/
54
static void
55
calculate_vertex_layout(struct i915_context *i915)
56
{
57
const struct i915_fragment_shader *fs = i915->fs;
58
struct vertex_info vinfo;
59
bool texCoords[I915_TEX_UNITS], colors[2], fog, needW, face;
60
uint32_t i;
61
int src;
62
63
memset(texCoords, 0, sizeof(texCoords));
64
colors[0] = colors[1] = fog = needW = face = false;
65
memset(&vinfo, 0, sizeof(vinfo));
66
67
/* Determine which fragment program inputs are needed. Setup HW vertex
68
* layout below, in the HW-specific attribute order.
69
*/
70
for (i = 0; i < fs->info.num_inputs; i++) {
71
switch (fs->info.input_semantic_name[i]) {
72
case TGSI_SEMANTIC_POSITION: {
73
uint32_t unit = I915_SEMANTIC_POS;
74
texCoords[find_mapping(fs, unit)] = true;
75
} break;
76
case TGSI_SEMANTIC_COLOR:
77
assert(fs->info.input_semantic_index[i] < 2);
78
colors[fs->info.input_semantic_index[i]] = true;
79
break;
80
case TGSI_SEMANTIC_GENERIC: {
81
/* texcoords/varyings/other generic */
82
uint32_t unit = fs->info.input_semantic_index[i];
83
84
texCoords[find_mapping(fs, unit)] = true;
85
needW = true;
86
} break;
87
case TGSI_SEMANTIC_FOG:
88
fog = true;
89
break;
90
case TGSI_SEMANTIC_FACE:
91
face = true;
92
break;
93
default:
94
debug_printf("Unknown input type %d\n",
95
fs->info.input_semantic_name[i]);
96
assert(0);
97
}
98
}
99
100
/* pos */
101
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
102
if (needW) {
103
draw_emit_vertex_attr(&vinfo, EMIT_4F, src);
104
vinfo.hwfmt[0] |= S4_VFMT_XYZW;
105
vinfo.attrib[0].emit = EMIT_4F;
106
} else {
107
draw_emit_vertex_attr(&vinfo, EMIT_3F, src);
108
vinfo.hwfmt[0] |= S4_VFMT_XYZ;
109
vinfo.attrib[0].emit = EMIT_3F;
110
}
111
112
/* point size. if not emitted here, then point size comes from LIS4. */
113
if (i915->rasterizer->templ.point_size_per_vertex) {
114
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_PSIZE, 0);
115
if (src != -1) {
116
draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
117
vinfo.hwfmt[0] |= S4_VFMT_POINT_WIDTH;
118
}
119
}
120
121
/* primary color */
122
if (colors[0]) {
123
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
124
draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);
125
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
126
}
127
128
/* secondary color */
129
if (colors[1]) {
130
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
131
draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);
132
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
133
}
134
135
/* fog coord, not fog blend factor */
136
if (fog) {
137
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
138
draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
139
vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
140
}
141
142
/* texcoords/varyings */
143
for (i = 0; i < I915_TEX_UNITS; i++) {
144
uint32_t hwtc;
145
if (texCoords[i]) {
146
hwtc = TEXCOORDFMT_4D;
147
if (fs->generic_mapping[i] == I915_SEMANTIC_POS) {
148
src =
149
draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
150
} else {
151
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC,
152
fs->generic_mapping[i]);
153
}
154
draw_emit_vertex_attr(&vinfo, EMIT_4F, src);
155
} else {
156
hwtc = TEXCOORDFMT_NOT_PRESENT;
157
}
158
vinfo.hwfmt[1] |= hwtc << (i * 4);
159
}
160
161
/* front/back face */
162
if (face) {
163
uint32_t slot = find_mapping(fs, I915_SEMANTIC_FACE);
164
debug_printf("Front/back face is broken\n");
165
/* XXX Because of limitations in the draw module, currently src will be 0
166
* for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw
167
* module by adding an extra shader output.
168
*/
169
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0);
170
draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
171
vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4));
172
vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4);
173
}
174
175
draw_compute_vertex_size(&vinfo);
176
177
if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
178
/* Need to set this flag so that the LIS2/4 registers get set.
179
* It also means the i915_update_immediate() function must be called
180
* after this one, in i915_update_derived().
181
*/
182
i915->dirty |= I915_NEW_VERTEX_FORMAT;
183
184
memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));
185
}
186
}
187
188
struct i915_tracked_state i915_update_vertex_layout = {
189
"vertex_layout", calculate_vertex_layout,
190
I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS};
191
192
/***********************************************************************
193
*/
194
static struct i915_tracked_state *atoms[] = {
195
&i915_update_vertex_layout, &i915_hw_samplers, &i915_hw_immediate,
196
&i915_hw_dynamic, &i915_hw_fs, &i915_hw_framebuffer,
197
&i915_hw_dst_buf_vars, &i915_hw_constants, NULL,
198
};
199
200
void
201
i915_update_derived(struct i915_context *i915)
202
{
203
int i;
204
205
if (I915_DBG_ON(DBG_ATOMS))
206
i915_dump_dirty(i915, __FUNCTION__);
207
208
if (!i915->fs) {
209
i915->dirty &= ~(I915_NEW_FS_CONSTANTS | I915_NEW_FS);
210
i915->hardware_dirty &= ~(I915_HW_PROGRAM | I915_HW_CONSTANTS);
211
}
212
213
if (!i915->vs)
214
i915->dirty &= ~I915_NEW_VS;
215
216
if (!i915->blend)
217
i915->dirty &= ~I915_NEW_BLEND;
218
219
if (!i915->rasterizer)
220
i915->dirty &= ~I915_NEW_RASTERIZER;
221
222
if (!i915->depth_stencil)
223
i915->dirty &= ~I915_NEW_DEPTH_STENCIL;
224
225
for (i = 0; atoms[i]; i++)
226
if (atoms[i]->dirty & i915->dirty)
227
atoms[i]->update(i915);
228
229
i915->dirty = 0;
230
}
231
232