zink: re-transform gl_Position for gs input
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Wed, 14 Oct 2020 14:34:06 +0000 (10:34 -0400)
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 16 Oct 2020 13:15:24 +0000 (09:15 -0400)
we've transformed this in the vertex output, so we need to undo that here

ideally we'd only be performing this transform once, but that's going to get
complicated later with the halfz extension which requires shader keys on top
of this, so we can get around to simplifying things at that stage

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7139>

src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c

index 498cb27..a22b4cf 100644 (file)
@@ -1577,6 +1577,28 @@ emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
                                           ptr);
    unsigned num_components = nir_dest_num_components(intr->dest);
    unsigned bit_size = nir_dest_bit_size(intr->dest);
+   if (ctx->stage > MESA_SHADER_VERTEX && ctx->stage <= MESA_SHADER_GEOMETRY &&
+       (nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]))->data.location == VARYING_SLOT_POS)) {
+      /* we previously transformed opengl gl_Position -> vulkan gl_Position in vertex shader,
+       * so now we have to reverse that and construct a new gl_Position:
+
+         gl_Position.z = gl_Position.z * 2 - gl_Position.w
+
+       */
+      SpvId components[4];
+      SpvId f_type = get_fvec_type(ctx, 32, 1);
+      SpvId base_type = get_fvec_type(ctx, 32, 4);
+      for (unsigned c = 0; c < 4; c++) {
+         uint32_t member[] = { c };
+
+         components[c] = spirv_builder_emit_composite_extract(&ctx->builder, f_type, result, member, 1);
+      }
+      components[2] = emit_binop(ctx, SpvOpFMul, f_type, components[2], emit_float_const(ctx, 32, 2.0));
+      components[2] = emit_binop(ctx, SpvOpFSub, f_type, components[2], components[3]);
+
+      result = spirv_builder_emit_composite_construct(&ctx->builder, base_type,
+                                                      components, 4);
+   }
    result = bitcast_to_uvec(ctx, result, bit_size, num_components);
    store_dest(ctx, &intr->dest, result, nir_type_uint);
 }