i965: Convert CC state on gen4-5 to genxml.

Use set_blend_entry_bits and set_depth_stencil_bits to fill most of the
color calc struct, and then manually update the rest.

v2:
   - Always check for depth_irb (Ken)
   - Always set Backface Stencil Ref (Ken)
   - Always set alpha reference value (Ken)

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Rafael Antognolli
2017-06-01 12:28:41 -07:00
parent b0052aa46f
commit 5d48710981
5 changed files with 68 additions and 284 deletions

View File

@@ -39,180 +39,6 @@
#include "main/stencil.h"
#include "intel_batchbuffer.h"
/**
* Modify blend function to force destination alpha to 1.0
*
* If \c function specifies a blend function that uses destination alpha,
* replace it with a function that hard-wires destination alpha to 1.0. This
* is used when rendering to xRGB targets.
*/
GLenum
brw_fix_xRGB_alpha(GLenum function)
{
switch (function) {
case GL_DST_ALPHA:
return GL_ONE;
case GL_ONE_MINUS_DST_ALPHA:
case GL_SRC_ALPHA_SATURATE:
return GL_ZERO;
}
return function;
}
/**
* Creates a CC unit packet from the current blend state.
*/
static void upload_cc_unit(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
struct brw_cc_unit_state *cc;
cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset);
memset(cc, 0, sizeof(*cc));
/* _NEW_STENCIL | _NEW_BUFFERS */
if (brw->stencil_enabled) {
const unsigned back = ctx->Stencil._BackFace;
cc->cc0.stencil_enable = 1;
cc->cc0.stencil_func =
intel_translate_compare_func(ctx->Stencil.Function[0]);
cc->cc0.stencil_fail_op =
intel_translate_stencil_op(ctx->Stencil.FailFunc[0]);
cc->cc0.stencil_pass_depth_fail_op =
intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]);
cc->cc0.stencil_pass_depth_pass_op =
intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]);
cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0];
cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0];
if (brw->stencil_two_sided) {
cc->cc0.bf_stencil_enable = 1;
cc->cc0.bf_stencil_func =
intel_translate_compare_func(ctx->Stencil.Function[back]);
cc->cc0.bf_stencil_fail_op =
intel_translate_stencil_op(ctx->Stencil.FailFunc[back]);
cc->cc0.bf_stencil_pass_depth_fail_op =
intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]);
cc->cc0.bf_stencil_pass_depth_pass_op =
intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]);
cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back);
cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back];
cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back];
}
/* Not really sure about this:
*/
if (ctx->Stencil.WriteMask[0] ||
(brw->stencil_two_sided && ctx->Stencil.WriteMask[back]))
cc->cc0.stencil_write_enable = 1;
}
/* _NEW_COLOR */
if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) {
cc->cc2.logicop_enable = 1;
cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
} else if (ctx->Color.BlendEnabled && !ctx->Color._AdvancedBlendMode) {
GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
GLenum eqA = ctx->Color.Blend[0].EquationA;
GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
GLenum srcA = ctx->Color.Blend[0].SrcA;
GLenum dstA = ctx->Color.Blend[0].DstA;
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
srcRGB = dstRGB = GL_ONE;
}
if (eqA == GL_MIN || eqA == GL_MAX) {
srcA = dstA = GL_ONE;
}
/* If the renderbuffer is XRGB, we have to frob the blend function to
* force the destination alpha to 1.0. This means replacing GL_DST_ALPHA
* with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
*/
const struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat,
GL_TEXTURE_ALPHA_TYPE)) {
srcRGB = brw_fix_xRGB_alpha(srcRGB);
srcA = brw_fix_xRGB_alpha(srcA);
dstRGB = brw_fix_xRGB_alpha(dstRGB);
dstA = brw_fix_xRGB_alpha(dstA);
}
cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
cc->cc6.blend_function = brw_translate_blend_equation(eqRGB);
cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA);
cc->cc3.blend_enable = 1;
cc->cc3.ia_blend_enable = (srcA != srcRGB ||
dstA != dstRGB ||
eqA != eqRGB);
}
/* _NEW_BUFFERS */
if (ctx->Color.AlphaEnabled && ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
cc->cc3.alpha_test = 1;
cc->cc3.alpha_test_func =
intel_translate_compare_func(ctx->Color.AlphaFunc);
cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef);
}
if (ctx->Color.DitherFlag) {
cc->cc5.dither_enable = 1;
cc->cc6.y_dither_offset = 0;
cc->cc6.x_dither_offset = 0;
}
/* _NEW_DEPTH */
if (ctx->Depth.Test) {
cc->cc2.depth_test = 1;
cc->cc2.depth_test_function =
intel_translate_compare_func(ctx->Depth.Func);
cc->cc2.depth_write_enable = brw_depth_writes_enabled(brw);
}
if (brw->stats_wm)
cc->cc5.statistics_enable = 1;
/* BRW_NEW_CC_VP */
cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset64 +
brw->cc.vp_offset) >> 5; /* reloc */
brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
/* Emit CC viewport relocation */
brw_emit_reloc(&brw->batch,
(brw->cc.state_offset +
offsetof(struct brw_cc_unit_state, cc4)),
brw->batch.bo, brw->cc.vp_offset,
I915_GEM_DOMAIN_INSTRUCTION, 0);
}
const struct brw_tracked_state brw_cc_unit = {
.dirty = {
.mesa = _NEW_BUFFERS |
_NEW_COLOR |
_NEW_DEPTH |
_NEW_STENCIL,
.brw = BRW_NEW_BATCH |
BRW_NEW_BLORP |
BRW_NEW_CC_VP |
BRW_NEW_STATS_WM,
},
.emit = upload_cc_unit,
};
static void upload_blend_constant_color(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;

View File

@@ -42,7 +42,6 @@ extern "C" {
enum intel_msaa_layout;
extern const struct brw_tracked_state brw_blend_constant_color;
extern const struct brw_tracked_state brw_cc_unit;
extern const struct brw_tracked_state brw_clip_unit;
extern const struct brw_tracked_state brw_vs_pull_constants;
extern const struct brw_tracked_state brw_tcs_pull_constants;

View File

@@ -180,98 +180,6 @@ struct brw_clip_unit_state
float viewport_ymax;
};
struct brw_cc_unit_state
{
struct
{
unsigned pad0:3;
unsigned bf_stencil_pass_depth_pass_op:3;
unsigned bf_stencil_pass_depth_fail_op:3;
unsigned bf_stencil_fail_op:3;
unsigned bf_stencil_func:3;
unsigned bf_stencil_enable:1;
unsigned pad1:2;
unsigned stencil_write_enable:1;
unsigned stencil_pass_depth_pass_op:3;
unsigned stencil_pass_depth_fail_op:3;
unsigned stencil_fail_op:3;
unsigned stencil_func:3;
unsigned stencil_enable:1;
} cc0;
struct
{
unsigned bf_stencil_ref:8;
unsigned stencil_write_mask:8;
unsigned stencil_test_mask:8;
unsigned stencil_ref:8;
} cc1;
struct
{
unsigned logicop_enable:1;
unsigned pad0:10;
unsigned depth_write_enable:1;
unsigned depth_test_function:3;
unsigned depth_test:1;
unsigned bf_stencil_write_mask:8;
unsigned bf_stencil_test_mask:8;
} cc2;
struct
{
unsigned pad0:8;
unsigned alpha_test_func:3;
unsigned alpha_test:1;
unsigned blend_enable:1;
unsigned ia_blend_enable:1;
unsigned pad1:1;
unsigned alpha_test_format:1;
unsigned pad2:16;
} cc3;
struct
{
unsigned pad0:5;
unsigned cc_viewport_state_offset:27; /* Offset from GENERAL_STATE_BASE */
} cc4;
struct
{
unsigned pad0:2;
unsigned ia_dest_blend_factor:5;
unsigned ia_src_blend_factor:5;
unsigned ia_blend_function:3;
unsigned statistics_enable:1;
unsigned logicop_func:4;
unsigned pad1:11;
unsigned dither_enable:1;
} cc5;
struct
{
unsigned clamp_post_alpha_blend:1;
unsigned clamp_pre_alpha_blend:1;
unsigned clamp_range:2;
unsigned pad0:11;
unsigned y_dither_offset:2;
unsigned x_dither_offset:2;
unsigned dest_blend_factor:5;
unsigned src_blend_factor:5;
unsigned blend_function:3;
} cc6;
struct {
union {
float f;
uint8_t ub[4];
} alpha_ref;
} cc7;
};
struct brw_gs_unit_state
{
struct thread0 thread0;

View File

@@ -38,7 +38,6 @@
extern GLuint brw_translate_blend_factor( GLenum factor );
extern GLuint brw_translate_blend_equation( GLenum mode );
extern GLenum brw_fix_xRGB_alpha(GLenum function);
static inline float
brw_get_line_width(struct brw_context *brw)

View File

@@ -1217,7 +1217,7 @@ set_depth_stencil_bits(struct brw_context *brw, DEPTH_STENCIL_GENXML *ds)
intel_translate_stencil_op(stencil->ZFailFunc[b]);
}
#if GEN_GEN >= 9
#if GEN_GEN <= 5 || GEN_GEN >= 9
ds->StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
ds->BackfaceStencilReferenceValue = _mesa_get_stencil_ref(ctx, b);
#endif
@@ -2530,6 +2530,28 @@ fix_dual_blend_alpha_to_one(GLenum function)
#define blend_factor(x) brw_translate_blend_factor(x)
#define blend_eqn(x) brw_translate_blend_equation(x)
/**
* Modify blend function to force destination alpha to 1.0
*
* If \c function specifies a blend function that uses destination alpha,
* replace it with a function that hard-wires destination alpha to 1.0. This
* is used when rendering to xRGB targets.
*/
static GLenum
brw_fix_xRGB_alpha(GLenum function)
{
switch (function) {
case GL_DST_ALPHA:
return GL_ONE;
case GL_ONE_MINUS_DST_ALPHA:
case GL_SRC_ALPHA_SATURATE:
return GL_ZERO;
}
return function;
}
#if GEN_GEN >= 6
typedef struct GENX(BLEND_STATE_ENTRY) BLEND_ENTRY_GENXML;
#else
@@ -2555,6 +2577,9 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
*/
const bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
const unsigned blend_enabled = GEN_GEN >= 6 ?
ctx->Color.BlendEnabled & (1 << i) : ctx->Color.BlendEnabled;
/* _NEW_COLOR */
if (ctx->Color.ColorLogicOpEnabled) {
GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
@@ -2570,8 +2595,8 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
entry->LogicOpFunction =
intel_translate_logic_op(ctx->Color.LogicOp);
}
} else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
!ctx->Color._AdvancedBlendMode) {
} else if (blend_enabled && !ctx->Color._AdvancedBlendMode
&& (GEN_GEN <= 5 || !integer)) {
GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
GLenum eqA = ctx->Color.Blend[i].EquationA;
GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
@@ -2997,53 +3022,80 @@ static const struct brw_tracked_state genX(multisample_state) = {
/* ---------------------------------------------------------------------- */
#if GEN_GEN >= 6
static void
genX(upload_color_calc_state)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
brw_state_emit(brw, GENX(COLOR_CALC_STATE), 64, &brw->cc.state_offset, cc) {
#if GEN_GEN <= 5
cc.IndependentAlphaBlendEnable =
set_blend_entry_bits(brw, &cc, 0, false);
set_depth_stencil_bits(brw, &cc);
if (ctx->Color.AlphaEnabled &&
ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
cc.AlphaTestEnable = true;
cc.AlphaTestFunction =
intel_translate_compare_func(ctx->Color.AlphaFunc);
}
cc.ColorDitherEnable = ctx->Color.DitherFlag;
cc.StatisticsEnable = brw->stats_wm;
cc.CCViewportStatePointer =
instruction_ro_bo(brw->batch.bo, brw->cc.vp_offset);
#else
/* _NEW_COLOR */
cc.AlphaTestFormat = ALPHATEST_UNORM8;
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
ctx->Color.AlphaRef);
cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
#if GEN_GEN < 9
/* _NEW_STENCIL */
cc.StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
cc.BackfaceStencilReferenceValue =
_mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
#endif
#endif
/* _NEW_COLOR */
cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
ctx->Color.AlphaRef);
}
#if GEN_GEN >= 6
brw_batch_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), ptr) {
ptr.ColorCalcStatePointer = brw->cc.state_offset;
#if GEN_GEN != 7
ptr.ColorCalcStatePointerValid = true;
#endif
}
#else
brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
#endif
}
static const struct brw_tracked_state genX(color_calc_state) = {
.dirty = {
.mesa = _NEW_COLOR |
_NEW_STENCIL,
_NEW_STENCIL |
(GEN_GEN <= 5 ? _NEW_BUFFERS |
_NEW_DEPTH
: 0),
.brw = BRW_NEW_BATCH |
BRW_NEW_BLORP |
BRW_NEW_CC_STATE |
BRW_NEW_STATE_BASE_ADDRESS,
(GEN_GEN <= 5 ? BRW_NEW_CC_VP |
BRW_NEW_STATS_WM
: BRW_NEW_CC_STATE |
BRW_NEW_STATE_BASE_ADDRESS),
},
.emit = genX(upload_color_calc_state),
};
#endif
/* ---------------------------------------------------------------------- */
@@ -4924,7 +4976,7 @@ genX(init_atoms)(struct brw_context *brw)
&brw_recalculate_urb_fence,
&genX(cc_vp),
&brw_cc_unit,
&genX(color_calc_state),
/* Surface state setup. Must come before the VS/WM unit. The binding
* table upload must be last.