diff options
author | Erik Faye-Lund <[email protected]> | 2019-06-12 19:24:52 +0200 |
---|---|---|
committer | Erik Faye-Lund <[email protected]> | 2019-10-28 08:51:44 +0000 |
commit | c471525fdc16331ee41ec11ac039c5efe5b346e0 (patch) | |
tree | b9e5af4334aec8825ae0f07d02262b28a9b20f8e | |
parent | 9cf6163ea1ac4f77d21dd06b1843c8314f4a0c99 (diff) |
zink: ensure non-fragment shaders use lod-versions of texture
Acked-by: Jordan Justen <[email protected]>
-rw-r--r-- | src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c | 46 | ||||
-rw-r--r-- | src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c | 38 | ||||
-rw-r--r-- | src/gallium/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 @@ -522,6 +522,25 @@ spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b, } 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, SpvId sampled_image, @@ -538,6 +557,25 @@ spirv_builder_emit_image_sample_proj_implicit_lod(struct spirv_builder *b, } 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, const SpvId *args, size_t num_args) 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 @@ -208,12 +208,26 @@ spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b, 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, const SpvId args[], size_t num_args); |