summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965
diff options
context:
space:
mode:
authorAnuj Phogat <[email protected]>2014-01-06 13:59:18 -0800
committerAnuj Phogat <[email protected]>2014-01-21 14:42:27 -0800
commita92e5f7cf63d496ad7830b5cea4bbab287c25b8e (patch)
tree9506d79aea368bac7b5e601379193df257ab80b0 /src/mesa/drivers/dri/i965
parent3313cc269bd428ca96a132d86da5fddc0f27386a (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'. Cc: [email protected] Signed-off-by: Anuj Phogat <[email protected]> Reviewed-by: Chris Forbes <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp13
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c20
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h1
4 files changed, 30 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 78ddf0d99cf..430a530d242 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -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;
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index f493784012b..a9039088a6e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 0a308862c47..a6b558fd6a2 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 211db0bdd2b..14a4b8bb5a6 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;