From c471525fdc16331ee41ec11ac039c5efe5b346e0 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Wed, 12 Jun 2019 19:24:52 +0200 Subject: [PATCH] zink: ensure non-fragment shaders use lod-versions of texture Acked-by: Jordan Justen --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 46 +++++++++++++++---- .../drivers/zink/nir_to_spirv/spirv_builder.c | 38 +++++++++++++++ .../drivers/zink/nir_to_spirv/spirv_builder.h | 14 ++++++ 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 1cfc821cc3b..4ab14b455e7 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -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); diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c index 053fba7b38b..8028b7a6d70 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -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, diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h index 03acd4110e7..d5f0e83e9b6 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -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, -- 2.30.2