r300-gallium: Finish VAP/VF setup.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Mon, 23 Feb 2009 11:18:02 +0000 (03:18 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Mon, 23 Feb 2009 12:37:58 +0000 (04:37 -0800)
Messy, messy.

src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_swtcl_emit.c

index fc32f8f669af7b823d5c7934d09777ce69b123a5..5bcf23e2c5991c66e6dd738ab13e900c0a93cb53 100644 (file)
@@ -191,6 +191,15 @@ struct r300_texture {
     struct pipe_buffer* buffer;
 };
 
+struct r300_vertex_format {
+    /* 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];
+};
+
 struct r300_context {
     /* Parent class */
     struct pipe_context context;
@@ -228,7 +237,7 @@ struct r300_context {
     struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
     int vertex_buffer_count;
     /* Vertex information. */
-    struct vertex_info vertex_info;
+    struct r300_vertex_format vertex_info;
     /* Bitmask of dirty state objects. */
     uint32_t dirty_state;
     /* Flag indicating whether or not the HW is dirty. */
index df19f20fc8f4a3f40c458ac4620a51107d2c8df1..2d611b951d16336a084829801dfdb3cc0451e839 100644 (file)
 /* r300_state_derived: Various bits of state which are dependent upon
  * currently bound CSO data. */
 
+static uint32_t translate_vertex_data_type(int type) {
+    switch (type) {
+        case EMIT_1F:
+        case EMIT_1F_PSIZE:
+            return R300_DATA_TYPE_FLOAT_1;
+            break;
+        case EMIT_2F:
+            return R300_DATA_TYPE_FLOAT_2;
+            break;
+        case EMIT_3F:
+            return R300_DATA_TYPE_FLOAT_3;
+            break;
+        case EMIT_4F:
+            return R300_DATA_TYPE_FLOAT_4;
+            break;
+    }
+}
+
 /* Update the vertex_info struct in our r300_context.
  *
  * The vertex_info struct describes the post-TCL format of vertices. It is
@@ -40,6 +58,8 @@ static void r300_update_vertex_layout(struct r300_context* r300)
     struct tgsi_shader_info* info = &r300->fs->info;
     memset(&vinfo, 0, sizeof(vinfo));
 
+    assert(info->num_inputs <= 16);
+
     /* This is rather lame. Since draw_find_vs_output doesn't return an error
      * when it can't find an output, we have to pre-iterate and count each
      * output ourselves. */
@@ -70,46 +90,82 @@ static void r300_update_vertex_layout(struct r300_context* r300)
     /* Do the actual vertex_info setup.
      *
      * vertex_info has four uints of hardware-specific data in it.
-     * vinfo.hwfmt[0] is VAP_OUT_VTX_FMT_0
-     * vinfo.hwfmt[1] is VAP_OUT_VTX_FMT_1 */
-
-    if (pos) {
-        draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
-        vinfo.hwfmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
-    } else {
-        debug_printf("r300: No vertex input for position in SW TCL;\n"
-            "    this will probably end poorly.\n");
+     * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
+     * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
+     * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
+     * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
+
+    vinfo.hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+
+    if (!pos) {
+        debug_printf("r300: Forcing vertex position attribute emit...");
     }
 
+    draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
+        draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+    vinfo.hwfmt[1] |= R300_INPUT_CNTL_POS;
+    vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
     if (psize) {
-        draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_LINEAR,
+        draw_emit_vertex_attr(&vinfo, EMIT_1F_PSIZE, INTERP_LINEAR,
             draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0));
-        vinfo.hwfmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+        vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
     }
 
     for (i = 0; i < cols; i++) {
         draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR,
             draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i));
-        vinfo.hwfmt[0] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
+        vinfo.hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+        vinfo.hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
     }
 
     if (fog) {
         draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
             draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
-        vinfo.hwfmt[0] |=
+        vinfo.hwfmt[2] |=
             (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << cols);
     }
 
     for (i = 0; i < texs; i++) {
         draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR,
             draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
-        vinfo.hwfmt[1] |= (4 << (3 * i));
+        vinfo.hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
+        vinfo.hwfmt[3] |= (4 << (3 * i));
     }
 
     draw_compute_vertex_size(&vinfo);
 
     if (memcmp(&r300->vertex_info, &vinfo, sizeof(struct vertex_info))) {
+        uint32_t temp;
+
+#define BORING_SWIZZLE \
+        ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) | \
+         (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) | \
+         (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) | \
+         (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) | \
+         (0xf << R300_WRITE_ENA_SHIFT))
+
+        for (i = 0; i < vinfo.num_attribs; i++) {
+            temp = translate_vertex_data_type(vinfo.attrib[i].emit) |
+                R300_SIGNED;
+            if (i & 1) {
+                r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0xffff0000;
+                r300->vertex_info.vap_prog_stream_cntl[i >> 1] |=
+                        (translate_vertex_data_type(vinfo.attrib[i].emit) |
+                        R300_SIGNED) << 16;
+            } else {
+                r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0xffff;
+                r300->vertex_info.vap_prog_stream_cntl[i >> 1] |=
+                    translate_vertex_data_type(vinfo.attrib[i].emit) |
+                    R300_SIGNED;
+            }
+
+            r300->vertex_info.vap_prog_stream_cntl_ext[i >> 1] |=
+                (BORING_SWIZZLE << (i & 1 ? 16 : 0));
+        }
+        r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC <<
+                (i & 1 ? 16 : 0));
+
         memcpy(&r300->vertex_info, &vinfo, sizeof(struct vertex_info));
         r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
     }
index 327d4ac2e1014a926a3c117cd95e682016405015..3ce1837ed1ba5522aa00baad23ebfc317420eabf 100644 (file)
@@ -177,6 +177,7 @@ static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render,
 static void prepare_render(struct r300_swtcl_render* render)
 {
     struct r300_context* r300 = render->r300;
+    int i;
 
     CS_LOCALS(r300);
 
@@ -185,27 +186,38 @@ static void prepare_render(struct r300_swtcl_render* render)
     r300_emit_dirty_state(r300);
 
     /* Take care of vertex formats and routes. */
-    BEGIN_CS(3);
+    BEGIN_CS(6);
+    OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
+    OUT_CS(r300->vertex_info.vinfo.hwfmt[0]);
+    OUT_CS(r300->vertex_info.vinfo.hwfmt[1]);
     OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
-    OUT_CS(r300->vertex_info.hwfmt[0]);
-    OUT_CS(r300->vertex_info.hwfmt[1]);
+    OUT_CS(r300->vertex_info.vinfo.hwfmt[2]);
+    OUT_CS(r300->vertex_info.vinfo.hwfmt[3]);
     END_CS;
 
-    /* Draw stuff! */
-    BEGIN_CS(6);
+    BEGIN_CS(18);
+    OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
+    for (i = 0; i < 8; i++) {
+        OUT_CS(r300->vertex_info.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(r300->vertex_info.vap_prog_stream_cntl_ext[i]);
+    }
+    END_CS;
 
     /* Set the pointer to our vertex buffer. The emitted values are this:
      * PACKET3 [3D_LOAD_VBPNTR]
      * COUNT   [1]
      * FORMAT  [size | stride << 8]
      * VBPNTR  [relocated BO]
-     *
-     * And of course that extra dword is space for the relocation. */
+     */
+    BEGIN_CS(5);
     OUT_CS(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 3));
     OUT_CS(1);
-    OUT_CS(r300->vertex_info.size | (r300->vertex_info.size << 8));
-    OUT_CS(0);
+    OUT_CS(r300->vertex_info.vinfo.size | (r300->vertex_info.vinfo.size << 8));
     OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+    END_CS;
 }
 
 static void r300_swtcl_render_draw_arrays(struct vbuf_render* render,