r300-gallium: Clean up RS.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 7 Mar 2009 19:31:36 +0000 (11:31 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 7 Mar 2009 21:28:02 +0000 (13:28 -0800)
Wow, there were buggies by the boatload in there.

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

index 95b3b14a1a1acde6288f9c6781e322a19a33c596..f22569e6feed4282f78589f76780fef023c39a4a 100644 (file)
@@ -208,6 +208,10 @@ struct r300_vertex_format {
     uint32_t vap_prog_stream_cntl[8];
     /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
     uint32_t vap_prog_stream_cntl_ext[8];
+    /* This is a map of VAP/SW TCL outputs into the GA/RS.
+     * tab[i] is the location of input i in GA/RS input memory.
+     * Named tab for historical reasons. */
+    int tab[16];
 };
 
 struct r300_context {
index e6bb4083ab4df5debf821e4fc8ff55a6628da2e5..feb0faa13c9975aeeeac02c55acb34067e34b93c 100644 (file)
@@ -93,15 +93,18 @@ static void r300_update_vertex_layout(struct r300_context* r300)
             tab[i] = tab[i-1];
         }
         tab[0] = 0;
-    }
 
-    draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
-        draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+        draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
+            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+    } else {
+        draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+            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_PSIZE, INTERP_LINEAR,
+        draw_emit_vertex_attr(&vinfo, EMIT_1F_PSIZE, INTERP_POS,
             draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0));
         vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
     }
@@ -161,6 +164,7 @@ static void r300_update_vertex_layout(struct r300_context* r300)
         r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC <<
                 (i & 1 ? 16 : 0));
 
+        memcpy(r300->vertex_info.tab, tab, sizeof(tab));
         memcpy(&r300->vertex_info, &vinfo, sizeof(struct vertex_info));
         r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
     }
@@ -173,30 +177,44 @@ static void r300_update_rs_block(struct r300_context* r300)
 {
     struct r300_rs_block* rs = r300->rs_block;
     struct vertex_info* vinfo = &r300->vertex_info.vinfo;
-    int col_count = 0, fp_offset = 0, i, tex_count = 0;
+    int* tab = r300->vertex_info.tab;
+    int col_count = 0, fp_offset = 0, i, memory_pos, tex_count = 0;
 
     memset(rs, 0, sizeof(struct r300_rs_block));
 
     if (r300_screen(r300->context.screen)->caps->is_r500) {
         for (i = 0; i < vinfo->num_attribs; i++) {
+            assert(tab[vinfo->attrib[i].src_index] != -1);
+            memory_pos = tab[vinfo->attrib[i].src_index] * 4;
             switch (vinfo->attrib[i].interp_mode) {
                 case INTERP_LINEAR:
                     rs->ip[col_count] |=
-                        R500_RS_COL_PTR(vinfo->attrib[i].src_index) |
+                        R500_RS_COL_PTR(memory_pos) |
                         R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
                     col_count++;
                     break;
                 case INTERP_PERSPECTIVE:
                     rs->ip[tex_count] |=
-                        R500_RS_SEL_S(vinfo->attrib[i].src_index) |
-                        R500_RS_SEL_T(vinfo->attrib[i].src_index + 1) |
-                        R500_RS_SEL_R(vinfo->attrib[i].src_index + 2) |
-                        R500_RS_SEL_Q(vinfo->attrib[i].src_index + 3);
+                        R500_RS_SEL_S(memory_pos) |
+                        R500_RS_SEL_T(memory_pos + 1) |
+                        R500_RS_SEL_R(memory_pos + 2) |
+                        R500_RS_SEL_Q(memory_pos + 3);
                     tex_count++;
                     break;
+                default:
+                    break;
             }
         }
 
+        /* Set up at least one texture pointer or RS will not be happy. */
+        if (tex_count == 0) {
+            rs->ip[0] |=
+                R500_RS_SEL_S(R500_RS_IP_PTR_K0) |
+                R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
+                R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
+                R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
+        }
+
         for (i = 0; i < tex_count; i++) {
             rs->inst[i] |= R500_RS_INST_TEX_ID(i) | R500_RS_INST_TEX_CN_WRITE |
                 R500_RS_INST_TEX_ADDR(fp_offset);
@@ -212,25 +230,40 @@ static void r300_update_rs_block(struct r300_context* r300)
         rs->inst_count = MAX2(col_count, tex_count);
     } else {
         for (i = 0; i < vinfo->num_attribs; i++) {
+            memory_pos = tab[vinfo->attrib[i].src_index] * 4;
+            assert(tab[vinfo->attrib[i].src_index] != -1);
             switch (vinfo->attrib[i].interp_mode) {
                 case INTERP_LINEAR:
                     rs->ip[col_count] |=
-                        R300_RS_COL_PTR(vinfo->attrib[i].src_index) |
+                        R300_RS_COL_PTR(memory_pos) |
                         R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
                     col_count++;
                     break;
                 case INTERP_PERSPECTIVE:
                     rs->ip[tex_count] |=
-                        R300_RS_TEX_PTR(vinfo->attrib[i].src_index) |
+                        R300_RS_TEX_PTR(memory_pos) |
                         R300_RS_SEL_S(R300_RS_SEL_C0) |
                         R300_RS_SEL_T(R300_RS_SEL_C1) |
                         R300_RS_SEL_R(R300_RS_SEL_C2) |
                         R300_RS_SEL_Q(R300_RS_SEL_C3);
-                    tex_count += 4;
+                    tex_count++;
+                    break;
+                default:
                     break;
             }
         }
 
+        if (tex_count == 0) {
+            rs->ip[0] |=
+                R300_RS_SEL_S(R300_RS_SEL_K0) |
+                R300_RS_SEL_T(R300_RS_SEL_K0) |
+                R300_RS_SEL_R(R300_RS_SEL_K0) |
+                R300_RS_SEL_Q(R300_RS_SEL_K1);
+        }
+
+        for (i = 0; i < 8; i++)
+            debug_printf("ip %d: 0x%x\n", i, rs->ip[i]);
+
         for (i = 0; i < tex_count; i++) {
             rs->inst[i] |= R300_RS_INST_TEX_ID(i) | R300_RS_INST_TEX_CN_WRITE |
                 R300_RS_INST_TEX_ADDR(fp_offset);
@@ -242,12 +275,17 @@ static void r300_update_rs_block(struct r300_context* r300)
                 R300_RS_INST_COL_ADDR(fp_offset);
             fp_offset++;
         }
+
+        for (i = 0; i < 8; i++)
+            debug_printf("inst %d: 0x%x\n", i, rs->inst[i]);
     }
 
     rs->count = (tex_count * 4) | (col_count << R300_IC_COUNT_SHIFT) |
         R300_HIRES_EN;
 
-    rs->inst_count = MAX2(col_count, tex_count);
+    rs->inst_count = MAX2(MAX2(col_count - 1, tex_count - 1), 0);
+
+    debug_printf("count: 0x%x, inst_count: 0x%x\n", rs->count, rs->inst_count);
 }
 
 void r300_update_derived_state(struct r300_context* r300)