summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_shader.c
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-09-10 19:46:31 +0200
committerNicolai Hähnle <[email protected]>2017-09-13 18:25:45 +0200
commite4af4433fc802fafcb6050e290c514ff40c8735d (patch)
tree8208f4f8058d1aa18048f22fb8decdc326f73415 /src/gallium/drivers/radeonsi/si_shader.c
parent92c4277990799641d4986ce66a62366228713945 (diff)
radeonsi: hard-code pixel center for interpolateAtSample without multisample buffers
The GLSL rules for interpolateAtSample are unfortunate: "Returns the value of the input interpolant variable at the location of sample number sample. If multisample buffers are not available, the input variable will be evaluated at the center of the pixel. If sample sample does not exist, the position used to interpolate the input variable is undefined." This fix will fallback to monolithic shader compilation when interpolateAtSample is used without multisampling. One alternative would be to always upload 16 sample positions, filling the buffer up with repetition when the actual number of samples is less, and then ANDing the sample ID with 0xf. However, that punishes all well-behaving users of interpolateAtSample, when in reality, only conformance tests should be affected by the issue. Fixes dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.* Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_shader.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index d151ba4c5c4..c4e7f225a8f 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3711,7 +3711,33 @@ static void interp_fetch_args(
emit_data->inst, 1, TGSI_CHAN_X);
sample_id = LLVMBuildBitCast(gallivm->builder, sample_id,
ctx->i32, "");
- sample_position = load_sample_position(ctx, sample_id);
+
+ /* Section 8.13.2 (Interpolation Functions) of the OpenGL Shading
+ * Language 4.50 spec says about interpolateAtSample:
+ *
+ * "Returns the value of the input interpolant variable at
+ * the location of sample number sample. If multisample
+ * buffers are not available, the input variable will be
+ * evaluated at the center of the pixel. If sample sample
+ * does not exist, the position used to interpolate the
+ * input variable is undefined."
+ *
+ * This means that sample_id values outside of the valid are
+ * in fact valid input, and the usual mechanism for loading the
+ * sample position doesn't work.
+ */
+ if (ctx->shader->key.mono.u.ps.interpolate_at_sample_force_center) {
+ LLVMValueRef center[4] = {
+ LLVMConstReal(ctx->f32, 0.5),
+ LLVMConstReal(ctx->f32, 0.5),
+ ctx->ac.f32_0,
+ ctx->ac.f32_0,
+ };
+
+ sample_position = lp_build_gather_values(gallivm, center, 4);
+ } else {
+ sample_position = load_sample_position(ctx, sample_id);
+ }
emit_data->args[0] = LLVMBuildExtractElement(gallivm->builder,
sample_position,