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