[Mesa-dev] [PATCH] gallium: add TGSI_SEMANTIC_TEXCOORD,PCOORD
Christoph Bumiller
e0425955 at student.tuwien.ac.at
Wed Mar 13 12:51:45 PDT 2013
Second attempt, 2 years ago no one replied or cared ...
We really need to know about these on nvc0 because there are only 8
fixed hardware locations that can be overwritten by sprite coordinates,
and one location that represents gl_PointCoord and unconditionally
returns sprite coordinates.
So far this was solved via a hack, which works since the locations the
state tracker picks aren't dynamic (and likely will never be, to facilitate
ARB_separate_shader_objects), but it still isn't nice to do it this way.
It looks like nv30 was using a hack, too, since it had a check for
Semantic.Index == 9, which is what mesa uses for PointCoord.
Implementing a safe, non-mesa-dependent way without these SEMANTICs would
be jumping through hoops and doing expensive shader recompilations just
because we like to destroy information at the gallium threshold, and that's
unacceptable.
I started to (try) fix up the other drivers, but maybe we just want a CAP
for this instead, since the default solution - if this is TEXCOORD then
treat it as GENERIC with semantic index += MAX_TEXCOORDS - doesn't really
look that nicer either.
E.g. if PIPE_CAP_RESTRICTED_SPRITE_COORDS is advertised, the state tracker
should use the TEXCOORD and PCOORD semantics, otherwise it should just use
GENERICs as before.
---
src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 39 ++++++++--------
src/gallium/auxiliary/tgsi/tgsi_dump.c | 1 +
src/gallium/auxiliary/tgsi/tgsi_strings.c | 2 +
src/gallium/docs/source/cso/rasterizer.rst | 2 +-
src/gallium/docs/source/tgsi.rst | 23 +++++++++-
src/gallium/drivers/freedreno/freedreno_compiler.c | 2 +
src/gallium/drivers/i915/i915_fpc_translate.c | 2 +
src/gallium/drivers/i915/i915_state_derived.c | 4 ++
src/gallium/drivers/llvmpipe/lp_setup_point.c | 29 ++++++------
src/gallium/drivers/nv30/nvfx_fragprog.c | 39 ++++++++--------
src/gallium/drivers/nv50/nv50_shader_state.c | 8 +--
src/gallium/drivers/nv50/nv50_surface.c | 5 +-
src/gallium/drivers/nvc0/nvc0_program.c | 37 +--------------
src/gallium/drivers/r300/r300_fs.c | 2 +
src/gallium/drivers/r300/r300_shader_semantics.h | 3 +-
src/gallium/drivers/r300/r300_vs.c | 2 +
src/gallium/drivers/r600/evergreen_state.c | 7 ++-
src/gallium/drivers/r600/r600_shader.c | 3 +-
src/gallium/drivers/r600/r600_state.c | 7 ++-
src/gallium/drivers/radeonsi/radeonsi_shader.c | 1 +
src/gallium/drivers/radeonsi/si_state.c | 2 +-
src/gallium/drivers/radeonsi/si_state_draw.c | 5 +-
src/gallium/include/pipe/p_shader_tokens.h | 36 +++++++++------
src/gallium/include/pipe/p_state.h | 2 +-
src/mesa/state_tracker/st_atom_rasterizer.c | 6 +--
src/mesa/state_tracker/st_program.c | 48 +++++++++----------
26 files changed, 162 insertions(+), 155 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..d4ed0f7 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -233,28 +233,29 @@ widepoint_first_point(struct draw_stage *stage,
wide->num_texcoord_gen = 0;
- /* Loop over fragment shader inputs looking for generic inputs
- * for which bit 'k' in sprite_coord_enable is set.
+ /* Loop over fragment shader inputs looking for the PCOORD input or
+ * TEXCOORD 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 == TGSI_SEMANTIC_TEXCOORD) {
+ /* Note that sprite_coord enable is a bitfield of 8 bits. */
+ if (si >= 8 || !(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;
}
}
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..eb73521 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
@@ -65,6 +65,8 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] =
"BCOLOR",
"FOG",
"PSIZE",
+ "PCOORD",
+ "TEXCOORD",
"GENERIC",
"NORMAL",
"FACE",
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index f4e24f0..61124e5 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -162,7 +162,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 TEXCOORD
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 d9a7fe9..2016e25 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -1922,7 +1922,7 @@ TGSI_SEMANTIC_PSIZE
"""""""""""""""""""
Vertex shader input and output registers may be labeled with
-TGIS_SEMANTIC_PSIZE to indicate that the register contains a point size
+TGSI_SEMANTIC_PSIZE to indicate that the register contains a point size
in the form (S, 0, 0, 1). The point size controls the width or diameter
of points for rasterization. This label cannot be used in fragment
shaders.
@@ -1930,13 +1930,32 @@ shaders.
When using this semantic, be sure to set the appropriate state in the
:ref:`rasterizer` first.
+TGSI_SEMANTIC_PCOORD
+""""""""""""""""""""
+
+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.
+This semantic should be used for gl_PointCoord.
+
+
+TGSI_SEMANTIC_TEXCOORD
+""""""""""""""""""""""
+
+Vertex shader outputs and fragment shader inputs may be labeled with this
+semantic to make the registers 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.
+This semantic should be used for gl_TexCoord.
+
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_NORMAL
diff --git a/src/gallium/drivers/freedreno/freedreno_compiler.c b/src/gallium/drivers/freedreno/freedreno_compiler.c
index 0610902..c3c81d1 100644
--- a/src/gallium/drivers/freedreno/freedreno_compiler.c
+++ b/src/gallium/drivers/freedreno/freedreno_compiler.c
@@ -102,6 +102,8 @@ semantic_idx(struct tgsi_declaration_semantic *semantic)
int idx = semantic->Name;
if (idx == TGSI_SEMANTIC_GENERIC)
idx = TGSI_SEMANTIC_COUNT + semantic->Index;
+ if (idx == TGSI_SEMANTIC_TEXCOORD)
+ idx = TGSI_SEMANTIC_COUNT + semantic->Index + TGSI_MAX_TEXCOORDS;
return idx;
}
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index def9a03..94ae5aa 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -230,6 +230,8 @@ src_vector(struct i915_fp_compile *p,
src = swizzle(src, W, W, W, W);
break;
case TGSI_SEMANTIC_GENERIC:
+ sem_ind += TGSI_MAX_TEXCOORDS;
+ case TGSI_SEMANTIC_TEXCOORD:
{
int real_tex_unit = get_mapping(fs, sem_ind);
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index e01f16e..a1dde05 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -82,11 +82,15 @@ static void calculate_vertex_layout(struct i915_context *i915)
assert(fs->info.input_semantic_index[i] < 2);
colors[fs->info.input_semantic_index[i]] = TRUE;
break;
+ case TGSI_SEMANTIC_TEXCOORD:
case TGSI_SEMANTIC_GENERIC:
{
/* texcoords/varyings/other generic */
uint unit = fs->info.input_semantic_index[i];
+ if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_GENERIC)
+ unit += TGSI_MAX_TEXCOORDS;
+
texCoords[find_mapping(fs, unit)] = TRUE;
needW = TRUE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index 146f1bd..71f11bb 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -220,6 +220,9 @@ setup_point_coefficients( struct lp_setup_context *setup,
boolean perspective = !!(interp == LP_INTERP_PERSPECTIVE);
unsigned i;
+ const unsigned sn = shader->info.base.input_semantic_name[slot];
+ const unsigned si = shader->info.base.input_semantic_index[slot];
+
if (perspective & usage_mask) {
fragcoord_usage_mask |= TGSI_WRITEMASK_W;
}
@@ -238,25 +241,21 @@ setup_point_coefficients( struct lp_setup_context *setup,
/* Sprite tex coords may use linear interpolation someday */
/* fall-through */
case LP_INTERP_PERSPECTIVE:
- /* check if the sprite coord flag is set for this attribute.
+ /* Check if the sprite coord flag is set for this attribute or
+ * if has the PCOORD semantic.
* 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_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);
- }
+ if (sn == TGSI_SEMANTIC_PCOORD ||
+ (sn == TGSI_SEMANTIC_TEXCOORD &&
+ si < 8 && setup->sprite_coord_enable & (1 << si))) {
+ 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/nv30/nvfx_fragprog.c b/src/gallium/drivers/nv30/nvfx_fragprog.c
index 935804e..5805b12 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 later assigned to remaining TC slots */
+ return TRUE;
default:
assert(0);
return FALSE;
@@ -955,22 +957,21 @@ 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) {
+ 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.Name == TGSI_SEMANTIC_PCOORD)
+ 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;
}
return FALSE;
}
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index 7f05243..48aef24 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -238,11 +238,9 @@ 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_PCOORD &&
+ (fp->in[i].sn != TGSI_SEMANTIC_TEXCOORD ||
+ !(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si)))) {
m += n;
continue;
}
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/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 6e1b4e4..80bff8c 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -59,6 +59,8 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
break;
case TGSI_SEMANTIC_GENERIC:
+ index += ATTR_TEXCOORD_COUNT;
+ 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 b756048..5a2eacb 100644
--- a/src/gallium/drivers/r300/r300_shader_semantics.h
+++ b/src/gallium/drivers/r300/r300_shader_semantics.h
@@ -25,7 +25,8 @@
#define ATTR_UNUSED (-1)
#define ATTR_COLOR_COUNT 2
-#define ATTR_GENERIC_COUNT 32
+#define ATTR_TEXCOORD_COUNT TGSI_MAX_TEXCOORDS
+#define ATTR_GENERIC_COUNT 32 /* includes TEXCOORDs */
/* 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 33612a3..5cab47f 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -70,6 +70,8 @@ static void r300_shader_read_vs_outputs(
break;
case TGSI_SEMANTIC_GENERIC:
+ index += ATTR_TEXCOORD_COUNT;
+ case TGSI_SEMANTIC_TEXCOORD:
assert(index < ATTR_GENERIC_COUNT);
vs_outputs->generic[index] = i;
vs_outputs->num_generic++;
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 2bdefb0..d0148af 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -940,7 +940,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
}
spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
- if (state->sprite_coord_enable) {
+ if (state->point_quad_rasterization) {
spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
S_0286D4_PNT_SPRITE_OVRD_X(2) |
S_0286D4_PNT_SPRITE_OVRD_Y(3) |
@@ -3295,8 +3295,9 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
tmp |= S_028644_FLAT_SHADE(1);
}
- if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
- (sprite_coord_enable & (1 << rshader->input[i].sid))) {
+ if (rshader->input[i].name == TGSI_SEMANTIC_PCOORD &&
+ (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+ (sprite_coord_enable & (1 << rshader->input[i].sid)))) {
tmp |= S_028644_PT_SPRITE_TEX(1);
}
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 29facf7..7788674 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -806,7 +806,8 @@ static int r600_spi_sid(struct r600_shader_io * io)
name == TGSI_SEMANTIC_FACE)
index = 0;
else {
- if (name == TGSI_SEMANTIC_GENERIC) {
+ if (name == TGSI_SEMANTIC_TEXCOORD ||
+ name == TGSI_SEMANTIC_GENERIC) {
/* For generic params simply use sid from tgsi */
index = io->sid;
} else {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 846c159..63e5373 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -935,7 +935,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
}
spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
- if (state->sprite_coord_enable) {
+ if (state->point_quad_rasterization) {
spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
S_0286D4_PNT_SPRITE_OVRD_X(2) |
S_0286D4_PNT_SPRITE_OVRD_Y(3) |
@@ -2722,8 +2722,9 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
rctx->rasterizer && rctx->rasterizer->flatshade))
tmp |= S_028644_FLAT_SHADE(1);
- if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
- sprite_coord_enable & (1 << rshader->input[i].sid)) {
+ if (rshader->input[i].name == TGSI_SEMANTIC_PCOORD ||
+ (rshader->input[i].name == TGSI_SEMANTIC_TEXCOORD &&
+ sprite_coord_enable & (1 << rshader->input[i].sid))) {
tmp |= S_028644_PT_SPRITE_TEX(1);
}
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 95ccd1e..69396d9 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -591,6 +591,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
color_count++;
}
break;
+ case TGSI_SEMANTIC_TEXCOORD:
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
target = V_008DFC_SQ_EXP_PARAM + param_count;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index a395ec4..d84ac81 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -422,7 +422,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
rs->offset_scale = state->offset_scale * 12.0f;
tmp = S_0286D4_FLAT_SHADE_ENA(1);
- if (state->sprite_coord_enable) {
+ if (state->point_quad_rasterization) {
tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 1049d2b..37ceb10 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -332,8 +332,9 @@ bcolor:
tmp |= S_028644_FLAT_SHADE(1);
}
- if (name == TGSI_SEMANTIC_GENERIC &&
- rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
+ if (name == TGSI_SEMANTIC_PCOORD ||
+ (name == TGSI_SEMANTIC_GENERIC &&
+ rctx->sprite_coord_enable & (1 << ps->input[i].sid))) {
tmp |= S_028644_PT_SPRITE_TEX(1);
}
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index a9fb6aa..86061b4 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -149,21 +149,27 @@ struct tgsi_declaration_interp
#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */
#define TGSI_SEMANTIC_FOG 3
#define TGSI_SEMANTIC_PSIZE 4
-#define TGSI_SEMANTIC_GENERIC 5
-#define TGSI_SEMANTIC_NORMAL 6
-#define TGSI_SEMANTIC_FACE 7
-#define TGSI_SEMANTIC_EDGEFLAG 8
-#define TGSI_SEMANTIC_PRIMID 9
-#define TGSI_SEMANTIC_INSTANCEID 10
-#define TGSI_SEMANTIC_VERTEXID 11
-#define TGSI_SEMANTIC_STENCIL 12
-#define TGSI_SEMANTIC_CLIPDIST 13
-#define TGSI_SEMANTIC_CLIPVERTEX 14
-#define TGSI_SEMANTIC_GRID_SIZE 15 /**< grid size in blocks */
-#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_PCOORD 5 /**< sprite coordinates */
+#define TGSI_SEMANTIC_TEXCOORD 6 /**< texture or sprite coordinates */
+#define TGSI_SEMANTIC_GENERIC 7
+#define TGSI_SEMANTIC_NORMAL 8
+#define TGSI_SEMANTIC_FACE 9
+#define TGSI_SEMANTIC_EDGEFLAG 10
+#define TGSI_SEMANTIC_PRIMID 11
+#define TGSI_SEMANTIC_INSTANCEID 12
+#define TGSI_SEMANTIC_VERTEXID 13
+#define TGSI_SEMANTIC_STENCIL 14
+#define TGSI_SEMANTIC_CLIPDIST 15
+#define TGSI_SEMANTIC_CLIPVERTEX 16
+#define TGSI_SEMANTIC_GRID_SIZE 17 /**< grid size in blocks */
+#define TGSI_SEMANTIC_BLOCK_ID 18 /**< id of the current block */
+#define TGSI_SEMANTIC_BLOCK_SIZE 19 /**< block size in threads */
+#define TGSI_SEMANTIC_THREAD_ID 20 /**< block-relative id of the current thread */
+#define TGSI_SEMANTIC_COUNT 21 /**< number of semantic values */
+
+/* Semantic index limits:
+ */
+#define TGSI_MAX_TEXCOORDS 8
struct tgsi_declaration_semantic
{
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index ab49cab..967461f 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 */
+ uint8_t sprite_coord_enable; /* referring to 8 TEXCOORD inputs */
float line_width;
float point_size; /**< used when no per-vertex size */
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 0e2a152..0030df0 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -163,7 +163,7 @@ static void update_raster_state( struct st_context *st )
raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
/* Coord replacement flags. If bit 'k' is set that means
- * that we need to replace GENERIC[k] attrib with an automatically
+ * that we need to replace TEXCOORD[k] attrib with an automatically
* computed texture coord.
*/
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
@@ -171,10 +171,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 f56f7cb..5c69670 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -574,22 +574,15 @@ st_translate_fragment_program(struct st_context *st,
input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
- /* In most cases, there is nothing special about these
- * inputs, so adopt a convention to use the generic
- * semantic name and the mesa FRAG_ATTRIB_ number as the
- * index.
- *
- * All that is required is that the vertex shader labels
- * its own outputs similarly, and that the vertex shader
- * generates at least every output required by the
- * 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.
- */
case FRAG_ATTRIB_PNTC:
+ input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ /* Semantic indices for TGSI_SEMANTIC_TEXCOORD are limited to [0,7],
+ * which is also the size of the bitfield to enable replacement with
+ * sprite coordinates.
+ */
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1:
case FRAG_ATTRIB_TEX2:
@@ -598,19 +591,24 @@ st_translate_fragment_program(struct st_context *st,
case FRAG_ATTRIB_TEX5:
case FRAG_ATTRIB_TEX6:
case FRAG_ATTRIB_TEX7:
+ input_semantic_index[slot] = attr - FRAG_ATTRIB_TEX0;
+ input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
+ interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
+ FALSE);
+ break;
+ /* Semantic indices should start at 0 because drivers may assign
+ * fixed slots based on semantic index.
+ * This is useful because ARB_separate_shader_objects uses location
+ * qualifiers for linkage, and the semantic index should correspond
+ * to these locations, and linkage passes become unncessary.
+ */
case FRAG_ATTRIB_VAR0:
default:
- /* 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;
- if (attr == FRAG_ATTRIB_PNTC)
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- else
- interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
- FALSE);
+ interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
+ FALSE);
break;
}
}
--
1.7.3.4
More information about the mesa-dev
mailing list