aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorErik Faye-Lund <[email protected]>2019-07-12 12:43:20 +0200
committerErik Faye-Lund <[email protected]>2019-10-28 08:51:46 +0000
commita005fae564b2b67f7c93207ac24fb92259231901 (patch)
treed8a5938854a1bca157dc6bdbfd8fa4db0555e096 /src/gallium/drivers
parent44f374ced5a49a196ebef31ebf74c173da475e65 (diff)
zink: support more texturing
Acked-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c58
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c90
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h30
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,