summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-02-14 18:58:50 -0700
committerBrian <brian.paul@tungstengraphics.com>2008-02-14 18:59:25 -0700
commit3d81a956b9de709de17a98b93fead4d3307b2b99 (patch)
tree7d69a25ebb85a13c341408ff671b95ea18df7049
parent1b6540b4b17969e9838facf5248fce34c9ff5c34 (diff)
gallium: rearrange vertex info/layout validation
Delay validation until someone really needs the vertex layout (vbuf alloc vertex buffer or point/line/tri setup/rendering). This will allow the vertex size to change depending on whether we're drawing points, lines or triangles.
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c21
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_vbuf.c5
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h10
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c174
4 files changed, 134 insertions, 76 deletions
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
index 7478b2336b..2772048661 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.c
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.c
@@ -499,7 +499,7 @@ setup_fragcoord_coeff(struct setup_stage *setup)
setup->coef[0].a0[2] = setup->posCoef.a0[2];
setup->coef[0].dadx[2] = setup->posCoef.dadx[2];
setup->coef[0].dady[2] = setup->posCoef.dady[2];
- /*w*/
+ /*W*/
setup->coef[0].a0[3] = setup->posCoef.a0[3];
setup->coef[0].dadx[3] = setup->posCoef.dadx[3];
setup->coef[0].dady[3] = setup->posCoef.dady[3];
@@ -513,8 +513,9 @@ setup_fragcoord_coeff(struct setup_stage *setup)
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
- const struct softpipe_context *softpipe = setup->softpipe;
+ struct softpipe_context *softpipe = setup->softpipe;
const struct pipe_shader_state *fs = &softpipe->fs->shader;
+ const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
uint fragSlot;
/* z and w are done by linear interpolation:
@@ -525,10 +526,10 @@ static void setup_tri_coefficients( struct setup_stage *setup )
/* setup interpolation for all the remaining attributes:
*/
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
- const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
- switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ switch (vinfo->interp_mode[fragSlot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
@@ -756,8 +757,9 @@ line_persp_coeff(struct setup_stage *setup,
static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
- const struct softpipe_context *softpipe = setup->softpipe;
+ struct softpipe_context *softpipe = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
+ const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
uint fragSlot;
/* use setup->vmin, vmax to point to vertices */
@@ -779,10 +781,10 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
/* setup interpolation for all the remaining attributes:
*/
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
- const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
- switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ switch (vinfo->interp_mode[fragSlot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
@@ -978,6 +980,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
const float x = v0->data[0][0]; /* Note: data[0] is always position */
const float y = v0->data[0][1];
+ const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
uint fragSlot;
/* For points, all interpolants are constant-valued.
@@ -1003,10 +1006,10 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const_coeff(setup, &setup->posCoef, 0, 3);
for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
- const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
- switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ switch (vinfo->interp_mode[fragSlot]) {
case INTERP_CONSTANT:
/* fall-through */
case INTERP_LINEAR:
diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
index c9089e7eb2..7f71fdb6a9 100644
--- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c
+++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
@@ -37,6 +37,7 @@
#include "sp_context.h"
+#include "sp_state.h"
#include "sp_prim_vbuf.h"
#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_private.h"
@@ -73,9 +74,7 @@ static const struct vertex_info *
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_vbuf;
+ return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
}
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index af955c1e17..b79db0d1f1 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -59,6 +59,8 @@ struct gallivm_prog;
#endif
+struct vertex_info;
+
/** Subclass of pipe_shader_state */
struct sp_fragment_shader_state {
@@ -174,4 +176,12 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
+
+struct vertex_info *
+softpipe_get_vertex_info(struct softpipe_context *softpipe);
+
+struct vertex_info *
+softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
+
+
#endif
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
index 39c3e1afe1..9e4c35e696 100644
--- a/src/mesa/pipe/softpipe/sp_state_derived.c
+++ b/src/mesa/pipe/softpipe/sp_state_derived.c
@@ -49,82 +49,128 @@ find_vs_output(const struct pipe_shader_state *vs,
}
+/**
+ * Mark the current vertex layout as "invalid".
+ * We'll validate the vertex layout later, when we start to actually
+ * render a point or line or tri.
+ */
+static void
+invalidate_vertex_layout(struct softpipe_context *softpipe)
+{
+ softpipe->vertex_info.num_attribs = 0;
+}
+
/**
- * 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.
+ * The vertex info describes how to convert the post-transformed vertices
+ * (simple float[][4]) used by the 'draw' module into vertices for
+ * rasterization.
+ *
+ * This function validates the vertex layout and returns a pointer to a
+ * vertex_info object.
*/
-static void calculate_vertex_layout( struct softpipe_context *softpipe )
+struct vertex_info *
+softpipe_get_vertex_info(struct softpipe_context *softpipe)
{
- const struct pipe_shader_state *vs = &softpipe->vs->shader;
- const struct pipe_shader_state *fs = &softpipe->fs->shader;
- const enum interp_mode colorInterp
- = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &softpipe->vertex_info;
- uint i;
- if (softpipe->vbuf) {
- /* if using the post-transform vertex buffer, tell draw_vbuf to
- * simply emit the whole post-xform vertex as-is:
- */
- struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
- vinfo_vbuf->num_attribs = 0;
- draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
- vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4;
- }
+ if (vinfo->num_attribs == 0) {
+ /* compute vertex layout now */
+ const struct pipe_shader_state *vs = &softpipe->vs->shader;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
+ const enum interp_mode colorInterp
+ = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
+ uint i;
+
+ if (softpipe->vbuf) {
+ /* if using the post-transform vertex buffer, tell draw_vbuf to
+ * simply emit the whole post-xform vertex as-is:
+ */
+ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
+ vinfo_vbuf->num_attribs = 0;
+ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
+ vinfo_vbuf->size = 4 * vs->num_outputs
+ + sizeof(struct vertex_header) / 4;
+ }
- /*
- * 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++) {
- int src;
- switch (fs->input_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
- break;
-
- case TGSI_SEMANTIC_COLOR:
- src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
- fs->input_semantic_index[i]);
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
- break;
-
- case TGSI_SEMANTIC_FOG:
- src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+ /*
+ * 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++) {
+ int src;
+ switch (fs->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
+ break;
+
+ case TGSI_SEMANTIC_COLOR:
+ src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
+ fs->input_semantic_index[i]);
+ if (src < 0)
+ src = 0;
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
+ break;
+
+ case TGSI_SEMANTIC_FOG:
+ src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
#if 1
- if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
- src = 0;
+ if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
+ src = 0;
#endif
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
- break;
-
- case TGSI_SEMANTIC_GENERIC:
- /* this includes texcoords and varying vars */
- src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
- fs->input_semantic_index[i]);
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
- break;
-
- default:
- assert(0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ break;
+
+ case TGSI_SEMANTIC_GENERIC:
+ /* this includes texcoords and varying vars */
+ src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+ fs->input_semantic_index[i]);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ break;
+
+ default:
+ assert(0);
+ }
}
- }
- softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
- if (softpipe->psize_slot >= 0) {
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
- softpipe->psize_slot);
+ softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+ if (softpipe->psize_slot >= 0) {
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
+ softpipe->psize_slot);
+ }
+
+ draw_compute_vertex_size(vinfo);
}
- draw_compute_vertex_size(vinfo);
+ return vinfo;
+}
+
+
+/**
+ * Called from vbuf module.
+ *
+ * Note that there's actually two different vertex layouts in softpipe.
+ *
+ * The normal one is computed in softpipe_get_vertex_info() above and is
+ * used by the point/line/tri "setup" code.
+ *
+ * The other one (this one) is only used by the vbuf module (which is
+ * not normally used by default but used in testing). For the vbuf module,
+ * we basically want to pass-through the draw module's vertex layout as-is.
+ * When the softpipe vbuf code begins drawing, the normal vertex layout
+ * will come into play again.
+ */
+struct vertex_info *
+softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
+{
+ (void) softpipe_get_vertex_info(softpipe);
+ return &softpipe->vertex_info_vbuf;
}
@@ -171,7 +217,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe )
if (softpipe->dirty & (SP_NEW_RASTERIZER |
SP_NEW_FS |
SP_NEW_VS))
- calculate_vertex_layout( softpipe );
+ invalidate_vertex_layout( softpipe );
if (softpipe->dirty & (SP_NEW_SCISSOR |
SP_NEW_DEPTH_STENCIL_ALPHA |