On 15.03.2013 22:16, Christoph Bumiller wrote: > This makes it possible to identify gl_TexCoord and gl_PointCoord > for drivers where sprite coordinate replacement is restricted. > > The new PIPE_CAP_TGSI_TEXCOORD decides whether these varyings > should be hidden behind the GENERIC semantic or not. > > With this patch only nvc0 and nv30 will request that they be used. > > v2: introduce a CAP so other drivers don't have to bother with > the new semantic > > v3: adapt to introduction gl_varying_slot enum
I would push this soon if there are no objections ... > --- > src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 46 > +++++++++++++-------- > src/gallium/auxiliary/tgsi/tgsi_dump.c | 1 + > src/gallium/auxiliary/tgsi/tgsi_strings.c | 4 +- > src/gallium/docs/source/cso/rasterizer.rst | 5 ++ > src/gallium/docs/source/screen.rst | 8 ++++ > src/gallium/docs/source/tgsi.rst | 29 +++++++++++++ > src/gallium/drivers/freedreno/freedreno_screen.c | 2 + > src/gallium/drivers/i915/i915_screen.c | 2 + > src/gallium/drivers/llvmpipe/lp_screen.c | 1 + > src/gallium/drivers/nv30/nv30_screen.c | 1 + > src/gallium/drivers/nv30/nvfx_fragprog.c | 42 ++++++++++--------- > src/gallium/drivers/nv30/nvfx_vertprog.c | 7 +++- > src/gallium/drivers/nv50/codegen/nv50_ir_driver.h | 2 - > src/gallium/drivers/nv50/nv50_screen.c | 1 + > src/gallium/drivers/nv50/nv50_surface.c | 5 +- > src/gallium/drivers/nvc0/nvc0_program.c | 37 +--------------- > src/gallium/drivers/nvc0/nvc0_screen.c | 1 + > src/gallium/drivers/r300/r300_screen.c | 2 + > src/gallium/drivers/r600/r600_pipe.c | 2 + > src/gallium/drivers/radeonsi/radeonsi_pipe.c | 2 + > src/gallium/drivers/softpipe/sp_screen.c | 2 + > src/gallium/drivers/svga/svga_screen.c | 2 + > src/gallium/include/pipe/p_defines.h | 3 +- > src/gallium/include/pipe/p_shader_tokens.h | 4 +- > src/gallium/include/pipe/p_state.h | 2 +- > src/mesa/state_tracker/st_context.c | 3 + > src/mesa/state_tracker/st_context.h | 2 + > src/mesa/state_tracker/st_program.c | 45 +++++++++++++++----- > 28 files changed, 171 insertions(+), 92 deletions(-) > > diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c > b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c > index 8e0a117..0d3fee4 100644 > --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c > +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c > @@ -52,6 +52,7 @@ > */ > > > +#include "pipe/p_screen.h" > #include "pipe/p_context.h" > #include "util/u_math.h" > #include "util/u_memory.h" > @@ -74,6 +75,9 @@ struct widepoint_stage { > uint num_texcoord_gen; > uint texcoord_gen_slot[PIPE_MAX_SHADER_OUTPUTS]; > > + /* TGSI_SEMANTIC to which sprite_coord_enable applies */ > + unsigned sprite_coord_semantic; > + > int psize_slot; > }; > > @@ -233,28 +237,29 @@ widepoint_first_point(struct draw_stage *stage, > > wide->num_texcoord_gen = 0; > > - /* Loop over fragment shader inputs looking for generic inputs > + /* Loop over fragment shader inputs looking for the PCOORD input or > inputs > * for which bit 'k' in sprite_coord_enable is set. > */ > for (i = 0; i < fs->info.num_inputs; i++) { > - if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { > - const int generic_index = fs->info.input_semantic_index[i]; > - /* Note that sprite_coord enable is a bitfield of > - * PIPE_MAX_SHADER_OUTPUTS bits. > - */ > - if (generic_index < PIPE_MAX_SHADER_OUTPUTS && > - (rast->sprite_coord_enable & (1 << generic_index))) { > - /* OK, this generic attribute needs to be replaced with a > - * texcoord (see above). > - */ > - int slot = draw_alloc_extra_vertex_attrib(draw, > - > TGSI_SEMANTIC_GENERIC, > - generic_index); > - > - /* add this slot to the texcoord-gen list */ > - wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot; > - } > + int slot; > + const unsigned sn = fs->info.input_semantic_name[i]; > + const unsigned si = fs->info.input_semantic_index[i]; > + > + if (sn == wide->sprite_coord_semantic) { > + /* Note that sprite_coord_enable is a bitfield of 32 bits. */ > + if (si >= 32 || !(rast->sprite_coord_enable & (1 << si))) > + continue; > + } else if (sn != TGSI_SEMANTIC_PCOORD) { > + continue; > } > + > + /* OK, this generic attribute needs to be replaced with a > + * sprite coord (see above). > + */ > + slot = draw_alloc_extra_vertex_attrib(draw, sn, si); > + > + /* add this slot to the texcoord-gen list */ > + wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot; > } > } > > @@ -326,6 +331,11 @@ struct draw_stage *draw_wide_point_stage( struct > draw_context *draw ) > if (!draw_alloc_temp_verts( &wide->stage, 4 )) > goto fail; > > + wide->sprite_coord_semantic = > + draw->pipe->screen->get_param(draw->pipe->screen, > PIPE_CAP_TGSI_TEXCOORD) > + ? > + TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; > + > return &wide->stage; > > fail: > diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c > b/src/gallium/auxiliary/tgsi/tgsi_dump.c > index 3e6f76a..8f16f2d 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c > @@ -279,6 +279,7 @@ iter_declaration( > TXT( ", " ); > ENM( decl->Semantic.Name, tgsi_semantic_names ); > if (decl->Semantic.Index != 0 || > + decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || > decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { > CHR( '[' ); > UID( decl->Semantic.Index ); > diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c > b/src/gallium/auxiliary/tgsi/tgsi_strings.c > index 70f997b..40062c7 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c > @@ -78,7 +78,9 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] = > "GRID_SIZE", > "BLOCK_ID", > "BLOCK_SIZE", > - "THREAD_ID" > + "THREAD_ID", > + "TEXCOORD", > + "PCOORD" > }; > > const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] = > diff --git a/src/gallium/docs/source/cso/rasterizer.rst > b/src/gallium/docs/source/cso/rasterizer.rst > index f4e24f0..8338243 100644 > --- a/src/gallium/docs/source/cso/rasterizer.rst > +++ b/src/gallium/docs/source/cso/rasterizer.rst > @@ -159,13 +159,18 @@ Points > > sprite_coord_enable > ^^^^^^^^^^^^^^^^^^^ > +The effect of this state depends on PIPE_CAP_TGSI_TEXCOORD ! > > Controls automatic texture coordinate generation for rendering sprite points. > > +If PIPE_CAP_TGSI_TEXCOORD is false: > When bit k in the sprite_coord_enable bitfield is set, then generic > input k to the fragment shader will get an automatically computed > texture coordinate. > > +If PIPE_CAP_TGSI_TEXCOORD is true: > +The bitfield refers to inputs with TEXCOORD semantic instead of generic > inputs. > + > The texture coordinate will be of the form (s, t, 0, 1) where s varies > from 0 to 1 from left to right while t varies from 0 to 1 according to > the state of 'sprite_coord_mode' (see below). > diff --git a/src/gallium/docs/source/screen.rst > b/src/gallium/docs/source/screen.rst > index 68d1a35..0550a30 100644 > --- a/src/gallium/docs/source/screen.rst > +++ b/src/gallium/docs/source/screen.rst > @@ -137,6 +137,14 @@ The integer capabilities: > * ``PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT``: Describes the required > alignment for pipe_sampler_view::u.buf.first_element, in bytes. > If a driver does not support first/last_element, it should return 0. > +* ``PIPE_CAP_TGSI_TEXCOORD``: This CAP describes a hw limitation. > + If true, the hardware cannot replace arbitrary shader inputs with sprite > + coordinates and hence the inputs that are desired to be replaceable must > + be declared with TGSI_SEMANTIC_TEXCOORD instead of TGSI_SEMANTIC_GENERIC. > + The rasterizer's sprite_coord_enable state therefore also applies to the > + TEXCOORD semantic. > + Also, TGSI_SEMANTIC_PCOORD becomes available, which labels a fragment > shader > + input that will always be replaced with sprite coordinates. > > > .. _pipe_capf: > diff --git a/src/gallium/docs/source/tgsi.rst > b/src/gallium/docs/source/tgsi.rst > index d9a7fe9..e5a61bc 100644 > --- a/src/gallium/docs/source/tgsi.rst > +++ b/src/gallium/docs/source/tgsi.rst > @@ -1931,6 +1931,35 @@ When using this semantic, be sure to set the > appropriate state in the > :ref:`rasterizer` first. > > > +TGSI_SEMANTIC_TEXCOORD > +"""""""""""""""""""""" > + > +Only available if PIPE_CAP_TGSI_TEXCOORD is exposed ! > + > +Vertex shader outputs and fragment shader inputs may be labeled with > +this semantic to make them replaceable by sprite coordinates via the > +sprite_coord_enable state in the :ref:`rasterizer`. > +The semantic index permitted with this semantic is limited to <= 7. > + > +If the driver does not support TEXCOORD, sprite coordinate replacement > +applies to inputs with the GENERIC semantic instead. > + > +The intended use case for this semantic is gl_TexCoord. > + > + > +TGSI_SEMANTIC_PCOORD > +"""""""""""""""""""" > + > +Only available if PIPE_CAP_TGSI_TEXCOORD is exposed ! > + > +Fragment shader inputs may be labeled with TGSI_SEMANTIC_PCOORD to indicate > +that the register contains sprite coordinates in the form (x, y, 0, 1), if > +the current primitive is a point and point sprites are enabled. Otherwise, > +the contents of the register are undefined. > + > +The intended use case for this semantic is gl_PointCoord. > + > + > TGSI_SEMANTIC_GENERIC > """"""""""""""""""""" > > diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c > b/src/gallium/drivers/freedreno/freedreno_screen.c > index 5310fc7..5ff132d 100644 > --- a/src/gallium/drivers/freedreno/freedreno_screen.c > +++ b/src/gallium/drivers/freedreno/freedreno_screen.c > @@ -165,6 +165,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum > pipe_cap param) > case PIPE_CAP_TEXTURE_MULTISAMPLE: > case PIPE_CAP_USER_CONSTANT_BUFFERS: > return 1; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > > case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: > return 256; > diff --git a/src/gallium/drivers/i915/i915_screen.c > b/src/gallium/drivers/i915/i915_screen.c > index eb96e9e..13aa91c 100644 > --- a/src/gallium/drivers/i915/i915_screen.c > +++ b/src/gallium/drivers/i915/i915_screen.c > @@ -184,6 +184,8 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap > cap) > case PIPE_CAP_USER_INDEX_BUFFERS: > case PIPE_CAP_USER_CONSTANT_BUFFERS: > return 1; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > > /* Unsupported features (boolean caps). */ > case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: > diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c > b/src/gallium/drivers/llvmpipe/lp_screen.c > index 93e125d..5ec1df6 100644 > --- a/src/gallium/drivers/llvmpipe/lp_screen.c > +++ b/src/gallium/drivers/llvmpipe/lp_screen.c > @@ -208,6 +208,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum > pipe_cap param) > case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: > case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: > case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: > + case PIPE_CAP_TGSI_TEXCOORD: > return 0; > > case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: > diff --git a/src/gallium/drivers/nv30/nv30_screen.c > b/src/gallium/drivers/nv30/nv30_screen.c > index 90c3672..e17ee76 100644 > --- a/src/gallium/drivers/nv30/nv30_screen.c > +++ b/src/gallium/drivers/nv30/nv30_screen.c > @@ -79,6 +79,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum > pipe_cap param) > case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: > case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: > case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: > + case PIPE_CAP_TGSI_TEXCOORD: > case PIPE_CAP_USER_CONSTANT_BUFFERS: > case PIPE_CAP_USER_INDEX_BUFFERS: > return 1; > diff --git a/src/gallium/drivers/nv30/nvfx_fragprog.c > b/src/gallium/drivers/nv30/nvfx_fragprog.c > index 935804e..4be7dec 100644 > --- a/src/gallium/drivers/nv30/nvfx_fragprog.c > +++ b/src/gallium/drivers/nv30/nvfx_fragprog.c > @@ -927,15 +927,17 @@ nvfx_fragprog_parse_decl_input(struct nv30_context > *nvfx, struct nvfx_fpc *fpc, > case TGSI_SEMANTIC_FACE: > hw = NV40_FP_OP_INPUT_SRC_FACING; > break; > - case TGSI_SEMANTIC_GENERIC: > - if (fdec->Semantic.Index >= 8) > - return TRUE; > - > + case TGSI_SEMANTIC_TEXCOORD: > + assert(fdec->Semantic.Index < 8); > fpc->fp->texcoord[fdec->Semantic.Index] = fdec->Semantic.Index; > fpc->fp->texcoords |= (1 << fdec->Semantic.Index); > fpc->fp->vp_or |= (0x00004000 << fdec->Semantic.Index); > hw = NVFX_FP_OP_INPUT_SRC_TC(fdec->Semantic.Index); > break; > + case TGSI_SEMANTIC_GENERIC: > + case TGSI_SEMANTIC_PCOORD: > + /* will be assigned to remaining TC slots later */ > + return TRUE; > default: > assert(0); > return FALSE; > @@ -955,22 +957,24 @@ nvfx_fragprog_assign_generic(struct nv30_context *nvfx, > struct nvfx_fpc *fpc, > > switch (fdec->Semantic.Name) { > case TGSI_SEMANTIC_GENERIC: > - if (fdec->Semantic.Index >= 8) { > - for (hw = 0; hw < num_texcoords; hw++) { > - if (fpc->fp->texcoord[hw] == 0xffff) { > - fpc->fp->texcoord[hw] = fdec->Semantic.Index; > - if (hw <= 7) { > - fpc->fp->texcoords |= (0x1 << hw); > - fpc->fp->vp_or |= (0x00004000 << hw); > - } else { > - fpc->fp->vp_or |= (0x00001000 << (hw - 8)); > - } > - if (fdec->Semantic.Index == 9) > - fpc->fp->point_sprite_control |= (0x00000100 << hw); > - hw = NVFX_FP_OP_INPUT_SRC_TC(hw); > - fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw); > - return TRUE; > + case TGSI_SEMANTIC_PCOORD: > + for (hw = 0; hw < num_texcoords; hw++) { > + if (fpc->fp->texcoord[hw] == 0xffff) { > + if (hw <= 7) { > + fpc->fp->texcoords |= (0x1 << hw); > + fpc->fp->vp_or |= (0x00004000 << hw); > + } else { > + fpc->fp->vp_or |= (0x00001000 << (hw - 8)); > + } > + if (fdec->Semantic.Name == TGSI_SEMANTIC_PCOORD) { > + fpc->fp->texcoord[hw] = 0xfffe; > + fpc->fp->point_sprite_control |= (0x00000100 << hw); > + } else { > + fpc->fp->texcoord[hw] = fdec->Semantic.Index + 8; > } > + hw = NVFX_FP_OP_INPUT_SRC_TC(hw); > + fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw); > + return TRUE; > } > return FALSE; > } > diff --git a/src/gallium/drivers/nv30/nvfx_vertprog.c > b/src/gallium/drivers/nv30/nvfx_vertprog.c > index 827d518..24b2412 100644 > --- a/src/gallium/drivers/nv30/nvfx_vertprog.c > +++ b/src/gallium/drivers/nv30/nvfx_vertprog.c > @@ -819,6 +819,7 @@ nvfx_vertprog_parse_decl_output(struct nv30_context > *nv30, struct nvfx_vpc *vpc, > { > unsigned num_texcoords = nv30->is_nv4x ? 10 : 8; > unsigned idx = fdec->Range.First; > + unsigned semantic_index = fdec->Semantic.Index; > int hw = 0, i; > > switch (fdec->Semantic.Name) { > @@ -860,8 +861,12 @@ nvfx_vertprog_parse_decl_output(struct nv30_context > *nv30, struct nvfx_vpc *vpc, > hw = NVFX_VP(INST_DEST_PSZ); > break; > case TGSI_SEMANTIC_GENERIC: > + /* this is really an identifier for VP/FP linkage */ > + semantic_index += 8; > + /* fall through */ > + case TGSI_SEMANTIC_TEXCOORD: > for (i = 0; i < num_texcoords; i++) { > - if (vpc->vp->texcoord[i] == fdec->Semantic.Index) { > + if (vpc->vp->texcoord[i] == semantic_index) { > hw = NVFX_VP(INST_DEST_TC(i)); > break; > } > diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h > b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h > index c5a5b23..51ed9c1 100644 > --- a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h > +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h > @@ -70,8 +70,6 @@ struct nv50_ir_varying > #endif > > #define NV50_SEMANTIC_CLIPDISTANCE (TGSI_SEMANTIC_COUNT + 0) > -#define NV50_SEMANTIC_TEXCOORD (TGSI_SEMANTIC_COUNT + 1) > -#define NV50_SEMANTIC_POINTCOORD (TGSI_SEMANTIC_COUNT + 2) > #define NV50_SEMANTIC_VIEWPORTINDEX (TGSI_SEMANTIC_COUNT + 4) > #define NV50_SEMANTIC_LAYER (TGSI_SEMANTIC_COUNT + 5) > #define NV50_SEMANTIC_INVOCATIONID (TGSI_SEMANTIC_COUNT + 6) > diff --git a/src/gallium/drivers/nv50/nv50_screen.c > b/src/gallium/drivers/nv50/nv50_screen.c > index aed1dd5..fb29b22 100644 > --- a/src/gallium/drivers/nv50/nv50_screen.c > +++ b/src/gallium/drivers/nv50/nv50_screen.c > @@ -184,6 +184,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum > pipe_cap param) > case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: > case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: > case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: > + case PIPE_CAP_TGSI_TEXCOORD: > case PIPE_CAP_TEXTURE_MULTISAMPLE: > return 0; > default: > diff --git a/src/gallium/drivers/nv50/nv50_surface.c > b/src/gallium/drivers/nv50/nv50_surface.c > index 7a0470c..117d3d1 100644 > --- a/src/gallium/drivers/nv50/nv50_surface.c > +++ b/src/gallium/drivers/nv50/nv50_surface.c > @@ -494,7 +494,7 @@ nv50_blitter_make_vp(struct nv50_blitter *blit) > blit->vp.out[1].hw = 2; > blit->vp.out[1].mask = 0x7; > blit->vp.out[1].sn = TGSI_SEMANTIC_GENERIC; > - blit->vp.out[1].si = 8; > + blit->vp.out[1].si = 0; > blit->vp.vp.attrs[0] = 0x73; > blit->vp.vp.psiz = 0x40; > blit->vp.vp.edgeflag = 0x40; > @@ -536,9 +536,8 @@ nv50_blitter_make_fp(struct pipe_context *pipe, > return NULL; > > out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); > - /* NOTE: use GENERIC[8] so we don't use the TEXCOORD slots on nvc0 */ > tc = ureg_DECL_fs_input( > - ureg, TGSI_SEMANTIC_GENERIC, 8, TGSI_INTERPOLATE_LINEAR); > + ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR); > > data = ureg_DECL_temporary(ureg); > > diff --git a/src/gallium/drivers/nvc0/nvc0_program.c > b/src/gallium/drivers/nvc0/nvc0_program.c > index 2f4eae8..2f1b417 100644 > --- a/src/gallium/drivers/nvc0/nvc0_program.c > +++ b/src/gallium/drivers/nvc0/nvc0_program.c > @@ -27,33 +27,6 @@ > #include "nv50/codegen/nv50_ir_driver.h" > #include "nve4_compute.h" > > -/* If only they told use the actual semantic instead of just GENERIC ... */ > -static void > -nvc0_mesa_varying_hack(struct nv50_ir_varying *var) > -{ > - unsigned c; > - > - if (var->sn != TGSI_SEMANTIC_GENERIC) > - return; > - > - if (var->si <= 7) /* gl_TexCoord */ > - for (c = 0; c < 4; ++c) > - var->slot[c] = (0x300 + var->si * 0x10 + c * 0x4) / 4; > - else > - if (var->si == 9) /* gl_PointCoord */ > - for (c = 0; c < 4; ++c) > - var->slot[c] = (0x2e0 + c * 0x4) / 4; > - else > - if (var->si <= 39) > - for (c = 0; c < 4; ++c) /* move down user varyings (first has index 8) > */ > - var->slot[c] -= 0x80 / 4; > - else { > - NOUVEAU_ERR("too many varyings / invalid location: %u !\n", var->si); > - for (c = 0; c < 4; ++c) > - var->slot[c] = (0x270 + c * 0x4) / 4; /* catch invalid indices */ > - } > -} > - > static uint32_t > nvc0_shader_input_address(unsigned sn, unsigned si, unsigned ubase) > { > @@ -69,11 +42,11 @@ nvc0_shader_input_address(unsigned sn, unsigned si, > unsigned ubase) > case NV50_SEMANTIC_CLIPDISTANCE: return 0x2c0 + si * 0x4; > case TGSI_SEMANTIC_CLIPDIST: return 0x2c0 + si * 0x10; > case TGSI_SEMANTIC_CLIPVERTEX: return 0x260; > - case NV50_SEMANTIC_POINTCOORD: return 0x2e0; > + case TGSI_SEMANTIC_PCOORD: return 0x2e0; > case NV50_SEMANTIC_TESSCOORD: return 0x2f0; > case TGSI_SEMANTIC_INSTANCEID: return 0x2f8; > case TGSI_SEMANTIC_VERTEXID: return 0x2fc; > - case NV50_SEMANTIC_TEXCOORD: return 0x300 + si * 0x10; > + case TGSI_SEMANTIC_TEXCOORD: return 0x300 + si * 0x10; > case TGSI_SEMANTIC_FACE: return 0x3fc; > case NV50_SEMANTIC_INVOCATIONID: return ~0; > default: > @@ -99,7 +72,7 @@ nvc0_shader_output_address(unsigned sn, unsigned si, > unsigned ubase) > case NV50_SEMANTIC_CLIPDISTANCE: return 0x2c0 + si * 0x4; > case TGSI_SEMANTIC_CLIPDIST: return 0x2c0 + si * 0x10; > case TGSI_SEMANTIC_CLIPVERTEX: return 0x260; > - case NV50_SEMANTIC_TEXCOORD: return 0x300 + si * 0x10; > + case TGSI_SEMANTIC_TEXCOORD: return 0x300 + si * 0x10; > case TGSI_SEMANTIC_EDGEFLAG: return ~0; > default: > assert(!"invalid TGSI output semantic"); > @@ -149,8 +122,6 @@ nvc0_sp_assign_input_slots(struct nv50_ir_prog_info *info) > > for (c = 0; c < 4; ++c) > info->in[i].slot[c] = (offset + c * 0x4) / 4; > - > - nvc0_mesa_varying_hack(&info->in[i]); > } > > return 0; > @@ -194,8 +165,6 @@ nvc0_sp_assign_output_slots(struct nv50_ir_prog_info > *info) > > for (c = 0; c < 4; ++c) > info->out[i].slot[c] = (offset + c * 0x4) / 4; > - > - nvc0_mesa_varying_hack(&info->out[i]); > } > > return 0; > diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c > b/src/gallium/drivers/nvc0/nvc0_screen.c > index 7d03479..e77b819 100644 > --- a/src/gallium/drivers/nvc0/nvc0_screen.c > +++ b/src/gallium/drivers/nvc0/nvc0_screen.c > @@ -114,6 +114,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum > pipe_cap param) > case PIPE_CAP_TWO_SIDED_STENCIL: > case PIPE_CAP_DEPTH_CLIP_DISABLE: > case PIPE_CAP_POINT_SPRITE: > + case PIPE_CAP_TGSI_TEXCOORD: > return 1; > case PIPE_CAP_SM3: > return 1; > diff --git a/src/gallium/drivers/r300/r300_screen.c > b/src/gallium/drivers/r300/r300_screen.c > index 06ed1cb..46fb869 100644 > --- a/src/gallium/drivers/r300/r300_screen.c > +++ b/src/gallium/drivers/r300/r300_screen.c > @@ -172,6 +172,8 @@ static int r300_get_param(struct pipe_screen* pscreen, > enum pipe_cap param) > case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: > case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: > return r300screen->caps.has_tcl; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > > /* Texturing. */ > case PIPE_CAP_MAX_COMBINED_SAMPLERS: > diff --git a/src/gallium/drivers/r600/r600_pipe.c > b/src/gallium/drivers/r600/r600_pipe.c > index 60a0247..9ed8814 100644 > --- a/src/gallium/drivers/r600/r600_pipe.c > +++ b/src/gallium/drivers/r600/r600_pipe.c > @@ -565,6 +565,8 @@ static int r600_get_param(struct pipe_screen* pscreen, > enum pipe_cap param) > case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: > case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: > return 1; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > > case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: > return R600_MAP_BUFFER_ALIGNMENT; > diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c > b/src/gallium/drivers/radeonsi/radeonsi_pipe.c > index acf3e2d..53bcac5 100644 > --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c > +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c > @@ -330,6 +330,8 @@ static int r600_get_param(struct pipe_screen* pscreen, > enum pipe_cap param) > case PIPE_CAP_START_INSTANCE: > case PIPE_CAP_NPOT_TEXTURES: > return 1; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > > case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: > return 64; > diff --git a/src/gallium/drivers/softpipe/sp_screen.c > b/src/gallium/drivers/softpipe/sp_screen.c > index 16aba5a..937035e 100644 > --- a/src/gallium/drivers/softpipe/sp_screen.c > +++ b/src/gallium/drivers/softpipe/sp_screen.c > @@ -173,6 +173,8 @@ softpipe_get_param(struct pipe_screen *screen, enum > pipe_cap param) > return 1; > case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: > return 0; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > } > /* should only get here on unhandled cases */ > debug_printf("Unexpected PIPE_CAP %d query\n", param); > diff --git a/src/gallium/drivers/svga/svga_screen.c > b/src/gallium/drivers/svga/svga_screen.c > index 3e71ac3..f0831b9 100644 > --- a/src/gallium/drivers/svga/svga_screen.c > +++ b/src/gallium/drivers/svga/svga_screen.c > @@ -150,6 +150,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap > param) > return 1; > case PIPE_CAP_POINT_SPRITE: > return 1; > + case PIPE_CAP_TGSI_TEXCOORD: > + return 0; > case PIPE_CAP_MAX_RENDER_TARGETS: > if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) > return 1; > diff --git a/src/gallium/include/pipe/p_defines.h > b/src/gallium/include/pipe/p_defines.h > index fdf6e7f..7f20b99 100644 > --- a/src/gallium/include/pipe/p_defines.h > +++ b/src/gallium/include/pipe/p_defines.h > @@ -498,7 +498,8 @@ enum pipe_cap { > PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT = 75, > PIPE_CAP_CUBE_MAP_ARRAY = 76, > PIPE_CAP_TEXTURE_BUFFER_OBJECTS = 77, > - PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78 > + PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78, > + PIPE_CAP_TGSI_TEXCOORD = 79 > }; > > /** > diff --git a/src/gallium/include/pipe/p_shader_tokens.h > b/src/gallium/include/pipe/p_shader_tokens.h > index a9fb6aa..6851dbf 100644 > --- a/src/gallium/include/pipe/p_shader_tokens.h > +++ b/src/gallium/include/pipe/p_shader_tokens.h > @@ -163,7 +163,9 @@ struct tgsi_declaration_interp > #define TGSI_SEMANTIC_BLOCK_ID 16 /**< id of the current block */ > #define TGSI_SEMANTIC_BLOCK_SIZE 17 /**< block size in threads */ > #define TGSI_SEMANTIC_THREAD_ID 18 /**< block-relative id of the current > thread */ > -#define TGSI_SEMANTIC_COUNT 19 /**< number of semantic values */ > +#define TGSI_SEMANTIC_TEXCOORD 19 /**< texture or sprite coordinates */ > +#define TGSI_SEMANTIC_PCOORD 20 /**< point sprite coordinate */ > +#define TGSI_SEMANTIC_COUNT 21 /**< number of semantic values */ > > struct tgsi_declaration_semantic > { > diff --git a/src/gallium/include/pipe/p_state.h > b/src/gallium/include/pipe/p_state.h > index ab49cab..dfafd0b 100644 > --- a/src/gallium/include/pipe/p_state.h > +++ b/src/gallium/include/pipe/p_state.h > @@ -145,7 +145,7 @@ struct pipe_rasterizer_state > unsigned line_stipple_factor:8; /**< [1..256] actually */ > unsigned line_stipple_pattern:16; > > - unsigned sprite_coord_enable; /* bitfield referring to 32 GENERIC inputs > */ > + uint32_t sprite_coord_enable; /* referring to 32 TEXCOORD/GENERIC inputs > */ > > float line_width; > float point_size; /**< used when no per-vertex size */ > diff --git a/src/mesa/state_tracker/st_context.c > b/src/mesa/state_tracker/st_context.c > index f9a584b..e2d074d 100644 > --- a/src/mesa/state_tracker/st_context.c > +++ b/src/mesa/state_tracker/st_context.c > @@ -183,6 +183,9 @@ st_create_context_priv( struct gl_context *ctx, struct > pipe_context *pipe, > screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); > st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); > > + st->needs_texcoord_semantic = > + screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD); > + > /* GL limits and extensions */ > st_init_limits(st); > st_init_extensions(st); > diff --git a/src/mesa/state_tracker/st_context.h > b/src/mesa/state_tracker/st_context.h > index b9a98cd..c6c68ad 100644 > --- a/src/mesa/state_tracker/st_context.h > +++ b/src/mesa/state_tracker/st_context.h > @@ -85,6 +85,8 @@ struct st_context > boolean has_time_elapsed; > boolean has_shader_model3; > > + boolean needs_texcoord_semantic; > + > /* On old libGL's for linux we need to invalidate the drawables > * on glViewpport calls, this is set via a option. > */ > diff --git a/src/mesa/state_tracker/st_program.c > b/src/mesa/state_tracker/st_program.c > index 6af8df3..7a38da84 100644 > --- a/src/mesa/state_tracker/st_program.c > +++ b/src/mesa/state_tracker/st_program.c > @@ -177,6 +177,7 @@ void > st_prepare_vertex_program(struct gl_context *ctx, > struct st_vertex_program *stvp) > { > + struct st_context *st = st_context(ctx); > GLuint attr; > > stvp->num_inputs = 0; > @@ -267,7 +268,8 @@ st_prepare_vertex_program(struct gl_context *ctx, > case VARYING_SLOT_TEX5: > case VARYING_SLOT_TEX6: > case VARYING_SLOT_TEX7: > - stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; > + stvp->output_semantic_name[slot] = st->needs_texcoord_semantic ? > + TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; > stvp->output_semantic_index[slot] = attr - VARYING_SLOT_TEX0; > break; > > @@ -275,10 +277,8 @@ st_prepare_vertex_program(struct gl_context *ctx, > default: > assert(attr < VARYING_SLOT_MAX); > stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; > - stvp->output_semantic_index[slot] = (VARYING_SLOT_VAR0 - > - VARYING_SLOT_TEX0 + > - attr - > - VARYING_SLOT_VAR0); > + stvp->output_semantic_index[slot] = st->needs_texcoord_semantic ? > + (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0); > break; > } > } > @@ -585,11 +585,18 @@ st_translate_fragment_program(struct st_context *st, > * fragment shader plus fixed-function hardware (such as > * BFC). > * > - * There is no requirement that semantic indexes start at > - * zero or be restricted to a particular range -- nobody > - * should be building tables based on semantic index. > + * However, some drivers may need us to identify the PNTC and > TEXi > + * varyings if, for example, their capability to replace them > with > + * sprite coordinates is limited. > */ > case VARYING_SLOT_PNTC: > + if (st->needs_texcoord_semantic) { > + input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD; > + input_semantic_index[slot] = 0; > + interpMode[slot] = TGSI_INTERPOLATE_LINEAR; > + break; > + } > + /* fall through */ > case VARYING_SLOT_TEX0: > case VARYING_SLOT_TEX1: > case VARYING_SLOT_TEX2: > @@ -598,13 +605,29 @@ st_translate_fragment_program(struct st_context *st, > case VARYING_SLOT_TEX5: > case VARYING_SLOT_TEX6: > case VARYING_SLOT_TEX7: > + if (st->needs_texcoord_semantic) { > + input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD; > + input_semantic_index[slot] = attr - VARYING_SLOT_TEX0; > + interpMode[slot] = > + st_translate_interp(stfp->Base.InterpQualifier[attr], > FALSE); > + break; > + } > + /* fall through */ > case VARYING_SLOT_VAR0: > default: > - /* Actually, let's try and zero-base this just for > - * readability of the generated TGSI. > + /* Semantic indices should be zero-based because drivers may > choose > + * to assign a fixed slot determined by that index. > + * This is useful because ARB_separate_shader_objects uses > location > + * qualifiers for linkage, and if the semantic index corresponds > to > + * these locations, linkage passes in the driver become > unecessary. > + * > + * If needs_texcoord_semantic is true, no semantic indices will > be > + * consumed for the TEXi varyings, and we can base the locations > of > + * the user varyings on VAR0. Otherwise, we use TEX0 as base > index. > */ > assert(attr >= VARYING_SLOT_TEX0); > - input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0); > + input_semantic_index[slot] = st->needs_texcoord_semantic ? > + (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0); > input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; > if (attr == VARYING_SLOT_PNTC) > interpMode[slot] = TGSI_INTERPOLATE_LINEAR; _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev