summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Faye-Lund <[email protected]>2019-06-12 19:24:52 +0200
committerErik Faye-Lund <[email protected]>2019-10-28 08:51:44 +0000
commitc471525fdc16331ee41ec11ac039c5efe5b346e0 (patch)
treeb9e5af4334aec8825ae0f07d02262b28a9b20f8e
parent9cf6163ea1ac4f77d21dd06b1843c8314f4a0c99 (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.c46
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c38
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h14
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);