gallium/i915: use draw_find_vs_output() directly, fix broken fogcoords.

We now produce the correct 915 vertex layout regardless of the order in
which fragment shader inputs are declared.
This commit is contained in:
Brian 2008-02-25 14:48:31 -07:00
parent c037b4d45a
commit 846b7fbc6c
1 changed files with 53 additions and 46 deletions

View File

@ -27,104 +27,111 @@
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "draw/draw_vertex.h"
#include "i915_context.h"
#include "i915_state.h"
#include "i915_reg.h"
#include "i915_fpc.h"
#include "pipe/p_shader_tokens.h"
/**
* Determine which post-transform / pre-rasterization vertex attributes
* we need.
* Derived from: fs, setup states.
* Determine the hardware vertex layout.
* Depends on vertex/fragment shader state.
*/
static void calculate_vertex_layout( struct i915_context *i915 )
{
const struct pipe_shader_state *fs = &i915->fs->state;
const enum interp_mode colorInterp = i915->rasterizer->color_interp;
struct vertex_info vinfo;
uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
boolean needW = 0;
boolean texCoords[8], colors[2], fog, needW;
uint i;
boolean texCoords[8];
uint src = 0;
int src;
memset(texCoords, 0, sizeof(texCoords));
colors[0] = colors[1] = fog = needW = FALSE;
memset(&vinfo, 0, sizeof(vinfo));
/* pos */
draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src++);
/* Note: we'll set the S4_VFMT_XYZ[W] bits below */
/* Determine which fragment program inputs are needed. Setup HW vertex
* layout below, in the HW-specific attribute order.
*/
for (i = 0; i < fs->num_inputs; i++) {
switch (fs->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
break;
case TGSI_SEMANTIC_COLOR:
if (fs->input_semantic_index[i] == 0) {
front0 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
else {
assert(fs->input_semantic_index[i] == 1);
front1 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
assert(fs->input_semantic_index[i] < 2);
colors[fs->input_semantic_index[i]] = TRUE;
break;
case TGSI_SEMANTIC_GENERIC:
/* usually a texcoord */
{
const uint unit = fs->input_semantic_index[i];
uint hwtc;
assert(unit < 8);
texCoords[unit] = TRUE;
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
hwtc = TEXCOORDFMT_4D;
needW = TRUE;
vinfo.hwfmt[1] |= hwtc << (unit * 4);
}
break;
case TGSI_SEMANTIC_FOG:
debug_printf("i915 fogcoord not implemented yet\n");
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++);
fog = TRUE;
break;
default:
assert(0);
}
}
/* finish up texcoord fields */
for (i = 0; i < 8; i++) {
if (!texCoords[i]) {
const uint hwtc = TEXCOORDFMT_NOT_PRESENT;
vinfo.hwfmt[1] |= hwtc << (i* 4);
}
}
/* go back and fill in the vertex position info now that we have needW */
/* pos */
src = draw_find_vs_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;
vinfo.emit[0] = EMIT_4F;
}
else {
draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src);
vinfo.hwfmt[0] |= S4_VFMT_XYZ;
vinfo.emit[0] = EMIT_3F;
}
/* Additional attributes required for setup: Just twosided
* lighting. Edgeflag is dealt with specially by setting bits in
* the vertex header.
*/
if (i915->rasterizer->light_twoside) {
if (front0) {
back0 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
/* hardware point size */
/* XXX todo */
/* 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);
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);
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);
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
}
/* texcoords */
for (i = 0; i < 8; i++) {
uint hwtc;
if (texCoords[i]) {
hwtc = TEXCOORDFMT_4D;
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
}
if (back0) {
back1 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
else {
hwtc = TEXCOORDFMT_NOT_PRESENT;
}
vinfo.hwfmt[1] |= hwtc << (i * 4);
}
draw_compute_vertex_size(&vinfo);