From d4b8e8a48144f4b899d48c271558f0dc613632cb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pavel=20Ondra=C4=8Dka?= Date: Fri, 28 Apr 2023 13:17:52 +0200 Subject: [PATCH] r300: enable PIPE_CAP_TGSI_TEXCOORD MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Ondračka Acked-by: Emma Anholt Reviewed-by: Filip Gawin Part-of: --- src/gallium/drivers/r300/r300_fs.c | 17 +++ src/gallium/drivers/r300/r300_render.c | 10 +- src/gallium/drivers/r300/r300_screen.c | 1 + src/gallium/drivers/r300/r300_shader_semantics.h | 10 ++ src/gallium/drivers/r300/r300_state.c | 20 ++- src/gallium/drivers/r300/r300_state_derived.c | 152 +++++++++++++++++++++-- src/gallium/drivers/r300/r300_vs.c | 13 ++ 7 files changed, 203 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 94a5505..201949c 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -58,6 +58,15 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, fs_inputs->color[index] = i; break; + case TGSI_SEMANTIC_PCOORD: + fs_inputs->pcoord = i; + break; + + case TGSI_SEMANTIC_TEXCOORD: + assert(index < ATTR_TEXCOORD_COUNT); + fs_inputs->texcoord[index] = i; + break; + case TGSI_SEMANTIC_GENERIC: assert(index < ATTR_GENERIC_COUNT); fs_inputs->generic[index] = i; @@ -133,6 +142,14 @@ static void allocate_hardware_inputs( allocate(mydata, inputs->generic[i], reg++); } } + for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) { + if (inputs->texcoord[i] != ATTR_UNUSED) { + allocate(mydata, inputs->texcoord[i], reg++); + } + } + if (inputs->pcoord != ATTR_UNUSED) { + allocate(mydata, inputs->pcoord, reg++); + } if (inputs->fog != ATTR_UNUSED) { allocate(mydata, inputs->fog, reg++); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 9b8d943..ba6e3db 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -41,6 +41,7 @@ #include "r300_emit.h" #include "r300_reg.h" #include "r300_vs.h" +#include "r300_fs.h" #include @@ -801,11 +802,13 @@ static void r300_draw_vbo(struct pipe_context* pipe, return; } - if (r300->sprite_coord_enable != 0) + if (r300->sprite_coord_enable != 0 || + r300_fs(r300)->shader->inputs.pcoord != ATTR_UNUSED) { if ((info.mode == MESA_PRIM_POINTS) != r300->is_point) { r300->is_point = !r300->is_point; r300_mark_atom_dirty(r300, &r300->rs_block_state); } + } r300_update_derived_state(r300); @@ -888,11 +891,14 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, info->index_size, ~0); } - if (r300->sprite_coord_enable != 0) + if (r300->sprite_coord_enable != 0 || + r300_fs(r300)->shader->inputs.pcoord != ATTR_UNUSED) { if ((info->mode == MESA_PRIM_POINTS) != r300->is_point) { r300->is_point = !r300->is_point; r300_mark_atom_dirty(r300, &r300->rs_block_state); } + } + r300_update_derived_state(r300); diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index ef85f00..6c4d259 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -144,6 +144,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_CLIP_HALFZ: case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION: case PIPE_CAP_LEGACY_MATH_RULES: + case PIPE_CAP_TGSI_TEXCOORD: return 1; case PIPE_CAP_TEXTURE_TRANSFER_MODES: diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h index 93bbc9d..b474a3e 100644 --- a/src/gallium/drivers/r300/r300_shader_semantics.h +++ b/src/gallium/drivers/r300/r300_shader_semantics.h @@ -26,6 +26,7 @@ #define ATTR_UNUSED (-1) #define ATTR_COLOR_COUNT 2 #define ATTR_GENERIC_COUNT 32 +#define ATTR_TEXCOORD_COUNT 8 /* This structure contains information about what attributes are written by VS * or read by FS. (but not both) It's much easier to work with than @@ -39,10 +40,13 @@ struct r300_shader_semantics { int color[ATTR_COLOR_COUNT]; int bcolor[ATTR_COLOR_COUNT]; int face; + int texcoord[ATTR_TEXCOORD_COUNT]; int generic[ATTR_GENERIC_COUNT]; int fog; int wpos; + int pcoord; + int num_texcoord; int num_generic; }; @@ -56,16 +60,22 @@ static inline void r300_shader_semantics_reset( info->face = ATTR_UNUSED; info->fog = ATTR_UNUSED; info->wpos = ATTR_UNUSED; + info->pcoord = ATTR_UNUSED; for (i = 0; i < ATTR_COLOR_COUNT; i++) { info->color[i] = ATTR_UNUSED; info->bcolor[i] = ATTR_UNUSED; } + for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) { + info->texcoord[i] = ATTR_UNUSED; + } + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { info->generic[i] = ATTR_UNUSED; } + info->num_texcoord = 0; info->num_generic = 0; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 09300ff..8a493a9 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1281,17 +1281,15 @@ static void* r300_create_rs_state(struct pipe_context* pipe, clip_rule = state->scissor ? 0xAAAA : 0xFFFF; /* Point sprites coord mode */ - if (rs->rs.sprite_coord_enable) { - switch (state->sprite_coord_mode) { - case PIPE_SPRITE_COORD_UPPER_LEFT: - point_texcoord_top = 0.0f; - point_texcoord_bottom = 1.0f; - break; - case PIPE_SPRITE_COORD_LOWER_LEFT: - point_texcoord_top = 1.0f; - point_texcoord_bottom = 0.0f; - break; - } + switch (state->sprite_coord_mode) { + case PIPE_SPRITE_COORD_UPPER_LEFT: + point_texcoord_top = 0.0f; + point_texcoord_bottom = 1.0f; + break; + case PIPE_SPRITE_COORD_LOWER_LEFT: + point_texcoord_top = 1.0f; + point_texcoord_bottom = 0.0f; + break; } if (r300_screen(pipe->screen)->caps.has_tcl) { diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 05a7e0e..67b8d4d 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -108,6 +108,15 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) } } + /* Texcoords */ + for (i = 0; i < ATTR_TEXCOORD_COUNT && gen_count < 8; i++) { + if (vs_outputs->texcoord[i] != ATTR_UNUSED && + (!(r300->sprite_coord_enable & (1U << i)) || !r300->is_point)) { + r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->texcoord[i]); + gen_count++; + } + } + /* Fog coordinates. */ if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) { r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->fog); @@ -429,15 +438,17 @@ static void r300_update_rs_block(struct r300_context *r300) fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n"); } - /* Re-use color varyings for texcoords if possible. + /* Re-use color varyings for generics if possible. * * The colors are interpolated as 20-bit floats (reduced precision), * Use this hack only if there are too many generic varyings. - * (number of generic varyings + fog + wpos > 8) */ + * (number of generics + texcoords + fog + wpos + pcoord > 8) */ if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade && - fs_inputs->face == ATTR_UNUSED && - vs_outputs->num_generic + (vs_outputs->fog != ATTR_UNUSED) + - (fs_inputs->wpos != ATTR_UNUSED) > 8) { + fs_inputs->face == ATTR_UNUSED && + vs_outputs->num_texcoord + vs_outputs->num_generic + + (vs_outputs->fog != ATTR_UNUSED) + (fs_inputs->wpos != ATTR_UNUSED) + + (vs_outputs->pcoord != ATTR_UNUSED) > 8 && + fs_inputs->num_generic > fs_inputs->num_texcoord) { for (i = 0; i < ATTR_GENERIC_COUNT && col_count < 2; i++) { /* Cannot use color varyings for sprite coords. */ if (fs_inputs->generic[i] != ATTR_UNUSED && @@ -481,7 +492,7 @@ static void r300_update_rs_block(struct r300_context *r300) gen_offset = i; } - /* Rasterize texture coordinates. */ + /* Rasterize generics. */ for (i = gen_offset; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) { boolean sprite_coord = false; @@ -530,6 +541,131 @@ static void r300_update_rs_block(struct r300_context *r300) } } + gen_offset = 0; + /* Re-use color varyings for texcoords if possible. + * + * The colors are interpolated as 20-bit floats (reduced precision), + * Use this hack only if there are too many generic varyings. + * (number of generics + texcoords + fog + wpos + pcoord > 8) */ + if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade && + fs_inputs->face == ATTR_UNUSED && + vs_outputs->num_texcoord + vs_outputs->num_generic + + (vs_outputs->fog != ATTR_UNUSED) + (fs_inputs->wpos != ATTR_UNUSED) + + (vs_outputs->pcoord != ATTR_UNUSED) > 8 && + fs_inputs->num_generic <= fs_inputs->num_texcoord) { + for (i = 0; i < ATTR_TEXCOORD_COUNT && col_count < 2; i++) { + /* Cannot use color varyings for sprite coords. */ + if (fs_inputs->texcoord[i] != ATTR_UNUSED && + (r300->sprite_coord_enable & (1U << i)) && r300->is_point) { + break; + } + + if (vs_outputs->texcoord[i] != ATTR_UNUSED) { + /* Set up the color in VAP. */ + rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + rs.vap_out_vtx_fmt[0] |= + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << col_count; + stream_loc_notcl[loc++] = 2 + col_count; + + /* Rasterize it. */ + rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); + + /* Write it to the FS input register if it's needed by the FS. */ + if (fs_inputs->texcoord[i] != ATTR_UNUSED) { + rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR); + fp_offset++; + + DBG(r300, DBG_RS, + "r300: Rasterized texcoord %i redirected to color %i and written to FS.\n", + i, col_count); + } else { + DBG(r300, DBG_RS, "r300: Rasterized texcoord %i redirected to color %i unused.\n", + i, col_count); + } + col_count++; + } else { + /* Skip the FS input register, leave it uninitialized. */ + /* If we try to set it to (0,0,0,1), it will lock up. */ + if (fs_inputs->texcoord[i] != ATTR_UNUSED) { + fp_offset++; + + DBG(r300, DBG_RS, "r300: FS input texcoord %i unassigned.\n", i); + } + } + } + gen_offset = i; + } + + /* Rasterize texcords. */ + for (i = gen_offset; i < ATTR_TEXCOORD_COUNT && tex_count < 8; i++) { + boolean sprite_coord = false; + + if (fs_inputs->texcoord[i] != ATTR_UNUSED) { + sprite_coord = !!(r300->sprite_coord_enable & (1 << i)) && r300->is_point; + } + + if (vs_outputs->texcoord[i] != ATTR_UNUSED || sprite_coord) { + if (!sprite_coord) { + /* Set up the texture coordinates in VAP. */ + rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); + rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); + stream_loc_notcl[loc++] = 6 + tex_count; + } else + stuffing_enable |= + R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2)); + + /* Rasterize it. */ + rX00_rs_tex(&rs, tex_count, tex_ptr, + sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); + + /* Write it to the FS input register if it's needed by the FS. */ + if (fs_inputs->texcoord[i] != ATTR_UNUSED) { + rX00_rs_tex_write(&rs, tex_count, fp_offset); + fp_offset++; + + DBG(r300, DBG_RS, + "r300: Rasterized texcoord %i written to FS%s in texcoord %d.\n", + i, sprite_coord ? " (sprite coord)" : "", tex_count); + } else { + DBG(r300, DBG_RS, + "r300: Rasterized texcoord %i unused%s.\n", + i, sprite_coord ? " (sprite coord)" : ""); + } + tex_count++; + tex_ptr += sprite_coord ? 2 : 4; + } else { + /* Skip the FS input register, leave it uninitialized. */ + /* If we try to set it to (0,0,0,1), it will lock up. */ + if (fs_inputs->texcoord[i] != ATTR_UNUSED) { + fp_offset++; + + DBG(r300, DBG_RS, "r300: FS input texcoord %i unassigned%s.\n", + i, sprite_coord ? " (sprite coord)" : ""); + } + } + } + + /* Rasterize pointcoord. */ + if (fs_inputs->pcoord != ATTR_UNUSED && tex_count < 8) { + + stuffing_enable |= + R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2)); + + /* Rasterize it. */ + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XY01); + + /* Write it to the FS input register if it's needed by the FS. */ + rX00_rs_tex_write(&rs, tex_count, fp_offset); + fp_offset++; + + DBG(r300, DBG_RS, + "r300: Rasterized pointcoord %i written to FS%s in texcoord %d.\n", + i, " (sprite coord)", tex_count); + + tex_count++; + tex_ptr += 2; + } + for (; i < ATTR_GENERIC_COUNT; i++) { if (fs_inputs->generic[i] != ATTR_UNUSED) { fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, " @@ -625,8 +761,10 @@ static void r300_update_rs_block(struct r300_context *r300) rs.inst_count = count - 1; /* set the GB enable flags */ - if (r300->sprite_coord_enable && r300->is_point) + if ((r300->sprite_coord_enable || fs_inputs->pcoord != ATTR_UNUSED) && + r300->is_point) { stuffing_enable |= R300_GB_POINT_STUFF_ENABLE; + } rs.gb_enable = stuffing_enable; diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index dba65ae..394604c 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -67,6 +67,12 @@ static void r300_shader_read_vs_outputs( vs_outputs->bcolor[index] = i; break; + case TGSI_SEMANTIC_TEXCOORD: + assert(index < ATTR_TEXCOORD_COUNT); + vs_outputs->texcoord[index] = i; + vs_outputs->num_texcoord++; + break; + case TGSI_SEMANTIC_GENERIC: assert(index < ATTR_GENERIC_COUNT); vs_outputs->generic[index] = i; @@ -153,6 +159,13 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) } /* Texture coordinates. */ + for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) { + if (outputs->texcoord[i] != ATTR_UNUSED) { + c->code->outputs[outputs->texcoord[i]] = reg++; + } + } + + /* Generics. */ for (i = 0; i < ATTR_GENERIC_COUNT; i++) { if (outputs->generic[i] != ATTR_UNUSED) { c->code->outputs[outputs->generic[i]] = reg++; -- 2.7.4