Module: Mesa
Branch: master
Commit: e4af4433fc802fafcb6050e290c514ff40c8735d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e4af4433fc802fafcb6050e290c514ff40c8735d

Author: Nicolai Hähnle <[email protected]>
Date:   Sun Sep 10 19:46:31 2017 +0200

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]>

---

 src/gallium/drivers/radeonsi/si_shader.c        | 28 ++++++++++++++++++++++++-
 src/gallium/drivers/radeonsi/si_shader.h        |  3 +++
 src/gallium/drivers/radeonsi/si_state_shaders.c |  3 +++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index d151ba4c5c..c4e7f225a8 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,
diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
b/src/gallium/drivers/radeonsi/si_shader.h
index 641f49cbac..f457f8e20b 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -517,6 +517,9 @@ struct si_shader_key {
                        uint64_t        ff_tcs_inputs_to_copy; /* for 
fixed-func TCS */
                        /* When PS needs PrimID and GS is disabled. */
                        unsigned        vs_export_prim_id:1;
+                       struct {
+                               unsigned interpolate_at_sample_force_center:1;
+                       } ps;
                } u;
        } mono;
 
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c 
b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 6d87cab988..bbc6b1d708 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1462,6 +1462,9 @@ static inline void si_shader_selector_key(struct 
pipe_context *ctx,
                                        sel->info.uses_linear_center +
                                        sel->info.uses_linear_centroid +
                                        sel->info.uses_linear_sample > 1;
+
+                               if 
(sel->info.opcode_count[TGSI_OPCODE_INTERP_SAMPLE])
+                                       
key->mono.u.ps.interpolate_at_sample_force_center = 1;
                        }
                }
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to