mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
i965/gen6+: Add support for noperspective interpolation.
This required the following changes: - WM setup now makes the appropriate set of barycentric coordinates (perspective vs. noperspective) available to the fragment shader, based on whether the shader requires perspective interpolation, noperspective interpolation, both, or neither. - The fragment shader backend now uses the appropriate set of barycentric coordiantes when interpolating, based on the interpolation mode returned by ir_variable::determine_interpolation_mode(). - SF setup now uses gl_fragment_program::InterpQualifier to determine which attributes are to be flat shaded (as opposed to the old logic, which only flat shaded colors). - CLIP setup now ensures that the clipper outputs non-perspective barycentric coordinates when they are needed by the fragment shader. Fixes the remaining piglit tests of interpolation qualifiers that were failing: - interpolation-flat-*-smooth-none - interpolation-flat-other-flat-none - interpolation-noperspective-* - interpolation-smooth-gl_*Color-flat-* Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
4d563ec1cc
commit
5aa96286e7
9 changed files with 122 additions and 39 deletions
|
|
@ -978,7 +978,12 @@ gl_clip_plane *brw_select_clip_planes(struct gl_context *ctx);
|
|||
|
||||
/* brw_wm.c */
|
||||
unsigned
|
||||
brw_compute_barycentric_interp_modes(void);
|
||||
brw_compute_barycentric_interp_modes(bool shade_model_flat,
|
||||
const struct gl_fragment_program *fprog);
|
||||
|
||||
/* gen6_clip_state.c */
|
||||
bool
|
||||
brw_fprog_uses_noperspective(const struct gl_fragment_program *fprog);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
|
|||
attr.reg_offset++;
|
||||
}
|
||||
} else {
|
||||
/* Perspective interpolation case. */
|
||||
/* Smooth/noperspective interpolation case. */
|
||||
for (unsigned int k = 0; k < type->vector_elements; k++) {
|
||||
/* FINISHME: At some point we probably want to push
|
||||
* this farther by giving similar treatment to the
|
||||
|
|
@ -483,8 +483,11 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
|
|||
emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f));
|
||||
} else {
|
||||
struct brw_reg interp = interp_reg(location, k);
|
||||
brw_wm_barycentric_interp_mode barycoord_mode =
|
||||
BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
brw_wm_barycentric_interp_mode barycoord_mode;
|
||||
if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
|
||||
barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
else
|
||||
barycoord_mode = BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
emit(FS_OPCODE_LINTERP, attr,
|
||||
this->delta_x[barycoord_mode],
|
||||
this->delta_y[barycoord_mode], fs_reg(interp));
|
||||
|
|
|
|||
|
|
@ -129,10 +129,41 @@ brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
|||
* (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
|
||||
*/
|
||||
unsigned
|
||||
brw_compute_barycentric_interp_modes(void)
|
||||
brw_compute_barycentric_interp_modes(bool shade_model_flat,
|
||||
const struct gl_fragment_program *fprog)
|
||||
{
|
||||
/* At the moment the only interpolation mode we support is perspective. */
|
||||
return (1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
|
||||
unsigned barycentric_interp_modes = 0;
|
||||
int attr;
|
||||
|
||||
/* Loop through all fragment shader inputs to figure out what interpolation
|
||||
* modes are in use, and set the appropriate bits in
|
||||
* barycentric_interp_modes.
|
||||
*/
|
||||
for (attr = 0; attr < FRAG_ATTRIB_MAX; ++attr) {
|
||||
enum glsl_interp_qualifier interp_qualifier =
|
||||
fprog->InterpQualifier[attr];
|
||||
bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
|
||||
|
||||
/* Ignore unused inputs. */
|
||||
if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
|
||||
continue;
|
||||
|
||||
/* Ignore WPOS and FACE, because they don't require interpolation. */
|
||||
if (attr == FRAG_ATTRIB_WPOS || attr == FRAG_ATTRIB_FACE)
|
||||
continue;
|
||||
|
||||
if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
} else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
|
||||
(!(shade_model_flat && is_gl_Color) &&
|
||||
interp_qualifier == INTERP_QUALIFIER_NONE)) {
|
||||
barycentric_interp_modes |=
|
||||
1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
|
||||
}
|
||||
}
|
||||
|
||||
return barycentric_interp_modes;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -144,7 +175,8 @@ brw_wm_payload_setup(struct brw_context *brw,
|
|||
bool uses_depth = (c->fp->program.Base.InputsRead &
|
||||
(1 << FRAG_ATTRIB_WPOS)) != 0;
|
||||
unsigned barycentric_interp_modes =
|
||||
brw_compute_barycentric_interp_modes();
|
||||
brw_compute_barycentric_interp_modes(c->key.flat_shade,
|
||||
&c->fp->program);
|
||||
int i;
|
||||
|
||||
if (intel->gen >= 6) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,26 @@
|
|||
#include "brw_util.h"
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
/**
|
||||
* Return true if at least one of the inputs used by the given fragment
|
||||
* program has the GLSL "noperspective" interpolation qualifier.
|
||||
*/
|
||||
bool
|
||||
brw_fprog_uses_noperspective(const struct gl_fragment_program *fprog)
|
||||
{
|
||||
int attr;
|
||||
for (attr = 0; attr < FRAG_ATTRIB_MAX; ++attr) {
|
||||
/* Ignore unused inputs. */
|
||||
if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
|
||||
continue;
|
||||
|
||||
if (fprog->InterpQualifier[attr] == INTERP_QUALIFIER_NOPERSPECTIVE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
upload_clip_state(struct brw_context *brw)
|
||||
{
|
||||
|
|
@ -38,6 +58,14 @@ upload_clip_state(struct brw_context *brw)
|
|||
struct gl_context *ctx = &intel->ctx;
|
||||
uint32_t depth_clamp = 0;
|
||||
uint32_t provoking, userclip;
|
||||
uint32_t nonperspective_barycentric_enable_flag = 0;
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
const struct gl_fragment_program *fprog = brw->fragment_program;
|
||||
|
||||
if (brw_fprog_uses_noperspective(fprog)) {
|
||||
nonperspective_barycentric_enable_flag =
|
||||
GEN6_CLIP_NON_PERSPECTIVE_BARYCENTRIC_ENABLE;
|
||||
}
|
||||
|
||||
if (!ctx->Transform.DepthClamp)
|
||||
depth_clamp = GEN6_CLIP_Z_TEST;
|
||||
|
|
@ -64,6 +92,7 @@ upload_clip_state(struct brw_context *brw)
|
|||
OUT_BATCH(GEN6_CLIP_ENABLE |
|
||||
GEN6_CLIP_API_OGL |
|
||||
GEN6_CLIP_MODE_NORMAL |
|
||||
nonperspective_barycentric_enable_flag |
|
||||
GEN6_CLIP_XY_TEST |
|
||||
userclip << GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT |
|
||||
depth_clamp |
|
||||
|
|
@ -77,7 +106,8 @@ upload_clip_state(struct brw_context *brw)
|
|||
const struct brw_tracked_state gen6_clip_state = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_TRANSFORM | _NEW_LIGHT,
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.brw = (BRW_NEW_CONTEXT |
|
||||
BRW_NEW_FRAGMENT_PROGRAM),
|
||||
.cache = 0
|
||||
},
|
||||
.emit = upload_clip_state,
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ upload_sf_state(struct brw_context *brw)
|
|||
GLbitfield64 vs_outputs_written = brw->vs.prog_data->outputs_written;
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead);
|
||||
/* _NEW_LIGHT */
|
||||
bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT;
|
||||
uint32_t dw1, dw2, dw3, dw4, dw16, dw17;
|
||||
int i;
|
||||
/* _NEW_BUFFER */
|
||||
|
|
@ -263,6 +265,10 @@ upload_sf_state(struct brw_context *brw)
|
|||
* they source from.
|
||||
*/
|
||||
for (; attr < FRAG_ATTRIB_MAX; attr++) {
|
||||
enum glsl_interp_qualifier interp_qualifier =
|
||||
brw->fragment_program->InterpQualifier[attr];
|
||||
bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
|
||||
|
||||
if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)))
|
||||
continue;
|
||||
|
||||
|
|
@ -277,17 +283,10 @@ upload_sf_state(struct brw_context *brw)
|
|||
dw16 |= (1 << input_index);
|
||||
|
||||
/* flat shading */
|
||||
if (ctx->Light.ShadeModel == GL_FLAT) {
|
||||
/*
|
||||
* Setup the Constant Interpolation Enable bit mask for each
|
||||
* corresponding attribute(currently, we only care two attrs:
|
||||
* FRAG_BIT_COL0 and FRAG_BIT_COL1).
|
||||
*
|
||||
* FIXME: should we care other attributes?
|
||||
*/
|
||||
if (attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1)
|
||||
dw17 |= (1 << input_index);
|
||||
}
|
||||
if (interp_qualifier == INTERP_QUALIFIER_FLAT ||
|
||||
(shade_model_flat && is_gl_Color &&
|
||||
interp_qualifier == INTERP_QUALIFIER_NONE))
|
||||
dw17 |= (1 << input_index);
|
||||
|
||||
/* The hardware can only do the overrides on 16 overrides at a
|
||||
* time, and the other up to 16 have to be lined up so that the
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@ upload_wm_state(struct brw_context *brw)
|
|||
brw_fragment_program_const(brw->fragment_program);
|
||||
uint32_t dw2, dw4, dw5, dw6;
|
||||
|
||||
/* _NEW_LIGHT */
|
||||
bool flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
|
||||
|
||||
/* CACHE_NEW_WM_PROG */
|
||||
if (brw->wm.prog_data->nr_params == 0) {
|
||||
/* Disable the push constant buffers. */
|
||||
|
|
@ -168,6 +171,8 @@ upload_wm_state(struct brw_context *brw)
|
|||
dw5 |= GEN6_WM_USES_SOURCE_DEPTH | GEN6_WM_USES_SOURCE_W;
|
||||
if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
|
||||
dw5 |= GEN6_WM_COMPUTED_DEPTH;
|
||||
dw6 |= brw_compute_barycentric_interp_modes(flat_shade, &fp->program) <<
|
||||
GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
|
||||
|
|
@ -178,9 +183,6 @@ upload_wm_state(struct brw_context *brw)
|
|||
dw5 |= GEN6_WM_DISPATCH_ENABLE;
|
||||
}
|
||||
|
||||
dw6 |= brw_compute_barycentric_interp_modes() <<
|
||||
GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
|
||||
|
||||
dw6 |= _mesa_bitcount_64(brw->fragment_program->Base.InputsRead) <<
|
||||
GEN6_WM_NUM_SF_OUTPUTS_SHIFT;
|
||||
|
||||
|
|
@ -206,6 +208,7 @@ upload_wm_state(struct brw_context *brw)
|
|||
const struct brw_tracked_state gen6_wm_state = {
|
||||
.dirty = {
|
||||
.mesa = (_NEW_LINE |
|
||||
_NEW_LIGHT |
|
||||
_NEW_COLOR |
|
||||
_NEW_BUFFERS |
|
||||
_NEW_PROGRAM_CONSTANTS |
|
||||
|
|
|
|||
|
|
@ -35,10 +35,18 @@ upload_clip_state(struct brw_context *brw)
|
|||
uint32_t depth_clamp = 0;
|
||||
uint32_t provoking, userclip;
|
||||
uint32_t dw1 = GEN6_CLIP_STATISTICS_ENABLE;
|
||||
uint32_t nonperspective_barycentric_enable_flag = 0;
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
const struct gl_fragment_program *fprog = brw->fragment_program;
|
||||
|
||||
/* _NEW_BUFFERS */
|
||||
bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
|
||||
|
||||
if (brw_fprog_uses_noperspective(fprog)) {
|
||||
nonperspective_barycentric_enable_flag =
|
||||
GEN6_CLIP_NON_PERSPECTIVE_BARYCENTRIC_ENABLE;
|
||||
}
|
||||
|
||||
dw1 |= GEN7_CLIP_EARLY_CULL;
|
||||
|
||||
/* _NEW_POLYGON */
|
||||
|
|
@ -90,6 +98,7 @@ upload_clip_state(struct brw_context *brw)
|
|||
OUT_BATCH(GEN6_CLIP_ENABLE |
|
||||
GEN6_CLIP_API_OGL |
|
||||
GEN6_CLIP_MODE_NORMAL |
|
||||
nonperspective_barycentric_enable_flag |
|
||||
GEN6_CLIP_XY_TEST |
|
||||
userclip << GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT |
|
||||
depth_clamp |
|
||||
|
|
@ -106,7 +115,8 @@ const struct brw_tracked_state gen7_clip_state = {
|
|||
_NEW_POLYGON |
|
||||
_NEW_LIGHT |
|
||||
_NEW_TRANSFORM),
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.brw = (BRW_NEW_CONTEXT |
|
||||
BRW_NEW_FRAGMENT_PROGRAM),
|
||||
.cache = 0
|
||||
},
|
||||
.emit = upload_clip_state,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ upload_sbe_state(struct brw_context *brw)
|
|||
GLbitfield64 vs_outputs_written = brw->vs.prog_data->outputs_written;
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead);
|
||||
/* _NEW_LIGHT */
|
||||
bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT;
|
||||
uint32_t dw1, dw10, dw11;
|
||||
int i;
|
||||
int attr = 0, input_index = 0;
|
||||
|
|
@ -74,6 +76,10 @@ upload_sbe_state(struct brw_context *brw)
|
|||
* they source from.
|
||||
*/
|
||||
for (; attr < FRAG_ATTRIB_MAX; attr++) {
|
||||
enum glsl_interp_qualifier interp_qualifier =
|
||||
brw->fragment_program->InterpQualifier[attr];
|
||||
bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
|
||||
|
||||
if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)))
|
||||
continue;
|
||||
|
||||
|
|
@ -87,17 +93,10 @@ upload_sbe_state(struct brw_context *brw)
|
|||
dw10 |= (1 << input_index);
|
||||
|
||||
/* flat shading */
|
||||
if (ctx->Light.ShadeModel == GL_FLAT) {
|
||||
/*
|
||||
* Setup the Constant Interpolation Enable bit mask for each
|
||||
* corresponding attribute(currently, we only care two attrs:
|
||||
* FRAG_BIT_COL0 and FRAG_BIT_COL1).
|
||||
*
|
||||
* FIXME: should we care other attributes?
|
||||
*/
|
||||
if (attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1)
|
||||
dw11 |= (1 << input_index);
|
||||
}
|
||||
if (interp_qualifier == INTERP_QUALIFIER_FLAT ||
|
||||
(shade_model_flat && is_gl_Color &&
|
||||
interp_qualifier == INTERP_QUALIFIER_NONE))
|
||||
dw11 |= (1 << input_index);
|
||||
|
||||
/* The hardware can only do the overrides on 16 overrides at a
|
||||
* time, and the other up to 16 have to be lined up so that the
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ upload_wm_state(struct brw_context *brw)
|
|||
bool writes_depth = false;
|
||||
uint32_t dw1;
|
||||
|
||||
/* _NEW_LIGHT */
|
||||
bool flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
|
||||
|
||||
dw1 = 0;
|
||||
dw1 |= GEN7_WM_STATISTICS_ENABLE;
|
||||
dw1 |= GEN7_WM_LINE_AA_WIDTH_1_0;
|
||||
|
|
@ -61,6 +64,8 @@ upload_wm_state(struct brw_context *brw)
|
|||
writes_depth = true;
|
||||
dw1 |= GEN7_WM_PSCDEPTH_ON;
|
||||
}
|
||||
dw1 |= brw_compute_barycentric_interp_modes(flat_shade, &fp->program) <<
|
||||
GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
|
||||
|
|
@ -72,9 +77,6 @@ upload_wm_state(struct brw_context *brw)
|
|||
dw1 |= GEN7_WM_DISPATCH_ENABLE;
|
||||
}
|
||||
|
||||
dw1 |= brw_compute_barycentric_interp_modes() <<
|
||||
GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
|
||||
|
||||
BEGIN_BATCH(3);
|
||||
OUT_BATCH(_3DSTATE_WM << 16 | (3 - 2));
|
||||
OUT_BATCH(dw1);
|
||||
|
|
@ -84,7 +86,7 @@ upload_wm_state(struct brw_context *brw)
|
|||
|
||||
const struct brw_tracked_state gen7_wm_state = {
|
||||
.dirty = {
|
||||
.mesa = (_NEW_LINE | _NEW_POLYGON |
|
||||
.mesa = (_NEW_LINE | _NEW_LIGHT | _NEW_POLYGON |
|
||||
_NEW_COLOR | _NEW_BUFFERS),
|
||||
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
|
||||
BRW_NEW_URB_FENCE |
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue