X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fi915%2Fi915_state_derived.c;h=e01f16e715ce9035bed822439b6b8f5cf051b0c6;hb=49ed1f3cb335fada1f9ee26d5420889292da3c92;hp=4da46772b5d8e049b806214b37e3b58c54474a97;hpb=feb619b7705897ca723e8fe728f739932f743327;p=mesa.git diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index 4da46772b5d..e01f16e715c 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -32,25 +32,39 @@ #include "draw/draw_vertex.h" #include "i915_context.h" #include "i915_state.h" +#include "i915_debug.h" +#include "i915_fpc.h" #include "i915_reg.h" +static uint find_mapping(const struct i915_fragment_shader* fs, int unit) +{ + int i; + for (i = 0; i < I915_TEX_UNITS ; i++) + { + if (fs->generic_mapping[i] == unit) + return i; + } + debug_printf("Mapping not found\n"); + return 0; +} -/** + +/*********************************************************************** * Determine the hardware vertex layout. * Depends on vertex/fragment shader state. */ -static void calculate_vertex_layout( struct i915_context *i915 ) +static void calculate_vertex_layout(struct i915_context *i915) { const struct i915_fragment_shader *fs = i915->fs; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; - boolean texCoords[8], colors[2], fog, needW; + boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face; uint i; int src; memset(texCoords, 0, sizeof(texCoords)); - colors[0] = colors[1] = fog = needW = FALSE; + colors[0] = colors[1] = fog = needW = face = FALSE; memset(&vinfo, 0, sizeof(vinfo)); /* Determine which fragment program inputs are needed. Setup HW vertex @@ -59,29 +73,37 @@ static void calculate_vertex_layout( struct i915_context *i915 ) for (i = 0; i < fs->info.num_inputs; i++) { switch (fs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: + { + uint unit = I915_SEMANTIC_POS; + texCoords[find_mapping(fs, unit)] = TRUE; + } break; case TGSI_SEMANTIC_COLOR: assert(fs->info.input_semantic_index[i] < 2); colors[fs->info.input_semantic_index[i]] = TRUE; break; case TGSI_SEMANTIC_GENERIC: - /* usually a texcoord */ { - const uint unit = fs->info.input_semantic_index[i]; - assert(unit < 8); - texCoords[unit] = TRUE; + /* texcoords/varyings/other generic */ + uint unit = fs->info.input_semantic_index[i]; + + texCoords[find_mapping(fs, unit)] = TRUE; needW = TRUE; } break; case TGSI_SEMANTIC_FOG: fog = TRUE; break; + case TGSI_SEMANTIC_FACE: + face = TRUE; + break; default: + debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]); assert(0); } } - + /* pos */ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); if (needW) { @@ -119,12 +141,12 @@ static void calculate_vertex_layout( struct i915_context *i915 ) vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; } - /* texcoords */ - for (i = 0; i < 8; i++) { + /* texcoords/varyings */ + for (i = 0; i < I915_TEX_UNITS; i++) { uint hwtc; if (texCoords[i]) { hwtc = TEXCOORDFMT_4D; - src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, i); + src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, fs->generic_mapping[i]); draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); } else { @@ -133,6 +155,20 @@ static void calculate_vertex_layout( struct i915_context *i915 ) vinfo.hwfmt[1] |= hwtc << (i * 4); } + /* front/back face */ + if (face) { + uint slot = find_mapping(fs, I915_SEMANTIC_FACE); + debug_printf("Front/back face is broken\n"); + /* XXX Because of limitations in the draw module, currently src will be 0 + * for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw + * module by adding an extra shader output. + */ + src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0); + draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src); + vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4)); + vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4); + } + draw_compute_vertex_size(&vinfo); if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { @@ -146,37 +182,39 @@ static void calculate_vertex_layout( struct i915_context *i915 ) } } +struct i915_tracked_state i915_update_vertex_layout = { + "vertex_layout", + calculate_vertex_layout, + I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS +}; -/* Hopefully this will remain quite simple, otherwise need to pull in - * something like the state tracker mechanism. +/*********************************************************************** */ -void i915_update_derived( struct i915_context *i915 ) +static struct i915_tracked_state *atoms[] = { + &i915_update_vertex_layout, + &i915_hw_samplers, + &i915_hw_sampler_views, + &i915_hw_immediate, + &i915_hw_dynamic, + &i915_hw_fs, + &i915_hw_framebuffer, + &i915_hw_dst_buf_vars, + &i915_hw_constants, + NULL, +}; + +void i915_update_derived(struct i915_context *i915) { - if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS)) - calculate_vertex_layout( i915 ); - - if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW)) - i915_update_samplers(i915); - - if (i915->dirty & I915_NEW_SAMPLER_VIEW) - i915_update_textures(i915); + int i; - if (i915->dirty) - i915_update_immediate( i915 ); + if (I915_DBG_ON(DBG_ATOMS)) + i915_dump_dirty(i915, __FUNCTION__); - if (i915->dirty) - i915_update_dynamic( i915 ); - - if (i915->dirty & I915_NEW_FS) { - i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ - } - - /* HW emit currently references framebuffer state directly: - */ - if (i915->dirty & I915_NEW_FRAMEBUFFER) - i915->hardware_dirty |= I915_HW_STATIC; + for (i = 0; atoms[i]; i++) + if (atoms[i]->dirty & i915->dirty) + atoms[i]->update(i915); i915->dirty = 0; }