From 016807161bbedd658ff8a691527078075f6c507a Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 17 Jul 2018 19:04:09 +0200 Subject: [PATCH] r600: Correct evaluation of cube array index and face The array index needs to be corrected and it must be insured that it is rounded and its value is non-negative before it is combined with the face id. v5: Use RNDNE instead of ADD 0.5 and FLOOR (Ilia Mirkin) v6: Fix type (Roland Scheidegger) Fixes 182 from android/cts/master/gles31-master.txt: dEQP-GLES31.functional.texture.filtering.cube_array.formats.* dEQP-GLES31.functional.texture.filtering.cube_array.sizes.* dEQP-GLES31.functional.texture.filtering.cube_array.combinations.nearest_mipmap_* dEQP-GLES31.functional.texture.filtering.cube_array.combinations.linear_mipmap_* dEQP-GLES31.functional.texture.filtering.cube_array.no_edges_visible.* Signed-off-by: Gert Wollny Reviewed-by: Roland Scheidegger --- src/gallium/drivers/r600/r600_shader.c | 34 +++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 15e35f006c1..fce14a12e98 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -7720,11 +7720,43 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) if (r) return r; + /* Evaluate the array index according to floor(idx + 0.5). This + * needs to be done before merging the face select value, because + * otherwise the fractional part of the array index will interfere + * with the face select value */ + memset(&alu, 0, sizeof(struct r600_bytecode_alu)); + r600_bytecode_src(&alu.src[0], &ctx->src[0], 3); + alu.op = ALU_OP1_RNDNE; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.dst.write = 1; + alu.last = 1; + r = r600_bytecode_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* Because the array slice index and the cube face index are merged + * into one value we have to make sure the array slice index is >= 0, + * otherwise the face selection will fail */ + memset(&alu, 0, sizeof(struct r600_bytecode_alu)); + alu.op = ALU_OP2_MAX; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = V_SQ_ALU_SRC_0; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.dst.write = 1; + alu.last = 1; + r = r600_bytecode_add_alu(ctx->bc, &alu); + if (r) + return r; + /* have to multiply original layer by 8 and add to face id (temp.w) in Z */ memset(&alu, 0, sizeof(struct r600_bytecode_alu)); alu.op = ALU_OP3_MULADD; alu.is_op3 = 1; - r600_bytecode_src(&alu.src[0], &ctx->src[0], 3); + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; alu.src[1].chan = 0; alu.src[1].value = u_bitcast_f2u(8.0f); -- 2.30.2