From af65bfb38fa56bf6a28dd4b681ca123b9c05a827 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 17 Dec 2019 21:17:09 +0100 Subject: [PATCH] zink: implement nir_texop_txd This lets us enable PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD, which in turns gives us ARB_shader_texture_lod. Still fails one piglit test on ANV, namely spec@arb_shader_texture_lod@execution@arb_shader_texture_lod-texgradcube, but with 33 new passing tests, I think this is worth it. Reviewed-by: Dave Airlie Tested-by: Marge Bot Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 17 ++++++++++++++--- .../drivers/zink/nir_to_spirv/spirv_builder.c | 12 +++++++++--- .../drivers/zink/nir_to_spirv/spirv_builder.h | 4 +++- src/gallium/drivers/zink/zink_screen.c | 4 ---- 4 files changed, 26 insertions(+), 11 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 36e6fa0f1fe..e11882348cb 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 @@ -1324,11 +1324,12 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) { assert(tex->op == nir_texop_tex || tex->op == nir_texop_txb || - tex->op == nir_texop_txl); + tex->op == nir_texop_txl || + tex->op == nir_texop_txd); assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float); assert(tex->texture_index == tex->sampler_index); - SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0; + SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0; unsigned coord_components = 0; for (unsigned i = 0; i < tex->num_srcs; i++) { switch (tex->src[i].src_type) { @@ -1361,6 +1362,16 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) assert(dref != 0); break; + case nir_tex_src_ddx: + dx = get_src_float(ctx, &tex->src[i].src); + assert(dx != 0); + break; + + case nir_tex_src_ddy: + dy = get_src_float(ctx, &tex->src[i].src); + assert(dy != 0); + break; + default: fprintf(stderr, "texture source: %d\n", tex->src[i].src_type); unreachable("unknown texture source"); @@ -1418,7 +1429,7 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex) actual_dest_type, load, coord, proj != 0, - lod, bias, dref); + lod, bias, dref, dx, dy); 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 32d5283c217..275f81eb4fb 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -513,7 +513,9 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, bool proj, SpvId lod, SpvId bias, - SpvId dref) + SpvId dref, + SpvId dx, + SpvId dy) { SpvId result = spirv_builder_new_id(b); @@ -521,7 +523,7 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, int operands = 5; if (proj) opcode += SpvOpImageSampleProjImplicitLod - SpvOpImageSampleImplicitLod; - if (lod) + if (lod || (dx && dy)) opcode += SpvOpImageSampleExplicitLod - SpvOpImageSampleImplicitLod; if (dref) { opcode += SpvOpImageSampleDrefImplicitLod - SpvOpImageSampleImplicitLod; @@ -529,7 +531,7 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, } SpvImageOperandsMask operand_mask = 0; - SpvId extra_operands[3]; + SpvId extra_operands[4]; int num_extra_operands = SpvImageOperandsMaskNone; if (bias) { extra_operands[++num_extra_operands] = bias; @@ -538,6 +540,10 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, if (lod) { extra_operands[++num_extra_operands] = lod; operand_mask |= SpvImageOperandsLodMask; + } else if (dx && dy) { + extra_operands[++num_extra_operands] = dx; + extra_operands[++num_extra_operands] = dy; + operand_mask |= SpvImageOperandsGradMask; } /* 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 612e6ec0373..736eb211fc7 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -213,7 +213,9 @@ spirv_builder_emit_image_sample(struct spirv_builder *b, bool proj, SpvId lod, SpvId bias, - SpvId dref); + SpvId dref, + SpvId dx, + SpvId dy); SpvId spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type, diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 81dd65672c9..5441445e1b8 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -122,11 +122,7 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1 + util_logbase2(screen->props.limits.maxImageDimensionCube); case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 1; - case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: - return 0; /* TODO: re-enable after implementing nir_texop_txd */ - case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: case PIPE_CAP_VERTEX_SHADER_SATURATE: return 1; -- 2.30.2