diff options
author | Kristian H. Kristensen <[email protected]> | 2019-09-13 15:20:05 -0700 |
---|---|---|
committer | Kristian H. Kristensen <[email protected]> | 2019-09-18 16:59:10 -0700 |
commit | be38480064a78c4a4391f87e45f7dd78dc88edce (patch) | |
tree | 08324f0963a69dbe6272601711a294e59da078ef /src | |
parent | d38e0a6326310d8c92e8344a5feeda1e869760e8 (diff) |
freedreno/a6xx: Track location of gl_Position out as we link it
When using xfb and rasterizing, the fragment shader may have fewer
inputs than the vertex shader outputs. We can't rely on gl_Position to
be placed at fs->total_in, but have to instead remember where we add
it in the link map and use that location.
Fixes 100+ tesselation dEQPs under
dEQP-GLES31.functional.tessellation.primitive_discard.*
dEQP-GLES31.functional.tessellation.user_defined_io.*
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/freedreno/registers/a6xx.xml | 10 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_pipeline.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_program.c | 8 |
3 files changed, 13 insertions, 13 deletions
diff --git a/src/freedreno/registers/a6xx.xml b/src/freedreno/registers/a6xx.xml index 13c3dcd5a01..30f0fe85093 100644 --- a/src/freedreno/registers/a6xx.xml +++ b/src/freedreno/registers/a6xx.xml @@ -2423,7 +2423,7 @@ to upconvert to 32b float internally? hw streamout (rather than stg instructions in shader) </doc> <bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/> - <bitfield name="NUMNONPOSVAR" low="8" high="15" type="uint"/> + <bitfield name="POSITIONLOC" low="8" high="15" type="uint"/> <!-- This seems to be the OUTLOC for the psize output. It could possibly be the max-OUTLOC position, but it is only set when VS writes psize @@ -2434,14 +2434,10 @@ to upconvert to 32b float internally? <reg32 offset="0x9303" name="VPC_PACK_3"> <doc> - domain shader version - - num of varyings plus four for gl_Position (plus one if gl_PointSize) - plus # of transform-feedback (streamout) varyings if using the - hw streamout (rather than stg instructions in shader) + domain shader version of VPC_PACK </doc> <bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/> - <bitfield name="NUMNONPOSVAR" low="8" high="15" type="uint"/> + <bitfield name="POSITIONLOC" low="8" high="15" type="uint"/> <!-- This seems to be the OUTLOC for the psize output. It could possibly be the max-OUTLOC position, but it is only set when VS writes psize diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 9964020a81f..12661f40082 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -523,9 +523,11 @@ tu6_emit_vpc(struct tu_cs *cs, ir3_find_output_regid(vs, VARYING_SLOT_POS); const uint32_t pointsize_regid = ir3_find_output_regid(vs, VARYING_SLOT_PSIZ); - uint32_t pointsize_loc = 0xff; - if (position_regid != regid(63, 0)) + uint32_t pointsize_loc = 0xff, position_loc = 0xff; + if (position_regid != regid(63, 0)) { + position_loc = linkage.max_loc; ir3_link_add(&linkage, position_regid, 0xf, linkage.max_loc); + } if (pointsize_regid != regid(63, 0)) { pointsize_loc = linkage.max_loc; ir3_link_add(&linkage, pointsize_regid, 0x1, linkage.max_loc); @@ -559,7 +561,7 @@ tu6_emit_vpc(struct tu_cs *cs, 0xff00ff00); tu_cs_emit_pkt4(cs, REG_A6XX_VPC_PACK, 1); - tu_cs_emit(cs, A6XX_VPC_PACK_NUMNONPOSVAR(fs->total_in) | + tu_cs_emit(cs, A6XX_VPC_PACK_POSITIONLOC(position_loc) | A6XX_VPC_PACK_PSIZELOC(pointsize_loc) | A6XX_VPC_PACK_STRIDE_IN_VPC(linkage.max_loc)); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index 8931d40a8e2..47ba86353b1 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -275,7 +275,7 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, uint32_t vertex_regid, instance_regid; uint32_t ij_pix_regid, ij_samp_regid, ij_cent_regid, ij_size_regid; enum a3xx_threadsize fssz; - uint8_t psize_loc = ~0; + uint8_t psize_loc = ~0, pos_loc = ~0; int i, j; static const struct ir3_shader_variant dummy_fs = {0}; @@ -393,8 +393,10 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, OUT_RING(ring, ~varmask[3]); /* VPC_VAR[3].DISABLE */ /* a6xx appends pos/psize to end of the linkage map: */ - if (VALIDREG(pos_regid)) + if (VALIDREG(pos_regid)) { + pos_loc = l.max_loc; ir3_link_add(&l, pos_regid, 0xf, l.max_loc); + } if (VALIDREG(psize_regid)) { psize_loc = l.max_loc; @@ -551,7 +553,7 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, } OUT_PKT4(ring, REG_A6XX_VPC_PACK, 1); - OUT_RING(ring, A6XX_VPC_PACK_NUMNONPOSVAR(fs->total_in) | + OUT_RING(ring, A6XX_VPC_PACK_POSITIONLOC(pos_loc) | A6XX_VPC_PACK_PSIZELOC(psize_loc) | A6XX_VPC_PACK_STRIDE_IN_VPC(l.max_loc)); |