zink: implement nir_texop_txs
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Wed, 30 Oct 2019 09:50:20 +0000 (10:50 +0100)
committerMarge Bot <eric+marge@anholt.net>
Sat, 18 Jan 2020 10:45:38 +0000 (10:45 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3275>

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

index b9fb5380b17ea4f02b899822dda0ee4b6e73cc30..35c2fc4c0f39d71e423c09c5d17a792480c3c905 100644 (file)
@@ -1366,8 +1366,10 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
           tex->op == nir_texop_txb ||
           tex->op == nir_texop_txl ||
           tex->op == nir_texop_txd ||
-          tex->op == nir_texop_txf);
-   assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
+          tex->op == nir_texop_txf ||
+          tex->op == nir_texop_txs);
+   assert(tex->op == nir_texop_txs ||
+          nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
    assert(tex->texture_index == tex->sampler_index);
 
    SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0;
@@ -1396,7 +1398,8 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
 
       case nir_tex_src_lod:
          assert(nir_src_num_components(tex->src[i].src) == 1);
-         if (tex->op == nir_texop_txf)
+         if (tex->op == nir_texop_txf ||
+             tex->op == nir_texop_txs)
             lod = get_src_int(ctx, &tex->src[i].src);
          else
             lod = get_src_float(ctx, &tex->src[i].src);
@@ -1445,6 +1448,15 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
 
    SpvId dest_type = get_dest_type(ctx, &tex->dest, tex->dest_type);
 
+   if (tex->op == nir_texop_txs) {
+      SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
+      SpvId result = spirv_builder_emit_image_query_size(&ctx->builder,
+                                                         dest_type, image,
+                                                         lod);
+      store_dest(ctx, &tex->dest, result, tex->dest_type);
+      return;
+   }
+
    if (proj) {
       SpvId constituents[coord_components + 1];
       if (coord_components == 1)
@@ -1779,8 +1791,10 @@ nir_to_spirv(struct nir_shader *s)
    }
 
    // TODO: only enable when needed
-   if (s->info.stage == MESA_SHADER_FRAGMENT)
+   if (s->info.stage == MESA_SHADER_FRAGMENT) {
       spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampled1D);
+      spirv_builder_emit_cap(&ctx.builder, SpvCapabilityImageQuery);
+   }
 
    ctx.stage = s->info.stage;
    ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
index 572b38b291de58ba14faedfb840a2c600bf8889e..bae23c97d4cd9a8215d74f2273be79fd5e37996e 100644 (file)
@@ -607,6 +607,32 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image_query_size(struct spirv_builder *b,
+                                    SpvId result_type,
+                                    SpvId image,
+                                    SpvId lod)
+{
+   int opcode = SpvOpImageQuerySize;
+   int words = 4;
+   if (lod) {
+      words++;
+      opcode = SpvOpImageQuerySizeLod;
+   }
+
+   SpvId result = spirv_builder_new_id(b);
+   spirv_buffer_prepare(&b->instructions, words);
+   spirv_buffer_emit_word(&b->instructions, opcode | (words << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, image);
+
+   if (lod)
+      spirv_buffer_emit_word(&b->instructions, lod);
+
+   return result;
+}
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,
index d7213d85f6543656e6eeaad71497df3a5ebfe5a5..56db0a11cf5204a38fc5225bbace6e9844171582 100644 (file)
@@ -228,6 +228,12 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b,
                                SpvId coordinate,
                                SpvId lod);
 
+SpvId
+spirv_builder_emit_image_query_size(struct spirv_builder *b,
+                                    SpvId result_type,
+                                    SpvId image,
+                                    SpvId lod);
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,