summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2008-01-23 23:08:59 -0700
committerBrian <[email protected]>2008-01-23 23:08:59 -0700
commit6000dcc973cdc1bd61621b432aed27d21059ae5d (patch)
treeb0995cac257f0da72d4e844da4a4b623ffbeef83
parentdc1abc393206c3eb00e7cca60ce3499c993bc1f6 (diff)
gallium: improved vertex layout and interpolant setup in softpipe
-rw-r--r--src/mesa/pipe/draw/draw_vertex.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h4
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c217
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_vbuf.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c55
5 files changed, 123 insertions, 159 deletions
diff --git a/src/mesa/pipe/draw/draw_vertex.h b/src/mesa/pipe/draw/draw_vertex.h
index e76a17c198b..7e9d8abcce1 100644
--- a/src/mesa/pipe/draw/draw_vertex.h
+++ b/src/mesa/pipe/draw/draw_vertex.h
@@ -36,6 +36,7 @@
/**
* Vertex attribute format
+ * XXX rename to "EMIT"
*/
enum attrib_format {
FORMAT_OMIT, /**< don't emit the attribute */
@@ -54,6 +55,7 @@ enum attrib_format {
*/
enum interp_mode {
INTERP_NONE, /**< never interpolate vertex header info */
+ INTERP_POS, /**< special case for frag position */
INTERP_CONSTANT,
INTERP_LINEAR,
INTERP_PERSPECTIVE
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index daf7dd5accc..aff8c2cc5dc 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -89,8 +89,8 @@ struct softpipe_context {
/** Vertex format */
struct vertex_info vertex_info;
- unsigned attr_mask;
- unsigned nr_frag_attrs; /**< number of active fragment attribs */
+ struct vertex_info vertex_info_vbuf;
+
int psize_slot;
#if 0
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
index 4b6b7a0fd12..478ecff2fb5 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.c
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.c
@@ -85,8 +85,6 @@ struct setup_stage {
struct tgsi_interp_coef posCoef; /* For Z, W */
struct quad_header quad;
- uint firstFpInput; /** Semantic type of first frag input */
-
struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
@@ -515,22 +513,10 @@ setup_fragcoord_coeff(struct setup_stage *setup)
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
- const enum interp_mode *interp;
-#define USE_INPUT_MAP 01
-#if USE_INPUT_MAP
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
-#endif
+ const struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
uint fragSlot;
- if (setup->softpipe->vertex_info.format[0] == FORMAT_HEADER) {
- /* skip header, pos slots */
- interp = setup->softpipe->vertex_info.interp_mode + 2;
- }
- else {
- /* skip pos slot */
- interp = setup->softpipe->vertex_info.interp_mode + 1;
- }
-
/* z and w are done by linear interpolation:
*/
tri_linear_coeff(setup, &setup->posCoef, 0, 2);
@@ -538,64 +524,37 @@ static void setup_tri_coefficients( struct setup_stage *setup )
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
-#if !USE_INPUT_MAP
- uint vertSlot;
- if (setup->firstFpInput == TGSI_SEMANTIC_POSITION) {
- if (fragSlot == 0) {
- setup_fragcoord_coeff(setup);
- continue;
- }
- vertSlot = fragSlot;
- }
- else {
- vertSlot = fragSlot + 1;
- }
-
-#else
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
- /* XXX with a new INTERP_POSITION token, we could just add a
- * new case to the switch below.
- */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
-#endif
- uint j;
- switch (interp[fragSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- /* invalid interp mode */
- /* assert(0); re-enable this and run demos/fogcoord.c ... */
- ;
- }
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
- /* FOG.y = front/back facing XXX fix this */
- setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
- setup->coef[fragSlot].dadx[1] = 0.0;
- setup->coef[fragSlot].dady[1] = 0.0;
- }
-
-
-#if USE_INPUT_MAP
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
-#endif
}
}
@@ -797,9 +756,9 @@ line_persp_coeff(struct setup_stage *setup,
static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ const struct softpipe_context *softpipe = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- unsigned fragSlot;
+ uint fragSlot;
/* use setup->vmin, vmax to point to vertices */
setup->vprovoke = prim->v[1];
@@ -819,34 +778,37 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
-
- default:
- /* invalid interp mode */
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
}
@@ -1005,8 +967,8 @@ static void
setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
const struct vertex_header *v0 = prim->v[0];
const int sizeAttr = setup->softpipe->psize_slot;
const float size
@@ -1040,31 +1002,36 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const_coeff(setup, &setup->posCoef, 0, 2);
const_coeff(setup, &setup->posCoef, 0, 3);
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ /* fall-through */
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ point_persp_coeff(setup, setup->vprovoke,
+ &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- /* fall-through */
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- point_persp_coeff(setup, setup->vprovoke,
- &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
@@ -1200,9 +1167,7 @@ static void setup_begin( struct draw_stage *stage )
struct softpipe_context *sp = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
-
- setup->firstFpInput = fs->input_semantic_name[0];
+ setup->quad.nr_attrs = fs->num_inputs;
sp->quad.first->begin(sp->quad.first);
}
diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
index 0ab8a55d7d4..dfabae83025 100644
--- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c
+++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
@@ -75,7 +75,7 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
/* XXX check for state changes? */
assert(!cvbr->softpipe->dirty );
- return &cvbr->softpipe->vertex_info;
+ return &cvbr->softpipe->vertex_info_vbuf;
}
@@ -140,7 +140,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
struct softpipe_context *softpipe = cvbr->softpipe;
struct draw_stage *setup = softpipe->setup;
struct prim_header prim;
- unsigned vertex_size = softpipe->vertex_info.size * sizeof(float);
+ unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float);
unsigned i, j;
void *vertex_buffer = cvbr->vertex_buffer;
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
index d399868f244..4be3641d677 100644
--- a/src/mesa/pipe/softpipe/sp_state_derived.c
+++ b/src/mesa/pipe/softpipe/sp_state_derived.c
@@ -50,9 +50,9 @@ find_vs_output(const struct pipe_shader_state *vs,
/**
- * Determine which post-transform / pre-rasterization vertex attributes
- * we need.
- * Derived from: fs, setup states.
+ * Determine how to map vertex program outputs to fragment program inputs.
+ * Basically, this will be used when computing the triangle interpolation
+ * coefficients from the post-transform vertex attributes.
*/
static void calculate_vertex_layout( struct softpipe_context *softpipe )
{
@@ -61,35 +61,33 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &softpipe->vertex_info;
+ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
uint i;
int src;
- memset(vinfo, 0, sizeof(*vinfo));
-
- softpipe->psize_slot = -1;
-
if (softpipe->vbuf) {
- /* softpipe's setup/rasterizer stage expects vertex to have a header */
- draw_emit_vertex_attr(vinfo, FORMAT_HEADER, INTERP_LINEAR, 0);
+ /* if using the post-transform vertex buffer, tell draw_vbuf to
+ * simply emit the whole post-xform vertex as-is:
+ */
+ vinfo_vbuf->num_attribs = 0;
+ draw_emit_vertex_attr(vinfo_vbuf, FORMAT_HEADER, INTERP_NONE, 0);
+ for (i = 0; i < vs->num_outputs; i++) {
+ draw_emit_vertex_attr(vinfo_vbuf, FORMAT_4F, INTERP_NONE, i);
+ }
+ draw_compute_vertex_size(vinfo_vbuf);
}
- /* always emit pos for softpipe rasterization */
- src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src);
-
/*
- * XXX I think we need to reconcile the vertex shader outputs with
- * the fragment shader inputs here to make sure the slots line up.
- * Might just be getting lucky so far.
- * Or maybe do that in the state tracker?
+ * Loop over fragment shader inputs, searching for the matching output
+ * from the vertex shader.
*/
-
+ vinfo->num_attribs = 0;
for (i = 0; i < fs->num_inputs; i++) {
switch (fs->input_semantic_name[i]) {
-
case TGSI_SEMANTIC_POSITION:
- /* handled above */
+ src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_POS, src);
break;
case TGSI_SEMANTIC_COLOR:
@@ -122,16 +120,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
}
}
- src = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
- if (src >= 0) {
- softpipe->psize_slot = src;
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT, src);
+ softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+ if (softpipe->psize_slot >= 0) {
+ draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT,
+ softpipe->psize_slot);
}
-
draw_compute_vertex_size(vinfo);
-
- softpipe->nr_frag_attrs = fs->num_inputs;
}
@@ -175,7 +170,9 @@ compute_cliprect(struct softpipe_context *sp)
*/
void softpipe_update_derived( struct softpipe_context *softpipe )
{
- if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS))
+ if (softpipe->dirty & (SP_NEW_RASTERIZER |
+ SP_NEW_FS |
+ SP_NEW_VS))
calculate_vertex_layout( softpipe );
if (softpipe->dirty & (SP_NEW_SCISSOR |