From a005fae564b2b67f7c93207ac24fb92259231901 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Fri, 12 Jul 2019 12:43:20 +0200 Subject: [PATCH] zink: support more texturing Acked-by: Jordan Justen --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 58 +++++------- .../drivers/zink/nir_to_spirv/spirv_builder.c | 90 +++++++------------ .../drivers/zink/nir_to_spirv/spirv_builder.h | 30 ++----- 3 files changed, 63 insertions(+), 115 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 e55fe449f6b..ca29e7e8398 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 @@ -1094,12 +1094,12 @@ get_src_float(struct ntv_context *ctx, nir_src *src) static void emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) { - assert(tex->op == nir_texop_tex); + assert(tex->op == nir_texop_tex || + tex->op == nir_texop_txb); assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float); assert(tex->texture_index == tex->sampler_index); - bool has_proj = false, has_lod = false; - SpvId coord = 0, proj, lod; + SpvId coord = 0, proj = 0, bias = 0, lod = 0; unsigned coord_components; for (unsigned i = 0; i < tex->num_srcs; i++) { switch (tex->src[i].src_type) { @@ -1109,15 +1109,21 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) break; case nir_tex_src_projector: - has_proj = true; - proj = get_src_float(ctx, &tex->src[i].src); assert(nir_src_num_components(tex->src[i].src) == 1); + proj = get_src_float(ctx, &tex->src[i].src); + assert(proj != 0); + break; + + case nir_tex_src_bias: + assert(tex->op == nir_texop_txb); + bias = get_src_float(ctx, &tex->src[i].src); + assert(bias != 0); 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); + lod = get_src_float(ctx, &tex->src[i].src); + assert(lod != 0); break; default: @@ -1126,9 +1132,9 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) } } - if (!has_lod && ctx->stage != MESA_SHADER_FRAGMENT) { - has_lod = true; + if (lod == 0 && ctx->stage != MESA_SHADER_FRAGMENT) { lod = spirv_builder_const_float(&ctx->builder, 32, 0); + assert(lod != 0); } bool is_ms; @@ -1146,8 +1152,7 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) SpvId dest_type = get_dest_type(ctx, &tex->dest, tex->dest_type); - SpvId result; - if (has_proj) { + if (proj) { SpvId constituents[coord_components + 1]; SpvId float_type = spirv_builder_type_float(&ctx->builder, 32); for (uint32_t i = 0; i < coord_components; ++i) @@ -1159,34 +1164,17 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) constituents[coord_components++] = proj; SpvId vec_type = get_fvec_type(ctx, 32, coord_components); - SpvId merged = spirv_builder_emit_composite_construct(&ctx->builder, + coord = spirv_builder_emit_composite_construct(&ctx->builder, vec_type, constituents, coord_components); - - 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); } + + SpvId result = spirv_builder_emit_image_sample(&ctx->builder, + dest_type, load, + coord, + proj != 0, + lod, bias); 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 b5aa3d9e61b..1b3718307f9 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -506,72 +506,48 @@ spirv_builder_emit_kill(struct spirv_builder *b) } SpvId -spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b, - SpvId result_type, - SpvId sampled_image, - SpvId coordinate) +spirv_builder_emit_image_sample(struct spirv_builder *b, + SpvId result_type, + SpvId sampled_image, + SpvId coordinate, + bool proj, + SpvId lod, + SpvId bias) { SpvId result = spirv_builder_new_id(b); - spirv_buffer_prepare(&b->instructions, 5); - spirv_buffer_emit_word(&b->instructions, SpvOpImageSampleImplicitLod | (5 << 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); - 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; -} + int opcode = SpvOpImageSampleImplicitLod; + if (proj) + opcode += SpvOpImageSampleProjImplicitLod - SpvOpImageSampleImplicitLod; + if (lod) + opcode += SpvOpImageSampleExplicitLod - SpvOpImageSampleImplicitLod; + + SpvImageOperandsMask operand_mask = 0; + SpvId extra_operands[3]; + int num_extra_operands = SpvImageOperandsMaskNone; + if (bias) { + extra_operands[++num_extra_operands] = bias; + operand_mask |= SpvImageOperandsBiasMask; + } + if (lod) { + extra_operands[++num_extra_operands] = lod; + operand_mask |= SpvImageOperandsLodMask; + } -SpvId -spirv_builder_emit_image_sample_proj_implicit_lod(struct spirv_builder *b, - SpvId result_type, - SpvId sampled_image, - SpvId coordinate) -{ - SpvId result = spirv_builder_new_id(b); - spirv_buffer_prepare(&b->instructions, 5); - spirv_buffer_emit_word(&b->instructions, SpvOpImageSampleProjImplicitLod | (5 << 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); - return result; -} + /* finalize num_extra_operands / extra_operands */ + if (num_extra_operands > 0) { + extra_operands[0] = operand_mask; + num_extra_operands++; + } -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, SpvOpImageSampleProjExplicitLod | (7 << 16)); + spirv_buffer_prepare(&b->instructions, 5 + num_extra_operands); + spirv_buffer_emit_word(&b->instructions, opcode | ((5 + num_extra_operands) << 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); + for (int i = 0; i < num_extra_operands; ++i) + spirv_buffer_emit_word(&b->instructions, extra_operands[i]); return result; } 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 461f5ad3d12..0bb16b16dd3 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -204,31 +204,15 @@ spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position, void spirv_builder_emit_kill(struct spirv_builder *b); -SpvId -spirv_builder_emit_image_sample_implicit_lod(struct spirv_builder *b, - SpvId result_type, - 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); +spirv_builder_emit_image_sample(struct spirv_builder *b, + SpvId result_type, + SpvId sampled_image, + SpvId coordinate, + bool proj, + SpvId lod, + SpvId bias); SpvId spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type, -- 2.30.2