From c6b450033d7ec2a415b1d761da1d94588358c94b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 9 Dec 2009 00:45:18 +0100 Subject: [PATCH] r300g: fix routing of vertex streams if TCL is bypassed Generating mipmaps finally works, among other things. Yay! --- src/gallium/drivers/r300/r300_state.c | 2 -- src/gallium/drivers/r300/r300_state_derived.c | 17 +++++++--- src/gallium/drivers/r300/r300_vs.c | 31 ++++++++----------- src/gallium/drivers/r300/r300_vs.h | 4 ++- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 68c5408a647..edf7114bbb5 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -419,8 +419,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, if (state->bypass_vs_clip_and_viewport || !r300_screen(pipe->screen)->caps->has_tcl) { rs->vap_control_status |= R300_VAP_TCL_BYPASS; - } else { - rs->rs.bypass_vs_clip_and_viewport = TRUE; } rs->point_size = pack_float_16_6x(state->point_size) | diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 6af49888b9e..29bc701a86e 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -134,6 +134,16 @@ static void r300_vertex_psc(struct r300_context* r300) 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; + + /* If TCL is bypassed, map vertex streams to equivalent VS output + * locations. */ + if (r300->rs_state->enable_vte) { + stream_tab = identity; + } else { + stream_tab = r300->vs->stream_loc_notcl; + } /* Vertex shaders have no semantics on their inputs, * so PSC should just route stuff based on the vertex elements, @@ -147,10 +157,10 @@ static void r300_vertex_psc(struct r300_context* r300) format = r300->vertex_element[i].src_format; type = r300_translate_vertex_data_type(format) | - (i << R300_DST_VEC_LOC_SHIFT); + (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); swizzle = r300_translate_vertex_data_swizzle(format); - if (i % 2) { + if (i & 1) { vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; } else { @@ -159,7 +169,6 @@ static void r300_vertex_psc(struct r300_context* r300) } } - assert(i <= 15); /* Set the last vector in the PSC. */ @@ -178,7 +187,7 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; - int* vs_output_tab = r300->vs->output_stream_loc_swtcl; + int* vs_output_tab = r300->vs->stream_loc_notcl; /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 31248346bc6..fa207c939ca 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -143,35 +143,33 @@ static void r300_shader_vap_output_fmt( assert(gen_count <= 8); } -/* Set VS output stream locations for SWTCL. */ -static void r300_stream_locations_swtcl( +/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed + * or isn't present. */ +static void r300_stream_locations_notcl( struct r300_shader_semantics* vs_outputs, - int* output_stream_loc) + int* stream_loc) { int i, tabi = 0, gen_count; - /* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct. - * These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */ - /* Position. */ - output_stream_loc[tabi++] = 0; + stream_loc[tabi++] = 0; /* Point size. */ if (vs_outputs->psize != ATTR_UNUSED) { - output_stream_loc[tabi++] = 1; + stream_loc[tabi++] = 1; } /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->color[i] != ATTR_UNUSED) { - output_stream_loc[tabi++] = 2 + i; + stream_loc[tabi++] = 2 + i; } } /* Back-face colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->bcolor[i] != ATTR_UNUSED) { - output_stream_loc[tabi++] = 4 + i; + stream_loc[tabi++] = 4 + i; } } @@ -180,7 +178,7 @@ static void r300_stream_locations_swtcl( for (i = 0; i < ATTR_GENERIC_COUNT; i++) { if (vs_outputs->bcolor[i] != ATTR_UNUSED) { assert(tabi < 16); - output_stream_loc[tabi++] = 6 + gen_count; + stream_loc[tabi++] = 6 + gen_count; gen_count++; } } @@ -188,7 +186,7 @@ static void r300_stream_locations_swtcl( /* Fog coordinates. */ if (vs_outputs->fog != ATTR_UNUSED) { assert(tabi < 16); - output_stream_loc[tabi++] = 6 + gen_count; + stream_loc[tabi++] = 6 + gen_count; gen_count++; } @@ -196,7 +194,7 @@ static void r300_stream_locations_swtcl( assert(gen_count <= 8); for (; tabi < 16;) { - output_stream_loc[tabi++] = -1; + stream_loc[tabi++] = -1; } } @@ -254,10 +252,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* Initialize. */ r300_shader_read_vs_outputs(&vs->info, &vs->outputs); r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt); - - if (!r300_screen(r300->context.screen)->caps->has_tcl) { - r300_stream_locations_swtcl(&vs->outputs, vs->output_stream_loc_swtcl); - } + r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl); /* Setup the compiler */ rc_init(&compiler.Base); @@ -283,7 +278,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { - /* XXX Fail gracefully */ + /* XXX We should fallback using Draw. */ fprintf(stderr, "r300 VP: Compiler error\n"); abort(); } diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 283dd5a9e83..67e9db5366f 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -38,9 +38,11 @@ struct r300_vertex_shader { struct tgsi_shader_info info; struct r300_shader_semantics outputs; - int output_stream_loc_swtcl[16]; uint hwfmt[4]; + /* Stream locations for SWTCL or if TCL is bypassed. */ + int stream_loc_notcl[16]; + /* Has this shader been translated yet? */ boolean translated; -- 2.30.2