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/log.h"
32 #include "util/u_memory.h"
33 #include "i915_context.h"
34 #include "i915_debug.h"
35 #include "i915_fpc.h"
36 #include "i915_reg.h"
37 #include "i915_state.h"
38
39
40 /***********************************************************************
41 * Determine the hardware vertex layout.
42 * Depends on vertex/fragment shader state.
43 */
44 static void
calculate_vertex_layout(struct i915_context * i915)45 calculate_vertex_layout(struct i915_context *i915)
46 {
47 const struct i915_fragment_shader *fs = i915->fs;
48 struct vertex_info vinfo;
49 bool colors[2], fog, needW, face;
50 uint32_t i;
51 int src;
52
53 colors[0] = colors[1] = fog = needW = face = false;
54 memset(&vinfo, 0, sizeof(vinfo));
55
56 /* Determine which fragment program inputs are needed. Setup HW vertex
57 * layout below, in the HW-specific attribute order.
58 */
59 for (i = 0; i < fs->info.num_inputs; i++) {
60 switch (fs->info.input_semantic_name[i]) {
61 case TGSI_SEMANTIC_POSITION:
62 case TGSI_SEMANTIC_PCOORD:
63 case TGSI_SEMANTIC_FACE:
64 /* Handled as texcoord inputs below */
65 break;
66 case TGSI_SEMANTIC_COLOR:
67 assert(fs->info.input_semantic_index[i] < 2);
68 colors[fs->info.input_semantic_index[i]] = true;
69 break;
70 case TGSI_SEMANTIC_TEXCOORD:
71 case TGSI_SEMANTIC_GENERIC:
72 needW = true;
73 break;
74 case TGSI_SEMANTIC_FOG:
75 fog = true;
76 break;
77 default:
78 debug_printf("Unknown input type %d\n",
79 fs->info.input_semantic_name[i]);
80 assert(0);
81 }
82 }
83
84 /* pos */
85 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
86 if (needW) {
87 draw_emit_vertex_attr(&vinfo, EMIT_4F, src);
88 vinfo.hwfmt[0] |= S4_VFMT_XYZW;
89 vinfo.attrib[0].emit = EMIT_4F;
90 } else {
91 draw_emit_vertex_attr(&vinfo, EMIT_3F, src);
92 vinfo.hwfmt[0] |= S4_VFMT_XYZ;
93 vinfo.attrib[0].emit = EMIT_3F;
94 }
95
96 /* point size. if not emitted here, then point size comes from LIS4. */
97 if (i915->rasterizer->templ.point_size_per_vertex) {
98 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_PSIZE, 0);
99 if (src != -1) {
100 draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
101 vinfo.hwfmt[0] |= S4_VFMT_POINT_WIDTH;
102 }
103 }
104
105 /* primary color */
106 if (colors[0]) {
107 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
108 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);
109 vinfo.hwfmt[0] |= S4_VFMT_COLOR;
110 }
111
112 /* secondary color */
113 if (colors[1]) {
114 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
115 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);
116 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
117 }
118
119 /* fog coord, not fog blend factor */
120 if (fog) {
121 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
122 draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
123 vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
124 }
125
126 /* texcoords/varyings */
127 for (i = 0; i < I915_TEX_UNITS; i++) {
128 uint32_t hwtc;
129 if (fs->texcoords[i].semantic != -1) {
130 src = draw_find_shader_output(i915->draw, fs->texcoords[i].semantic,
131 fs->texcoords[i].index);
132 if (fs->texcoords[i].semantic == TGSI_SEMANTIC_FACE) {
133 /* XXX Because of limitations in the draw module, currently src will
134 * be 0 for SEMANTIC_FACE, so this aliases to POS. We need to fix in
135 * the draw module by adding an extra shader output.
136 */
137 mesa_loge("Front/back face is broken\n");
138 draw_emit_vertex_attr(&vinfo, EMIT_1F, src);
139 hwtc = TEXCOORDFMT_1D;
140 } else {
141 hwtc = TEXCOORDFMT_4D;
142 draw_emit_vertex_attr(&vinfo, EMIT_4F, src);
143 }
144 } else {
145 hwtc = TEXCOORDFMT_NOT_PRESENT;
146 }
147 vinfo.hwfmt[1] |= hwtc << (i * 4);
148 }
149
150 draw_compute_vertex_size(&vinfo);
151
152 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
153 /* Need to set this flag so that the LIS2/4 registers get set.
154 * It also means the i915_update_immediate() function must be called
155 * after this one, in i915_update_derived().
156 */
157 i915->dirty |= I915_NEW_VERTEX_FORMAT;
158
159 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));
160 }
161 }
162
163 struct i915_tracked_state i915_update_vertex_layout = {
164 "vertex_layout", calculate_vertex_layout,
165 I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS};
166
167 /***********************************************************************
168 */
169 static struct i915_tracked_state *atoms[] = {
170 &i915_update_vertex_layout, &i915_hw_samplers, &i915_hw_immediate,
171 &i915_hw_dynamic, &i915_hw_fs, &i915_hw_framebuffer,
172 &i915_hw_dst_buf_vars, &i915_hw_constants, NULL,
173 };
174
175 void
i915_update_derived(struct i915_context * i915)176 i915_update_derived(struct i915_context *i915)
177 {
178 int i;
179
180 if (I915_DBG_ON(DBG_ATOMS))
181 i915_dump_dirty(i915, __FUNCTION__);
182
183 if (!i915->fs) {
184 i915->dirty &= ~(I915_NEW_FS_CONSTANTS | I915_NEW_FS);
185 i915->hardware_dirty &= ~(I915_HW_PROGRAM | I915_HW_CONSTANTS);
186 }
187
188 if (!i915->vs)
189 i915->dirty &= ~I915_NEW_VS;
190
191 if (!i915->blend)
192 i915->dirty &= ~I915_NEW_BLEND;
193
194 if (!i915->rasterizer)
195 i915->dirty &= ~I915_NEW_RASTERIZER;
196
197 if (!i915->depth_stencil)
198 i915->dirty &= ~I915_NEW_DEPTH_STENCIL;
199
200 for (i = 0; atoms[i]; i++)
201 if (atoms[i]->dirty & i915->dirty)
202 atoms[i]->update(i915);
203
204 i915->dirty = 0;
205 }
206