Mesa (master): r300g: decouple vertex stream setup (PSC) and VS output mapping (VAP_OUT)

Marek Olšák mareko at kemper.freedesktop.org
Sun Feb 28 18:32:10 UTC 2010


Module: Mesa
Branch: master
Commit: 942762cd973af0df75040de21d3321cd19829e70
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=942762cd973af0df75040de21d3321cd19829e70

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Feb 28 07:45:56 2010 +0100

r300g: decouple vertex stream setup (PSC) and VS output mapping (VAP_OUT)

Formerly known as vertex_format_state. These two are completely
unrelated when using HWTCL and decoupling them makes the design
less SWTCL-centric.

When bypass_vs_clip_and_viewport gets removed, the PSC setup will
no longer be a derived state.

This change shouldn't make unbreaking SWTCL harder.

---

 src/gallium/drivers/r300/r300_context.c       |    9 +++-
 src/gallium/drivers/r300/r300_context.h       |   35 ++++++++++------
 src/gallium/drivers/r300/r300_emit.c          |   55 ++++++++++++++-----------
 src/gallium/drivers/r300/r300_emit.h          |    5 ++-
 src/gallium/drivers/r300/r300_render.c        |    2 +-
 src/gallium/drivers/r300/r300_state.c         |   14 +++++--
 src/gallium/drivers/r300/r300_state_derived.c |   47 ++++++++++++---------
 7 files changed, 101 insertions(+), 66 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 3a84fc5..1d7d598 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -59,7 +59,8 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300->fb_state.state);
     FREE(r300->rs_block_state.state);
     FREE(r300->scissor_state.state);
-    FREE(r300->vertex_format_state.state);
+    FREE(r300->vertex_stream_state.state);
+    FREE(r300->vap_output_state.state);
     FREE(r300->viewport_state.state);
     FREE(r300->ztop_state.state);
     FREE(r300);
@@ -127,7 +128,8 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(scissor_state, 3);
     R300_INIT_ATOM(viewport_state, 9);
     R300_INIT_ATOM(rs_block_state, 0);
-    R300_INIT_ATOM(vertex_format_state, 26);
+    R300_INIT_ATOM(vertex_stream_state, 0);
+    R300_INIT_ATOM(vap_output_state, 6);
     R300_INIT_ATOM(pvs_flush, 2);
     R300_INIT_ATOM(vs_state, 0);
     R300_INIT_ATOM(texture_cache_inval, 2);
@@ -138,7 +140,8 @@ static void r300_setup_atoms(struct r300_context* r300)
     r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
     r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
     r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
-    r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info);
+    r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
+    r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
     r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
     r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
 }
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 47f2aa5..3eb884a 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -134,6 +134,21 @@ struct r300_texture_fb_state {
     uint32_t zb_format; /* R300_ZB_FORMAT */
 };
 
+struct r300_vertex_stream_state {
+    /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+    uint32_t vap_prog_stream_cntl[8];
+    /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+    uint32_t vap_prog_stream_cntl_ext[8];
+
+    unsigned count;
+};
+
+struct r300_vap_output_state {
+    uint32_t vap_vtx_state_cntl;  /* R300_VAP_VTX_STATE_CNTL: 0x2180 */
+    uint32_t vap_vsm_vtx_assm;    /* R300_VAP_VSM_VTX_ASSM: 0x2184 */
+    uint32_t vap_out_vtx_fmt[2];  /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */
+};
+
 struct r300_viewport_state {
     float xscale;         /* R300_VAP_VPORT_XSCALE:  0x2098 */
     float xoffset;        /* R300_VAP_VPORT_XOFFSET: 0x209c */
@@ -246,16 +261,6 @@ struct r300_texture {
     enum r300_buffer_tiling microtile, macrotile;
 };
 
-struct r300_vertex_info {
-    /* Parent class */
-    struct vertex_info vinfo;
-
-    /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
-    uint32_t vap_prog_stream_cntl[8];
-    /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
-    uint32_t vap_prog_stream_cntl_ext[8];
-};
-
 extern struct pipe_viewport_state r300_viewport_identity;
 
 struct r300_context {
@@ -280,9 +285,6 @@ struct r300_context {
     struct r300_query *query_current;
     struct r300_query query_list;
 
-    /* Vertex formatting information. */
-    struct r300_atom vertex_format_state;
-
     /* Various CSO state objects. */
     /* Beginning of atom list. */
     struct r300_atom atom_list;
@@ -312,6 +314,10 @@ struct r300_context {
     /* Texture states. */
     struct r300_texture* textures[8];
     int texture_count;
+    /* Vertex stream formatting state. */
+    struct r300_atom vertex_stream_state;
+    /* VAP (vertex shader) output mapping state. */
+    struct r300_atom vap_output_state;
     /* Vertex shader. */
     struct r300_atom vs_state;
     /* Viewport state. */
@@ -334,6 +340,9 @@ struct r300_context {
     struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
     int vertex_element_count;
 
+    /* Vertex info for Draw. */
+    struct vertex_info vertex_info;
+
     struct pipe_stencil_ref stencil_ref;
 
     /* Bitmask of dirty state objects. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d66fa0d..6a67713 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -814,44 +814,51 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
     END_CS;
 }
 
-void r300_emit_vertex_format_state(struct r300_context* r300,
+void r300_emit_vertex_stream_state(struct r300_context* r300,
                                    unsigned size, void* state)
 {
-    struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state;
+    struct r300_vertex_stream_state *streams =
+        (struct r300_vertex_stream_state*)state;
     unsigned i;
     CS_LOCALS(r300);
 
-    DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n");
+    DBG(r300, DBG_DRAW, "r300: PSC emit:\n");
 
     BEGIN_CS(size);
-    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size);
-
-    OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
-    OUT_CS(vertex_info->vinfo.hwfmt[0]);
-    OUT_CS(vertex_info->vinfo.hwfmt[1]);
-    OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
-    OUT_CS(vertex_info->vinfo.hwfmt[2]);
-    OUT_CS(vertex_info->vinfo.hwfmt[3]);
-    for (i = 0; i < 4; i++) {
-       DBG(r300, DBG_DRAW, "    : hwfmt%d: 0x%08x\n", i,
-               vertex_info->vinfo.hwfmt[i]);
-    }
-
-    OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
-    for (i = 0; i < 8; i++) {
-        OUT_CS(vertex_info->vap_prog_stream_cntl[i]);
+    OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count);
+    for (i = 0; i < streams->count; i++) {
+        OUT_CS(streams->vap_prog_stream_cntl[i]);
         DBG(r300, DBG_DRAW, "    : prog_stream_cntl%d: 0x%08x\n", i,
-               vertex_info->vap_prog_stream_cntl[i]);
+               streams->vap_prog_stream_cntl[i]);
     }
-    OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
-    for (i = 0; i < 8; i++) {
-        OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]);
+    OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count);
+    for (i = 0; i < streams->count; i++) {
+        OUT_CS(streams->vap_prog_stream_cntl_ext[i]);
         DBG(r300, DBG_DRAW, "    : prog_stream_cntl_ext%d: 0x%08x\n", i,
-               vertex_info->vap_prog_stream_cntl_ext[i]);
+               streams->vap_prog_stream_cntl_ext[i]);
     }
     END_CS;
 }
 
+void r300_emit_vap_output_state(struct r300_context* r300,
+                               unsigned size, void* state)
+{
+    struct r300_vap_output_state *vap_out_state =
+        (struct r300_vap_output_state*)state;
+    CS_LOCALS(r300);
+
+    DBG(r300, DBG_DRAW, "r300: VAP emit:\n");
+
+    BEGIN_CS(size);
+    OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
+    OUT_CS(vap_out_state->vap_vtx_state_cntl);
+    OUT_CS(vap_out_state->vap_vsm_vtx_assm);
+    OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+    OUT_CS(vap_out_state->vap_out_vtx_fmt[0]);
+    OUT_CS(vap_out_state->vap_out_vtx_fmt[1]);
+    END_CS;
+}
+
 void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state)
 {
     CS_LOCALS(r300);
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 4a3f940..a2c2a91 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -77,9 +77,12 @@ void r300_emit_texture(struct r300_context* r300,
 
 void r300_emit_vertex_buffer(struct r300_context* r300);
 
-void r300_emit_vertex_format_state(struct r300_context* r300,
+void r300_emit_vertex_stream_state(struct r300_context* r300,
                                    unsigned size, void* state);
 
+void r300_emit_vap_output_state(struct r300_context* r300,
+                               unsigned size, void* state);
+
 void r300_emit_vertex_program_code(struct r300_context* r300,
                                    struct r300_vertex_program_code* code);
 
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index c5baf55..770a92b 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -597,7 +597,7 @@ r300_render_get_vertex_info(struct vbuf_render* render)
 
     r300_update_derived_state(r300);
 
-    return (struct vertex_info*)r300->vertex_format_state.state;
+    return &r300->vertex_info;
 }
 
 static boolean r300_render_allocate_vertices(struct vbuf_render* render,
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 97a0897..5a47158 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -659,7 +659,11 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
     r300->fs = fs;
     r300_pick_fragment_shader(r300);
 
-    r300->vertex_format_state.dirty = TRUE;
+    r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+
+    if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) {
+        r300->vap_output_state.dirty = TRUE;
+    }
 
     r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
@@ -1033,9 +1037,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
     if (r300->draw) {
         draw_flush(r300->draw);
         draw_set_vertex_buffers(r300->draw, count, buffers);
+    } else {
+        r300->vertex_stream_state.dirty = TRUE;
     }
-
-    r300->vertex_format_state.dirty = TRUE;
 }
 
 static boolean r300_validate_aos(struct r300_context *r300)
@@ -1114,7 +1118,9 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
         r300->vs_state.size = vs->code.length + 9;
         r300->vs_state.dirty = TRUE;
 
-        r300->vertex_format_state.dirty = TRUE;
+        r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+        r300->vap_output_state.dirty = TRUE;
+        r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */
         r300->pvs_flush.dirty = TRUE;
 
         if (r300->fs) {
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 86301e2..0574d98 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -49,9 +49,7 @@ static void r300_draw_emit_attrib(struct r300_context* r300,
     output = draw_find_shader_output(r300->draw,
                                      info->output_semantic_name[index],
                                      info->output_semantic_index[index]);
-    draw_emit_vertex_attr(
-        (struct vertex_info*)r300->vertex_format_state.state,
-        emit, interp, output);
+    draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
 }
 
 static void r300_draw_emit_all_attribs(struct r300_context* r300)
@@ -106,17 +104,21 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
 }
 
 /* Update the PSC tables. */
+/* XXX move this function into r300_state.c after TCL-bypass gets removed
+ * XXX because this one is dependent only on vertex elements. */
 static void r300_vertex_psc(struct r300_context* r300)
 {
     struct r300_vertex_shader* vs = r300->vs_state.state;
-    struct r300_vertex_info *vformat =
-        (struct r300_vertex_info*)r300->vertex_format_state.state;
+    struct r300_vertex_stream_state *vformat =
+        (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
     uint16_t type, swizzle;
     enum pipe_format format;
     unsigned i;
     int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
     int* stream_tab;
 
+    memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
+
     /* If TCL is bypassed, map vertex streams to equivalent VS output
      * locations. */
     if (r300->tcl_bypass) {
@@ -157,20 +159,25 @@ static void r300_vertex_psc(struct r300_context* r300)
     }
     vformat->vap_prog_stream_cntl[i >> 1] |=
         (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+    vformat->count = (i >> 1) + 1;
+    r300->vertex_stream_state.size = (1 + vformat->count) * 2;
 }
 
 /* Update the PSC tables for SW TCL, using Draw. */
 static void r300_swtcl_vertex_psc(struct r300_context* r300)
 {
     struct r300_vertex_shader* vs = r300->vs_state.state;
-    struct r300_vertex_info *vformat =
-        (struct r300_vertex_info*)r300->vertex_format_state.state;
-    struct vertex_info* vinfo = &vformat->vinfo;
+    struct r300_vertex_stream_state *vformat =
+        (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
+    struct vertex_info* vinfo = &r300->vertex_info;
     uint16_t type, swizzle;
     enum pipe_format format;
     unsigned i, attrib_count;
     int* vs_output_tab = vs->stream_loc_notcl;
 
+    memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
+
     /* For each Draw attribute, route it to the fragment shader according
      * to the vs_output_tab. */
     attrib_count = vinfo->num_attribs;
@@ -212,6 +219,9 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300)
     }
     vformat->vap_prog_stream_cntl[i >> 1] |=
         (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+    vformat->count = (i >> 1) + 1;
+    r300->vertex_stream_state.size = (1 + vformat->count) * 2;
 }
 
 static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
@@ -430,13 +440,12 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
 {
     struct r300_vertex_shader* vs = r300->vs_state.state;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
-    struct r300_vertex_info *vformat =
-        (struct r300_vertex_info*)r300->vertex_format_state.state;
-    struct vertex_info* vinfo = &vformat->vinfo;
+    struct r300_vap_output_state *vap_out =
+        (struct r300_vap_output_state*)r300->vap_output_state.state;
 
-    /* Mmm, delicious hax */
-    memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info));
-    memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4);
+    /* XXX Mmm, delicious hax */
+    memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+    memcpy(vap_out, vs->hwfmt, sizeof(uint)*4);
 
     r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
 
@@ -444,8 +453,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
         r300_vertex_psc(r300);
     } else {
         r300_draw_emit_all_attribs(r300);
-        draw_compute_vertex_size(
-            (struct vertex_info*)r300->vertex_format_state.state);
+        draw_compute_vertex_size(&r300->vertex_info);
         r300_swtcl_vertex_psc(r300);
     }
 }
@@ -523,10 +531,9 @@ static void r300_update_ztop(struct r300_context* r300)
 
 void r300_update_derived_state(struct r300_context* r300)
 {
-    /* XXX */
-    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER ||
-        r300->vs_state.dirty || r300->vertex_format_state.dirty ||
-        r300->rs_state.dirty) {
+    if (r300->rs_block_state.dirty ||
+        r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */
+        r300->rs_state.dirty) {  /* XXX and remove this one (tcl_bypass dependency) */
         r300_update_derived_shader_state(r300);
     }
 




More information about the mesa-commit mailing list