summaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-09-13 15:33:23 +0200
committerNicolai Hähnle <[email protected]>2017-09-18 11:25:18 +0200
commit94736d31c364635a76a11e0bd4f046a42d2221d5 (patch)
tree78061e83a2feff4b0ad80ff436d0e377c116ca0e /src/amd
parent6772452e4c75dd3d6880333fc98fd9035dd42717 (diff)
amd/common: add workaround for cube map array layer clamping
Fixes dEQP-GLES31.functional.texture.filtering.cube_array.* Cc: [email protected] Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/common/ac_llvm_build.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 6c010e8c3a6..8a329515b57 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -498,8 +498,35 @@ ac_prepare_cube_coords(struct ac_llvm_context *ctx,
LLVMValueRef invma;
if (is_array && !is_lod) {
- coords_arg[3] = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32,
- &coords_arg[3], 1, 0);
+ LLVMValueRef tmp = coords_arg[3];
+ tmp = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32, &tmp, 1, 0);
+
+ /* Section 8.9 (Texture Functions) of the GLSL 4.50 spec says:
+ *
+ * "For Array forms, the array layer used will be
+ *
+ * max(0, min(d−1, floor(layer+0.5)))
+ *
+ * where d is the depth of the texture array and layer
+ * comes from the component indicated in the tables below.
+ * Workaroudn for an issue where the layer is taken from a
+ * helper invocation which happens to fall on a different
+ * layer due to extrapolation."
+ *
+ * VI and earlier attempt to implement this in hardware by
+ * clamping the value of coords[2] = (8 * layer) + face.
+ * Unfortunately, this means that the we end up with the wrong
+ * face when clamping occurs.
+ *
+ * Clamp the layer earlier to work around the issue.
+ */
+ if (ctx->chip_class <= VI) {
+ LLVMValueRef ge0;
+ ge0 = LLVMBuildFCmp(builder, LLVMRealOGE, tmp, ctx->f32_0, "");
+ tmp = LLVMBuildSelect(builder, ge0, tmp, ctx->f32_0, "");
+ }
+
+ coords_arg[3] = tmp;
}
build_cube_intrinsic(ctx, coords_arg, &selcoords);