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 ffce5df6bc9..30eafa6b833 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 @@ -2171,7 +2171,7 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) assert(tex->texture_index == tex->sampler_index); SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0, - const_offset = 0, sample = 0, tex_offset = 0; + const_offset = 0, offset = 0, sample = 0, tex_offset = 0; unsigned coord_components = 0; for (unsigned i = 0; i < tex->num_srcs; i++) { switch (tex->src[i].src_type) { @@ -2191,8 +2191,10 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) break; case nir_tex_src_offset: - assert(nir_src_is_const(tex->src[i].src)); - const_offset = get_src_int(ctx, &tex->src[i].src); + if (nir_src_is_const(tex->src[i].src)) + const_offset = get_src_int(ctx, &tex->src[i].src); + else + offset = get_src_int(ctx, &tex->src[i].src); break; case nir_tex_src_bias: @@ -2329,6 +2331,8 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) actual_dest_type = spirv_builder_type_float(&ctx->builder, 32); SpvId result; + if (offset) + spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended); if (tex->op == nir_texop_txf || tex->op == nir_texop_txf_ms || tex->op == nir_texop_tg4) { @@ -2339,17 +2343,17 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended); result = spirv_builder_emit_image_gather(&ctx->builder, dest_type, load, coord, emit_uint_const(ctx, 32, tex->component), - lod, sample, const_offset, dref); + lod, sample, const_offset, offset, dref); } else result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type, - image, coord, lod, sample, const_offset); + image, coord, lod, sample, const_offset, offset); } else { result = spirv_builder_emit_image_sample(&ctx->builder, actual_dest_type, load, coord, proj != 0, lod, bias, dref, dx, dy, - const_offset); + const_offset, offset); } spirv_builder_emit_decoration(&ctx->builder, result, 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 47ea144cb1c..a413c551d06 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -669,7 +669,8 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, SpvId dref, SpvId dx, SpvId dy, - SpvId const_offset) + SpvId const_offset, + SpvId offset) { SpvId result = spirv_builder_new_id(b); @@ -699,9 +700,13 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, extra_operands[++num_extra_operands] = dy; operand_mask |= SpvImageOperandsGradMask; } + assert(!(const_offset && offset)); if (const_offset) { extra_operands[++num_extra_operands] = const_offset; operand_mask |= SpvImageOperandsConstOffsetMask; + } else if (offset) { + extra_operands[++num_extra_operands] = offset; + operand_mask |= SpvImageOperandsOffsetMask; } /* finalize num_extra_operands / extra_operands */ @@ -745,6 +750,7 @@ spirv_builder_emit_image_gather(struct spirv_builder *b, SpvId lod, SpvId sample, SpvId const_offset, + SpvId offset, SpvId dref) { SpvId result = spirv_builder_new_id(b); @@ -761,9 +767,13 @@ spirv_builder_emit_image_gather(struct spirv_builder *b, extra_operands[++num_extra_operands] = sample; operand_mask |= SpvImageOperandsSampleMask; } + assert(!(const_offset && offset)); if (const_offset) { extra_operands[++num_extra_operands] = const_offset; operand_mask |= SpvImageOperandsConstOffsetMask; + } else if (offset) { + extra_operands[++num_extra_operands] = offset; + operand_mask |= SpvImageOperandsOffsetMask; } if (dref) op = SpvOpImageDrefGather; @@ -796,7 +806,8 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b, SpvId coordinate, SpvId lod, SpvId sample, - SpvId const_offset) + SpvId const_offset, + SpvId offset) { SpvId result = spirv_builder_new_id(b); @@ -811,9 +822,13 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b, extra_operands[++num_extra_operands] = sample; operand_mask |= SpvImageOperandsSampleMask; } + assert(!(const_offset && offset)); if (const_offset) { extra_operands[++num_extra_operands] = const_offset; operand_mask |= SpvImageOperandsConstOffsetMask; + } else if (offset) { + extra_operands[++num_extra_operands] = offset; + operand_mask |= SpvImageOperandsOffsetMask; } /* finalize num_extra_operands / extra_operands */ 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 f3c8d5b4eb1..632f196733f 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -256,6 +256,7 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, SpvId dref, SpvId dx, SpvId dy, + SpvId const_offset, SpvId offset); SpvId @@ -269,6 +270,7 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b, SpvId coordinate, SpvId lod, SpvId sample, + SpvId const_offset, SpvId offset); SpvId spirv_builder_emit_image_gather(struct spirv_builder *b, @@ -278,6 +280,7 @@ spirv_builder_emit_image_gather(struct spirv_builder *b, SpvId component, SpvId lod, SpvId sample, + SpvId const_offset, SpvId offset, SpvId dref);