diff options
author | Anuj Phogat <[email protected]> | 2014-01-29 17:31:04 -0800 |
---|---|---|
committer | Carl Worth <[email protected]> | 2014-01-31 13:01:34 -0800 |
commit | 765e3d373b3308a411abcec78650163be5703525 (patch) | |
tree | e3535ae017dea9ad901466a44d8e25057e0d62e5 /src/mesa/drivers/dri | |
parent | ae286af09da8a4e5b09997907e6f7a4f9ed538a5 (diff) |
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'.
Signed-off-by: Anuj Phogat <[email protected]>
Reviewed-by: Chris Forbes <[email protected]>
(cherry picked from commit a92e5f7cf63d496ad7830b5cea4bbab287c25b8e)
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.h | 1 |
4 files changed, 29 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 25731fbd825..a006740224e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1008,7 +1008,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) { @@ -1017,6 +1017,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; @@ -1094,7 +1099,9 @@ 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->centroid); + ir->centroid, + c->key.persample_shading); + if (brw->needs_unlit_centroid_workaround && ir->centroid) { /* Get the pixel/sample mask into f0 so that we know * which pixels are lit. Then, for each channel that is @@ -1103,7 +1110,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; } diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 529bd3a558a..43fcde395ba 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -338,7 +338,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); diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index bc1480c3a96..464e826ec71 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -48,6 +48,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; @@ -61,6 +62,7 @@ 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 = persample_shading; bool is_gl_Color = attr == VARYING_SLOT_COL0 || attr == VARYING_SLOT_COL1; /* Ignore unused inputs. */ @@ -81,8 +83,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; } @@ -92,8 +98,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; } @@ -170,6 +180,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); @@ -490,6 +501,9 @@ static void brw_wm_populate_key( struct brw_context *brw, (ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled); /* _NEW_BUFFERS _NEW_MULTISAMPLE */ + key->persample_shading = + _mesa_get_min_invocations_per_fragment(ctx, &fp->program) > 1; + key->compute_pos_offset = _mesa_get_min_invocations_per_fragment(ctx, &fp->program) > 1 && fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_POS; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index df5fb4caaf5..13a60908a41 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -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; |