summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/r300_context.h4
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c66
2 files changed, 56 insertions, 14 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 95b3b14a1a..f22569e6fe 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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 {
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index e6bb4083ab..feb0faa13c 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -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)