zink: use actual const for const offset
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Thu, 27 May 2021 09:17:01 +0000 (11:17 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 27 May 2021 11:16:38 +0000 (11:16 +0000)
When we emit constants, we don't know what type they'll be used as, so
we just emit them as uint, and then bitcast them to whatever we need.

But this isn't a good idea for ConstOffset, which needs to actually be a
const value, and not a const value bitcasted. So we sadly have to
open-code the const emitting here to avoid the problem.

Fixes: e963d35efe1 ("zink: use ConstOffset for nir_tex_src_offset")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4831
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11032>

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

index 62ef3cc..6c7543d 100644 (file)
@@ -2896,9 +2896,26 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
          break;
 
       case nir_tex_src_offset:
-         if (nir_src_is_const(tex->src[i].src))
-            const_offset = get_src_int(ctx, &tex->src[i].src);
-         else
+         if (nir_src_is_const(tex->src[i].src)) {
+            nir_const_value *v = nir_src_as_const_value(tex->src[i].src);
+            unsigned bit_size = nir_src_bit_size(tex->src[i].src);
+            unsigned num_components = nir_src_num_components(tex->src[i].src);
+
+            SpvId components[NIR_MAX_VEC_COMPONENTS];
+            for (int i = 0; i < num_components; ++i) {
+               int64_t tmp = nir_const_value_as_int(v[i], bit_size);
+               components[i] = emit_int_const(ctx, bit_size, tmp);
+            }
+
+            if (num_components > 1) {
+               SpvId type = get_ivec_type(ctx, bit_size, num_components);
+               const_offset = spirv_builder_const_composite(&ctx->builder,
+                                                            type,
+                                                            components,
+                                                            num_components);
+            } else
+               const_offset = components[0];
+         } else
             offset = get_src_int(ctx, &tex->src[i].src);
          break;