Go to the source code of this file.
Functions | |
static void | calculate_vertex_layout (struct i915_context *i915) |
Determine the hardware vertex layout. | |
void | i915_update_derived (struct i915_context *i915) |
static void calculate_vertex_layout | ( | struct i915_context * | i915 | ) | [static] |
Determine the hardware vertex layout.
Depends on vertex/fragment shader state.
Definition at line 44 of file i915_state_derived.c.
References assert, vertex_info::attrib, i915_rasterizer_state::color_interp, i915_context::current, i915_context::dirty, i915_context::draw, draw_compute_vertex_size(), draw_emit_vertex_attr(), draw_find_vs_output(), vertex_info::emit, EMIT_1F, EMIT_3F, EMIT_4F, EMIT_4UB, FALSE, i915_context::fs, vertex_info::hwfmt, I915_NEW_VERTEX_FORMAT, i915_fragment_shader::info, tgsi_shader_info::input_semantic_index, tgsi_shader_info::input_semantic_name, INTERP_LINEAR, INTERP_PERSPECTIVE, tgsi_shader_info::num_inputs, i915_context::rasterizer, S4_VFMT_COLOR, S4_VFMT_FOG_PARAM, S4_VFMT_SPEC_FOG, S4_VFMT_XYZ, S4_VFMT_XYZW, TEXCOORDFMT_4D, TEXCOORDFMT_NOT_PRESENT, TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_FOG, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, TRUE, and i915_state::vertex_info.
00045 { 00046 const struct i915_fragment_shader *fs = i915->fs; 00047 const enum interp_mode colorInterp = i915->rasterizer->color_interp; 00048 struct vertex_info vinfo; 00049 boolean texCoords[8], colors[2], fog, needW; 00050 uint i; 00051 int src; 00052 00053 memset(texCoords, 0, sizeof(texCoords)); 00054 colors[0] = colors[1] = fog = needW = FALSE; 00055 memset(&vinfo, 0, sizeof(vinfo)); 00056 00057 /* Determine which fragment program inputs are needed. Setup HW vertex 00058 * layout below, in the HW-specific attribute order. 00059 */ 00060 for (i = 0; i < fs->info.num_inputs; i++) { 00061 switch (fs->info.input_semantic_name[i]) { 00062 case TGSI_SEMANTIC_POSITION: 00063 break; 00064 case TGSI_SEMANTIC_COLOR: 00065 assert(fs->info.input_semantic_index[i] < 2); 00066 colors[fs->info.input_semantic_index[i]] = TRUE; 00067 break; 00068 case TGSI_SEMANTIC_GENERIC: 00069 /* usually a texcoord */ 00070 { 00071 const uint unit = fs->info.input_semantic_index[i]; 00072 assert(unit < 8); 00073 texCoords[unit] = TRUE; 00074 needW = TRUE; 00075 } 00076 break; 00077 case TGSI_SEMANTIC_FOG: 00078 fog = TRUE; 00079 break; 00080 default: 00081 assert(0); 00082 } 00083 } 00084 00085 00086 /* pos */ 00087 src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); 00088 if (needW) { 00089 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src); 00090 vinfo.hwfmt[0] |= S4_VFMT_XYZW; 00091 vinfo.attrib[0].emit = EMIT_4F; 00092 } 00093 else { 00094 draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src); 00095 vinfo.hwfmt[0] |= S4_VFMT_XYZ; 00096 vinfo.attrib[0].emit = EMIT_3F; 00097 } 00098 00099 /* hardware point size */ 00100 /* XXX todo */ 00101 00102 /* primary color */ 00103 if (colors[0]) { 00104 src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); 00105 draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src); 00106 vinfo.hwfmt[0] |= S4_VFMT_COLOR; 00107 } 00108 00109 /* secondary color */ 00110 if (colors[1]) { 00111 src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); 00112 draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src); 00113 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; 00114 } 00115 00116 /* fog coord, not fog blend factor */ 00117 if (fog) { 00118 src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0); 00119 draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); 00120 vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; 00121 } 00122 00123 /* texcoords */ 00124 for (i = 0; i < 8; i++) { 00125 uint hwtc; 00126 if (texCoords[i]) { 00127 hwtc = TEXCOORDFMT_4D; 00128 src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i); 00129 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); 00130 } 00131 else { 00132 hwtc = TEXCOORDFMT_NOT_PRESENT; 00133 } 00134 vinfo.hwfmt[1] |= hwtc << (i * 4); 00135 } 00136 00137 draw_compute_vertex_size(&vinfo); 00138 00139 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { 00140 /* Need to set this flag so that the LIS2/4 registers get set. 00141 * It also means the i915_update_immediate() function must be called 00142 * after this one, in i915_update_derived(). 00143 */ 00144 i915->dirty |= I915_NEW_VERTEX_FORMAT; 00145 00146 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); 00147 } 00148 }
void i915_update_derived | ( | struct i915_context * | i915 | ) |
Definition at line 156 of file i915_state_derived.c.
References calculate_vertex_layout(), i915_context::dirty, i915_context::hardware_dirty, I915_HW_PROGRAM, I915_HW_STATIC, I915_NEW_FRAMEBUFFER, I915_NEW_FS, I915_NEW_RASTERIZER, I915_NEW_SAMPLER, I915_NEW_TEXTURE, I915_NEW_VS, i915_update_dynamic(), i915_update_immediate(), i915_update_samplers(), and i915_update_textures().
00157 { 00158 if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS)) 00159 calculate_vertex_layout( i915 ); 00160 00161 if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE)) 00162 i915_update_samplers(i915); 00163 00164 if (i915->dirty & I915_NEW_TEXTURE) 00165 i915_update_textures(i915); 00166 00167 if (i915->dirty) 00168 i915_update_immediate( i915 ); 00169 00170 if (i915->dirty) 00171 i915_update_dynamic( i915 ); 00172 00173 if (i915->dirty & I915_NEW_FS) { 00174 i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ 00175 } 00176 00177 /* HW emit currently references framebuffer state directly: 00178 */ 00179 if (i915->dirty & I915_NEW_FRAMEBUFFER) 00180 i915->hardware_dirty |= I915_HW_STATIC; 00181 00182 i915->dirty = 0; 00183 }