mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 20:10:17 +01:00
i965: Use sample barycentric coordinates with per sample shading
Current implementation of arb_sample_shading doesn't set 'Barycentric
Interpolation Mode' correctly. We use pixel barycentric coordinates
for per sample shading. Instead we should select perspective sample
or non-perspective sample barycentric coordinates.
It also enables using sample barycentric coordinates in case of a
fragment shader variable declared with 'sample' qualifier.
e.g. sample in vec4 pos;
A piglit test to verify the implementation has been posted on piglit
mailing list for review.
V2: Do not interpolate all the 'in' variables at sample position
if fragment shader uses 'sample' qualifier with one of them.
For example we have a fragment shader:
#version 330
#extension ARB_gpu_shader5: require
sample in vec4 a;
in vec4 b;
main()
{
...
}
Only 'a' should be sampled at sample location, not 'b'.
Cc: mesa-stable@lists.freedesktop.org
Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
parent
3313cc269b
commit
a92e5f7cf6
4 changed files with 30 additions and 6 deletions
|
|
@ -998,7 +998,7 @@ fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
|
|||
fs_inst *
|
||||
fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
|
||||
glsl_interp_qualifier interpolation_mode,
|
||||
bool is_centroid)
|
||||
bool is_centroid, bool is_sample)
|
||||
{
|
||||
brw_wm_barycentric_interp_mode barycoord_mode;
|
||||
if (brw->gen >= 6) {
|
||||
|
|
@ -1007,6 +1007,11 @@ fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
|
|||
barycoord_mode = BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
|
||||
else
|
||||
barycoord_mode = BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
|
||||
} else if (is_sample) {
|
||||
if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
|
||||
barycoord_mode = BRW_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC;
|
||||
else
|
||||
barycoord_mode = BRW_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC;
|
||||
} else {
|
||||
if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
|
||||
barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
|
|
@ -1084,7 +1089,8 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
|
|||
*/
|
||||
struct brw_reg interp = interp_reg(location, k);
|
||||
emit_linterp(attr, fs_reg(interp), interpolation_mode,
|
||||
ir->data.centroid);
|
||||
ir->data.centroid,
|
||||
ir->data.sample || c->key.persample_shading);
|
||||
if (brw->needs_unlit_centroid_workaround && ir->data.centroid) {
|
||||
/* Get the pixel/sample mask into f0 so that we know
|
||||
* which pixels are lit. Then, for each channel that is
|
||||
|
|
@ -1093,7 +1099,8 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
|
|||
*/
|
||||
emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
|
||||
fs_inst *inst = emit_linterp(attr, fs_reg(interp),
|
||||
interpolation_mode, false);
|
||||
interpolation_mode,
|
||||
false, false);
|
||||
inst->predicate = BRW_PREDICATE_NORMAL;
|
||||
inst->predicate_inverse = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ public:
|
|||
fs_reg *emit_fragcoord_interpolation(ir_variable *ir);
|
||||
fs_inst *emit_linterp(const fs_reg &attr, const fs_reg &interp,
|
||||
glsl_interp_qualifier interpolation_mode,
|
||||
bool is_centroid);
|
||||
bool is_centroid, bool is_sample);
|
||||
fs_reg *emit_frontfacing_interpolation(ir_variable *ir);
|
||||
fs_reg *emit_samplepos_setup(ir_variable *ir);
|
||||
fs_reg *emit_sampleid_setup(ir_variable *ir);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
static unsigned
|
||||
brw_compute_barycentric_interp_modes(struct brw_context *brw,
|
||||
bool shade_model_flat,
|
||||
bool persample_shading,
|
||||
const struct gl_fragment_program *fprog)
|
||||
{
|
||||
unsigned barycentric_interp_modes = 0;
|
||||
|
|
@ -62,6 +63,8 @@ brw_compute_barycentric_interp_modes(struct brw_context *brw,
|
|||
enum glsl_interp_qualifier interp_qualifier =
|
||||
fprog->InterpQualifier[attr];
|
||||
bool is_centroid = fprog->IsCentroid & BITFIELD64_BIT(attr);
|
||||
bool is_sample = (fprog->IsSample & BITFIELD64_BIT(attr)) ||
|
||||
persample_shading;
|
||||
bool is_gl_Color = attr == VARYING_SLOT_COL0 || attr == VARYING_SLOT_COL1;
|
||||
|
||||
/* Ignore unused inputs. */
|
||||
|
|
@ -82,8 +85,12 @@ brw_compute_barycentric_interp_modes(struct brw_context *brw,
|
|||
if (is_centroid) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
|
||||
} else if (is_sample) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC;
|
||||
}
|
||||
if (!is_centroid || brw->needs_unlit_centroid_workaround) {
|
||||
if ((!is_centroid && !is_sample) ||
|
||||
brw->needs_unlit_centroid_workaround) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
}
|
||||
|
|
@ -93,8 +100,12 @@ brw_compute_barycentric_interp_modes(struct brw_context *brw,
|
|||
if (is_centroid) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
|
||||
} else if (is_sample) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC;
|
||||
}
|
||||
if (!is_centroid || brw->needs_unlit_centroid_workaround) {
|
||||
if ((!is_centroid && !is_sample) ||
|
||||
brw->needs_unlit_centroid_workaround) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
}
|
||||
|
|
@ -171,6 +182,7 @@ bool do_wm_prog(struct brw_context *brw,
|
|||
|
||||
c->prog_data.barycentric_interp_modes =
|
||||
brw_compute_barycentric_interp_modes(brw, c->key.flat_shade,
|
||||
c->key.persample_shading,
|
||||
&fp->program);
|
||||
|
||||
program = brw_wm_fs_emit(brw, c, &fp->program, prog, &program_size);
|
||||
|
|
@ -503,6 +515,10 @@ static void brw_wm_populate_key( struct brw_context *brw,
|
|||
(ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled);
|
||||
|
||||
/* _NEW_BUFFERS _NEW_MULTISAMPLE */
|
||||
/* Ignore sample qualifier while computing this flag. */
|
||||
key->persample_shading =
|
||||
_mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1;
|
||||
|
||||
key->compute_pos_offset =
|
||||
_mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 &&
|
||||
fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_POS;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ struct brw_wm_prog_key {
|
|||
uint8_t iz_lookup;
|
||||
GLuint stats_wm:1;
|
||||
GLuint flat_shade:1;
|
||||
GLuint persample_shading:1;
|
||||
GLuint nr_color_regions:5;
|
||||
GLuint replicate_alpha:1;
|
||||
GLuint render_to_fbo:1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue