diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 28 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 3 |
3 files changed, 33 insertions, 1 deletions
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; } } |