zink: ensure non-fragment shaders use lod-versions of texture
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Wed, 12 Jun 2019 17:24:52 +0000 (19:24 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:44 +0000 (08:51 +0000)
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
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 1cfc821cc3b7f6731b28dcadbb31f64ace21565c..4ab14b455e74e845dd2d8ffb517c8d82c48a799c 100644 (file)
@@ -1076,8 +1076,8 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
    assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
    assert(tex->texture_index == tex->sampler_index);
 
-   bool has_proj = false;
-   SpvId coord = 0, proj;
+   bool has_proj = false, has_lod = false;
+   SpvId coord = 0, proj, lod;
    unsigned coord_components;
    for (unsigned i = 0; i < tex->num_srcs; i++) {
       switch (tex->src[i].src_type) {
@@ -1092,12 +1092,23 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
          assert(nir_src_num_components(tex->src[i].src) == 1);
          break;
 
+      case nir_tex_src_lod:
+         has_lod = true;
+         lod = get_src_float(ctx, &tex->src[i].src);
+         assert(nir_src_num_components(tex->src[i].src) == 1);
+         break;
+
       default:
          fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
          unreachable("unknown texture source");
       }
    }
 
+   if (!has_lod && ctx->stage != MESA_SHADER_FRAGMENT) {
+      has_lod = true;
+      lod = spirv_builder_const_float(&ctx->builder, 32, 0);
+   }
+
    bool is_ms;
    SpvDim dimension = type_to_dim(tex->sampler_dim, &is_ms);
    SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
@@ -1131,14 +1142,29 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
                                                             constituents,
                                                             coord_components);
 
-      result = spirv_builder_emit_image_sample_proj_implicit_lod(&ctx->builder,
-                                                                 dest_type,
-                                                                 load,
-                                                                 merged);
-   } else
-      result = spirv_builder_emit_image_sample_implicit_lod(&ctx->builder,
-                                                            dest_type, load,
-                                                            coord);
+      if (has_lod)
+         result = spirv_builder_emit_image_sample_proj_explicit_lod(&ctx->builder,
+                                                                    dest_type,
+                                                                    load,
+                                                                    merged,
+                                                                    lod);
+      else
+         result = spirv_builder_emit_image_sample_proj_implicit_lod(&ctx->builder,
+                                                                    dest_type,
+                                                                    load,
+                                                                    merged);
+   } else {
+      if (has_lod)
+         result = spirv_builder_emit_image_sample_explicit_lod(&ctx->builder,
+                                                               dest_type,
+                                                               load,
+                                                               coord, lod);
+      else
+         result = spirv_builder_emit_image_sample_implicit_lod(&ctx->builder,
+                                                               dest_type,
+                                                               load,
+                                                               coord);
+   }
    spirv_builder_emit_decoration(&ctx->builder, result,
                                  SpvDecorationRelaxedPrecision);
 
index 053fba7b38b8aabe65bb959318469c5d291cab18..8028b7a6d706af8ce459943b964b1168483a8128 100644 (file)
@@ -521,6 +521,25 @@ spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image_sample_explicit_lod(struct spirv_builder *b,
+                                             SpvId result_type,
+                                             SpvId sampled_image,
+                                             SpvId coordinate,
+                                             SpvId lod)
+{
+   SpvId result = spirv_builder_new_id(b);
+   spirv_buffer_prepare(&b->instructions, 7);
+   spirv_buffer_emit_word(&b->instructions, SpvOpImageSampleExplicitLod | (7 << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, sampled_image);
+   spirv_buffer_emit_word(&b->instructions, coordinate);
+   spirv_buffer_emit_word(&b->instructions, SpvImageOperandsLodMask);
+   spirv_buffer_emit_word(&b->instructions, lod);
+   return result;
+}
+
 SpvId
 spirv_builder_emit_image_sample_proj_implicit_lod(struct spirv_builder *b,
                                                   SpvId result_type,
@@ -537,6 +556,25 @@ spirv_builder_emit_image_sample_proj_implicit_lod(struct spirv_builder *b,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image_sample_proj_explicit_lod(struct spirv_builder *b,
+                                                  SpvId result_type,
+                                                  SpvId sampled_image,
+                                                  SpvId coordinate,
+                                                  SpvId lod)
+{
+   SpvId result = spirv_builder_new_id(b);
+   spirv_buffer_prepare(&b->instructions, 7);
+   spirv_buffer_emit_word(&b->instructions, SpvOpImageSampleProjImplicitLod | (7 << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, sampled_image);
+   spirv_buffer_emit_word(&b->instructions, coordinate);
+   spirv_buffer_emit_word(&b->instructions, SpvImageOperandsLodMask);
+   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 03acd4110e763a7bfb132fd64cd8ebf2983941df..d5f0e83e9b695488d1bef10eacd738acd7417628 100644 (file)
@@ -207,12 +207,26 @@ spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b,
                                              SpvId sampled_image,
                                              SpvId coordinate);
 
+SpvId
+spirv_builder_emit_image_sample_explicit_lod(struct spirv_builder *b,
+                                             SpvId result_type,
+                                             SpvId sampled_image,
+                                             SpvId coordinate,
+                                             SpvId lod);
+
 SpvId
 spirv_builder_emit_image_sample_proj_implicit_lod(struct spirv_builder *b,
                                                   SpvId result_type,
                                                   SpvId sampled_image,
                                                   SpvId coordinate);
 
+SpvId
+spirv_builder_emit_image_sample_proj_explicit_lod(struct spirv_builder *b,
+                                                  SpvId result_type,
+                                                  SpvId sampled_image,
+                                                  SpvId coordinate,
+                                                  SpvId lod);
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,