The attached patches are preliminary, and I didn't try very hard to fix most drivers yet, as I did not want to invest too much time yet only to get shot down later.
I'd like to add 2 new TGSI semantics so that nvc0 can identify gl_TexCoord and gl_PointCoord. The reason for this is that nvc0 hardware, contrary to nv50, now has dedicated output/input locations for most semantics in order to make GL_ARB_separate_shader_objects easily implementable. Unfortunately this limits the point coordinate replacement enable to a small set of locations which I should be able to choose when the shader is compiled. I realize that this is going to be a bit invasive and possibly make some drivers' shader linkage code a little less nice, and all that just for a single target (although I hope newer Radeons will work similarly), but I really want to find a solution to make the gallium interface not be a major pain for it. I'm looking forward to comments or suggestions of alternatives, and, given that we might abandon TGSI at some point and use e.g. GLSL IR directly I'd be willing to wait (keeping my hack in the code) and hope that the new IR makes this change come more naturally. Thanks in advance in case of potential responses, Regards, Christoph
>From 542686da008eda2415230e279f32f04dd507ff9a Mon Sep 17 00:00:00 2001 From: Christoph Bumiller <e0425...@student.tuwien.ac.at> Date: Thu, 10 Mar 2011 21:11:13 +0100 Subject: [PATCH 2/2] gallium: add TGSI_SEMANTIC_TEXCOORD This semantic should be used to indicate to the driver which shader varyings may be replaced by sprite coordinates. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 6 ++++-- src/gallium/docs/source/cso/rasterizer.rst | 2 +- src/gallium/docs/source/tgsi.rst | 7 ++++++- src/gallium/drivers/llvmpipe/lp_setup_point.c | 2 +- src/gallium/drivers/nv50/nv50_shader_state.c | 2 +- src/gallium/drivers/nvc0/nvc0_program.c | 11 +++-------- src/gallium/drivers/r300/r300_fs.c | 2 ++ src/gallium/drivers/r300/r300_shader_semantics.h | 1 + src/gallium/drivers/r300/r300_vs.c | 2 ++ src/gallium/drivers/r600/r600_state_common.c | 2 +- src/gallium/include/pipe/p_shader_tokens.h | 3 ++- src/mesa/state_tracker/st_program.c | 11 ++++------- 12 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 95c947e..baf583c 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -129,7 +129,8 @@ static const char *semantic_names[] = "PRIM_ID", "INSTANCEID", "STENCIL", - "PNTCOORD" + "PNTCOORD", + "TEXCOORD" }; static const char *immediate_type_names[] = @@ -399,7 +400,8 @@ iter_declaration( TXT( ", " ); ENM( decl->Semantic.Name, semantic_names ); if (decl->Semantic.Index != 0 || - decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { + decl->Semantic.Name == TGSI_SEMANTIC_GENERIC || + decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD) { CHR( '[' ); UID( decl->Semantic.Index ); CHR( ']' ); diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index d547055..bc5d97f 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -126,7 +126,7 @@ sprite_coord_enable Controls automatic texture coordinate generation for rendering sprite points. -When bit k in the sprite_coord_enable bitfield is set, then generic +When bit k in the sprite_coord_enable bitfield is set, then texture coord input k to the fragment shader will get an automatically computed texture coordinate. diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst index 4debcc6..49b5352 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -1588,8 +1588,13 @@ TGSI_SEMANTIC_GENERIC All vertex/fragment shader inputs/outputs not labeled with any other semantic label can be considered to be generic attributes. Typical -uses of generic inputs/outputs are texcoords and user-defined values. +uses of generic inputs/outputs are user-defined values. +TGSI_SEMANTIC_TEXCOORD +"""""""""""""""""""""" + +Vertex/fragment shader inputs/outputs that are labeled with this semantic +are eligible for sprite coordinate replacement. TGSI_SEMANTIC_NORMAL """""""""""""""""""" diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index 4b81374..7f639e7 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -245,7 +245,7 @@ setup_point_coefficients( struct lp_setup_context *setup, if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_PNTCOORD) { sprite_coord = TRUE; } else - if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) { + if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_TEXCOORD) { unsigned semantic_index = shader->info.base.input_semantic_index[slot]; /* Note that sprite_coord enable is a bitfield of * PIPE_MAX_SHADER_OUTPUTS bits. diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index ce0b3ad..211e2a1 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -253,7 +253,7 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) for (i = 0; i < fp->in_nr; i++) { unsigned n = util_bitcount(fp->in[i].mask); - if (fp->in[i].sn == TGSI_SEMANTIC_GENERIC) { + if (fp->in[i].sn == TGSI_SEMANTIC_TEXCOORD) { if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) { m += n; continue; diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 3cee2ce..8027a98 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -182,16 +182,11 @@ nvc0_varying_location(unsigned sn, unsigned si) return 0x6c; case TGSI_SEMANTIC_PNTCOORD: return 0x2e0; + case TGSI_SEMANTIC_TEXCOORD: + return 0x300 + si * 16; case TGSI_SEMANTIC_GENERIC: - /* We'd really like to distinguish between TEXCOORD and GENERIC here, - * since only 0x300 to 0x37c can be replaced by sprite coordinates. - * Also, gl_PointCoord should be a system value and must be assigned to - * address 0x2e0. For now, let's cheat: - */ assert(si < 31); - if (si <= 7) - return 0x300 + si * 16; - return 0x80 + ((si - 8) * 16); + return 0x80 + si * 16; case TGSI_SEMANTIC_NORMAL: return 0x360; case TGSI_SEMANTIC_PRIMID: diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index cec7473..e484a89 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -58,6 +58,8 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, break; case TGSI_SEMANTIC_GENERIC: + index += ATTR_GENERIC_BASE; + case TGSI_SEMANTIC_TEXCOORD: assert(index < ATTR_GENERIC_COUNT); fs_inputs->generic[index] = i; break; diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h index 4be23e6..75340c9 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_GENERIC_BASE 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 diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index b319890..03ed6ec 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -69,6 +69,8 @@ static void r300_shader_read_vs_outputs( break; case TGSI_SEMANTIC_GENERIC: + index += ATTR_GENERIC_BASE; + case TGSI_SEMANTIC_TEXCOORD: assert(index < ATTR_GENERIC_COUNT); vs_outputs->generic[index] = i; break; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 231aea7..1acedac 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -282,7 +282,7 @@ r600_ps_input_is_sprite_coord(struct r600_pipe_context *rctx, { struct r600_shader *rshader = &rctx->ps_shader->shader; - if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC) + if (rshader->input[i].name == TGSI_SEMANTIC_TEXCOORD) return (rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) ? TRUE : FALSE; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index af2e8e1..cd8fff3 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -146,7 +146,8 @@ struct tgsi_declaration_dimension #define TGSI_SEMANTIC_INSTANCEID 10 #define TGSI_SEMANTIC_STENCIL 11 #define TGSI_SEMANTIC_PNTCOORD 12 -#define TGSI_SEMANTIC_COUNT 13 /**< number of semantic values */ +#define TGSI_SEMANTIC_TEXCOORD 13 +#define TGSI_SEMANTIC_COUNT 14 /**< number of semantic values */ struct tgsi_declaration_semantic { diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 2b2448f..c95d711 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -255,7 +255,7 @@ st_prepare_vertex_program(struct st_context *st, case VERT_RESULT_TEX5: case VERT_RESULT_TEX6: case VERT_RESULT_TEX7: - stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD; stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0; break; @@ -263,10 +263,7 @@ st_prepare_vertex_program(struct st_context *st, default: assert(attr < VERT_RESULT_MAX); stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 - - FRAG_ATTRIB_TEX0 + - attr - - VERT_RESULT_VAR0); + stvp->output_semantic_index[slot] = attr - VERT_RESULT_VAR0; break; } } @@ -533,8 +530,8 @@ st_translate_fragment_program(struct st_context *st, /* Actually, let's try and zero-base this just for * readability of the generated TGSI. */ - assert(attr >= FRAG_ATTRIB_TEX0); - input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); + assert(attr >= FRAG_ATTRIB_VAR0); + input_semantic_index[slot] = attr - FRAG_ATTRIB_VAR0; input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; -- 1.7.3.4
>From 017216e02b1ce23b7a89c5ed87138b0f2cc3c6f2 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller <e0425...@student.tuwien.ac.at> Date: Thu, 10 Mar 2011 21:13:43 +0100 Subject: [PATCH 1/2] gallium: add TGSI_SEMANTIC_PNTCOORD This semantic should be used to identify the PointCoord system value which is unconditionally replaced by sprite coordinates if point quad rasterization is enabled. Coordinate replacement of normal texture coordinates as done with GL_COORD_REPLACE still uses the bitfield in the rasterizer state. Actually this is supposed to be used with TGSI_FILE_SYSTEM_VALUE only, but that will require mesa changes as well, just like with the FACE attribute. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_point.c | 25 +++++++++++++++++-------- src/gallium/drivers/nv50/nv50_shader_state.c | 12 +++++++----- src/gallium/drivers/nvc0/nvc0_program.c | 6 +----- src/gallium/drivers/r600/r600_state_common.c | 17 ++++++++++++++--- src/gallium/include/pipe/p_shader_tokens.h | 3 ++- src/mesa/state_tracker/st_atom_rasterizer.c | 4 ---- src/mesa/state_tracker/st_program.c | 9 +++++---- 8 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index c126620..95c947e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -128,7 +128,8 @@ static const char *semantic_names[] = "EDGEFLAG", "PRIM_ID", "INSTANCEID", - "STENCIL" + "STENCIL", + "PNTCOORD" }; static const char *immediate_type_names[] = diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index 146f1bd..4b81374 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -218,6 +218,7 @@ setup_point_coefficients( struct lp_setup_context *setup, unsigned usage_mask = key->inputs[slot].usage_mask; enum lp_interp interp = key->inputs[slot].interp; boolean perspective = !!(interp == LP_INTERP_PERSPECTIVE); + boolean sprite_coord; unsigned i; if (perspective & usage_mask) { @@ -241,22 +242,30 @@ setup_point_coefficients( struct lp_setup_context *setup, /* check if the sprite coord flag is set for this attribute. * If so, set it up so it up so x and y vary from 0 to 1. */ + if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_PNTCOORD) { + sprite_coord = TRUE; + } else if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) { unsigned semantic_index = shader->info.base.input_semantic_index[slot]; /* Note that sprite_coord enable is a bitfield of * PIPE_MAX_SHADER_OUTPUTS bits. */ if (semantic_index < PIPE_MAX_SHADER_OUTPUTS && - (setup->sprite_coord_enable & (1 << semantic_index))) { - for (i = 0; i < NUM_CHANNELS; i++) { - if (usage_mask & (1 << i)) { - texcoord_coef(setup, info, slot + 1, i, - setup->sprite_coord_origin, - perspective); - } + (setup->sprite_coord_enable & (1 << semantic_index))) + sprite_coord = TRUE; + } else { + sprite_coord = FALSE; + } + + if (sprite_coord) { + for (i = 0; i < NUM_CHANNELS; i++) { + if (usage_mask & (1 << i)) { + texcoord_coef(setup, info, slot + 1, i, + setup->sprite_coord_origin, + perspective); } - break; } + break; } /* fall-through */ case LP_INTERP_CONSTANT: diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index bea9c09..ce0b3ad 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -253,11 +253,13 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) for (i = 0; i < fp->in_nr; i++) { unsigned n = util_bitcount(fp->in[i].mask); - if (fp->in[i].sn != TGSI_SEMANTIC_GENERIC) { - m += n; - continue; - } - if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) { + if (fp->in[i].sn == TGSI_SEMANTIC_GENERIC) { + if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) { + m += n; + continue; + } + } else + if (fp->in[i].sn != TGSI_SEMANTIC_PNTCOORD) { m += n; continue; } diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 975745a..3cee2ce 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -180,10 +180,8 @@ nvc0_varying_location(unsigned sn, unsigned si) return 0x270; case TGSI_SEMANTIC_PSIZE: return 0x6c; - /* - case TGSI_SEMANTIC_PNTC: + case TGSI_SEMANTIC_PNTCOORD: return 0x2e0; - */ case TGSI_SEMANTIC_GENERIC: /* We'd really like to distinguish between TEXCOORD and GENERIC here, * since only 0x300 to 0x37c can be replaced by sprite coordinates. @@ -193,8 +191,6 @@ nvc0_varying_location(unsigned sn, unsigned si) assert(si < 31); if (si <= 7) return 0x300 + si * 16; - if (si == 9) - return 0x2e0; return 0x80 + ((si - 8) * 16); case TGSI_SEMANTIC_NORMAL: return 0x360; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 43dad0c..231aea7 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -276,6 +276,19 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) free(shader); } +static INLINE boolean +r600_ps_input_is_sprite_coord(struct r600_pipe_context *rctx, + unsigned i) +{ + struct r600_shader *rshader = &rctx->ps_shader->shader; + + if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC) + return (rctx->sprite_coord_enable & + (1 << rshader->input[i].sid)) ? TRUE : FALSE; + + return rshader->input[i].name == TGSI_SEMANTIC_PNTCOORD; +} + /* FIXME optimize away spi update when it's not needed */ void r600_spi_update(struct r600_pipe_context *rctx) { @@ -294,10 +307,8 @@ void r600_spi_update(struct r600_pipe_context *rctx) tmp |= S_028644_FLAT_SHADE(rctx->flatshade); } - if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && - rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { + if (r600_ps_input_is_sprite_coord(rctx, i)) tmp |= S_028644_PT_SPRITE_TEX(1); - } if (rctx->family < CHIP_CEDAR) { if (rshader->input[i].centroid) diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index d3a3632..af2e8e1 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -145,7 +145,8 @@ struct tgsi_declaration_dimension #define TGSI_SEMANTIC_PRIMID 9 #define TGSI_SEMANTIC_INSTANCEID 10 #define TGSI_SEMANTIC_STENCIL 11 -#define TGSI_SEMANTIC_COUNT 12 /**< number of semantic values */ +#define TGSI_SEMANTIC_PNTCOORD 12 +#define TGSI_SEMANTIC_COUNT 13 /**< number of semantic values */ struct tgsi_declaration_semantic { diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 8bcccee..2747b6d 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -196,10 +196,6 @@ static void update_raster_state( struct st_context *st ) raster->sprite_coord_enable |= 1 << i; } } - if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) { - raster->sprite_coord_enable |= - 1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0); - } raster->point_quad_rasterization = 1; } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index fc1dfb3..2b2448f 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -516,6 +516,10 @@ st_translate_fragment_program(struct st_context *st, * should be building tables based on semantic index. */ case FRAG_ATTRIB_PNTC: + input_semantic_name[slot] = TGSI_SEMANTIC_PNTCOORD; + input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_LINEAR; + break; case FRAG_ATTRIB_TEX0: case FRAG_ATTRIB_TEX1: case FRAG_ATTRIB_TEX2: @@ -532,10 +536,7 @@ st_translate_fragment_program(struct st_context *st, assert(attr >= FRAG_ATTRIB_TEX0); input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - if (attr == FRAG_ATTRIB_PNTC) - interpMode[slot] = TGSI_INTERPOLATE_LINEAR; - else - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; } } -- 1.7.3.4
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev