summaryrefslogtreecommitdiff
path: root/src/broadcom/compiler/nir_to_vir.c
diff options
context:
space:
mode:
authorIago Toral Quiroga <itoral@igalia.com>2021-07-13 12:47:20 +0200
committerMarge Bot <eric+marge@anholt.net>2021-07-14 12:05:56 +0000
commit940725a7d991939aae576f73e4815fad34a68a22 (patch)
tree364037e5a7733d78bae91253646f27a7522911e7 /src/broadcom/compiler/nir_to_vir.c
parent82fadbd3ab3809184c0ca21d4dcb995abac7baa5 (diff)
broadcom/compiler: implement gl_PrimitiveID in FS without a GS
OpenGL ES 3.1 specifies that a geometry shader can write to gl_PrimitiveID, which can then be read by a fragment shader. OpenGL ES 3.2 additionally adds the capacity for the fragment shader to read gl_PrimitiveID even if there is no geometry shader. This commit adds support for this feature, which is also implicitly expected by the geometry shader feature in Vulkan 1.0. Fixes: dEQP-VK.pipeline.framebuffer_attachment.no_attachments dEQP-VK.pipeline.framebuffer_attachment.no_attachments_ms Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11874>
Diffstat (limited to 'src/broadcom/compiler/nir_to_vir.c')
-rw-r--r--src/broadcom/compiler/nir_to_vir.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index ab04e4cf269..9f0dc14519f 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -2101,6 +2101,14 @@ ntq_setup_fs_inputs(struct v3d_compile *c)
if (var->data.location == VARYING_SLOT_POS) {
emit_fragcoord_input(c, loc);
+ } else if (var->data.location == VARYING_SLOT_PRIMITIVE_ID &&
+ !c->fs_key->has_gs) {
+ /* If the fragment shader reads gl_PrimitiveID and we
+ * don't have a geometry shader in the pipeline to write
+ * it then we program the hardware to inject it as
+ * an implicit varying. Take it from there.
+ */
+ c->inputs[loc * 4] = c->primitive_id;
} else if (util_varying_is_point_coord(var->data.location,
c->fs_key->point_sprite_mask)) {
c->inputs[loc * 4 + 0] = c->point_x;
@@ -3143,6 +3151,7 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
* VPM output header. According to docs, we should read this
* using ldvpm(v,d)_in (See Table 71).
*/
+ assert(c->s->info.stage == MESA_SHADER_GEOMETRY);
ntq_store_dest(c, &instr->dest, 0,
vir_LDVPMV_IN(c, vir_uniform_ui(c, 0)));
break;
@@ -3764,9 +3773,15 @@ nir_to_vir(struct v3d_compile *c)
c->payload_w_centroid = vir_MOV(c, vir_reg(QFILE_REG, 1));
c->payload_z = vir_MOV(c, vir_reg(QFILE_REG, 2));
- /* V3D 4.x can disable implicit point coordinate varyings if
- * they are not used.
- */
+ /* V3D 4.x can disable implicit varyings if they are not used */
+ c->fs_uses_primitive_id =
+ nir_find_variable_with_location(c->s, nir_var_shader_in,
+ VARYING_SLOT_PRIMITIVE_ID);
+ if (c->fs_uses_primitive_id && !c->fs_key->has_gs) {
+ c->primitive_id =
+ emit_fragment_varying(c, NULL, -1, 0, 0);
+ }
+
if (c->fs_key->is_points &&
(c->devinfo->ver < 40 || program_reads_point_coord(c))) {
c->point_x = emit_fragment_varying(c, NULL, -1, 0, 0);