#include "draw/draw_vertex.h"
#include "i915_context.h"
#include "i915_state.h"
-#include "i915_reg.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
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_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
if (needW) {
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
vinfo.hwfmt[0] |= S4_VFMT_XYZW;
/* primary color */
if (colors[0]) {
- src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
/* secondary color */
if (colors[1]) {
- src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
/* fog coord, not fog blend factor */
if (fog) {
- src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
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_vs_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 {
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))) {
}
}
+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_TEXTURE))
- i915_update_samplers(i915);
+ int i;
- if (i915->dirty & I915_NEW_TEXTURE)
- i915_update_textures(i915);
+ if (I915_DBG_ON(DBG_ATOMS))
+ i915_dump_dirty(i915, __FUNCTION__);
- if (i915->dirty)
- i915_update_immediate( i915 );
-
- 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;
}