mesa: optimize the dual source blend error checking using a bitmask

Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8798>
This commit is contained in:
Marek Olšák 2021-01-25 23:55:55 -05:00 committed by Marge Bot
parent ad057b7f60
commit 9ee052eb73
5 changed files with 37 additions and 26 deletions

View file

@ -480,7 +480,7 @@ brw_wm_populate_key(struct brw_context *brw, struct brw_wm_prog_key *key)
/* _NEW_COLOR */ /* _NEW_COLOR */
key->force_dual_color_blend = brw->dual_color_blend_by_location && key->force_dual_color_blend = brw->dual_color_blend_by_location &&
(ctx->Color.BlendEnabled & 1) && ctx->Color.Blend[0]._UsesDualSrc; (ctx->Color.BlendEnabled & 1) && ctx->Color._BlendUsesDualSrc & 0x1;
/* _NEW_MULTISAMPLE, _NEW_BUFFERS */ /* _NEW_MULTISAMPLE, _NEW_BUFFERS */
key->alpha_to_coverage = _mesa_is_alpha_to_coverage_enabled(ctx); key->alpha_to_coverage = _mesa_is_alpha_to_coverage_enabled(ctx);

View file

@ -1942,7 +1942,7 @@ genX(upload_wm)(struct brw_context *brw)
#if GEN_GEN == 6 #if GEN_GEN == 6
wm.DualSourceBlendEnable = wm.DualSourceBlendEnable =
wm_prog_data->dual_src_blend && (ctx->Color.BlendEnabled & 1) && wm_prog_data->dual_src_blend && (ctx->Color.BlendEnabled & 1) &&
ctx->Color.Blend[0]._UsesDualSrc; ctx->Color._BlendUsesDualSrc & 0x1;
wm.oMaskPresenttoRenderTarget = wm_prog_data->uses_omask; wm.oMaskPresenttoRenderTarget = wm_prog_data->uses_omask;
wm.NumberofSFOutputAttributes = wm_prog_data->num_varying_inputs; wm.NumberofSFOutputAttributes = wm_prog_data->num_varying_inputs;
@ -2885,7 +2885,7 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
* We override SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO, * We override SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO,
* and leave it enabled anyway. * and leave it enabled anyway.
*/ */
if (GEN_GEN >= 6 && ctx->Color.Blend[i]._UsesDualSrc && alpha_to_one) { if (GEN_GEN >= 6 && ctx->Color._BlendUsesDualSrc & (1 << i) && alpha_to_one) {
srcRGB = fix_dual_blend_alpha_to_one(srcRGB); srcRGB = fix_dual_blend_alpha_to_one(srcRGB);
srcA = fix_dual_blend_alpha_to_one(srcA); srcA = fix_dual_blend_alpha_to_one(srcA);
dstRGB = fix_dual_blend_alpha_to_one(dstRGB); dstRGB = fix_dual_blend_alpha_to_one(dstRGB);
@ -2910,7 +2910,7 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
* so we just disable the blending to prevent possible issues. * so we just disable the blending to prevent possible issues.
*/ */
entry->ColorBufferBlendEnable = entry->ColorBufferBlendEnable =
!ctx->Color.Blend[0]._UsesDualSrc || wm_prog_data->dual_src_blend; !(ctx->Color._BlendUsesDualSrc & 0x1) || wm_prog_data->dual_src_blend;
entry->DestinationBlendFactor = blend_factor(dstRGB); entry->DestinationBlendFactor = blend_factor(dstRGB);
entry->SourceBlendFactor = blend_factor(srcRGB); entry->SourceBlendFactor = blend_factor(srcRGB);
@ -3926,7 +3926,7 @@ genX(upload_ps)(struct brw_context *brw)
*/ */
ps.DualSourceBlendEnable = prog_data->dual_src_blend && ps.DualSourceBlendEnable = prog_data->dual_src_blend &&
(ctx->Color.BlendEnabled & 1) && (ctx->Color.BlendEnabled & 1) &&
ctx->Color.Blend[0]._UsesDualSrc; ctx->Color._BlendUsesDualSrc & 0x1;
/* BRW_NEW_FS_PROG_DATA */ /* BRW_NEW_FS_PROG_DATA */
ps.AttributeEnable = (prog_data->num_varying_inputs != 0); ps.AttributeEnable = (prog_data->num_varying_inputs != 0);
@ -4818,7 +4818,7 @@ genX(upload_ps_blend)(struct brw_context *brw)
/* Alpha to One doesn't work with Dual Color Blending. Override /* Alpha to One doesn't work with Dual Color Blending. Override
* SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO. * SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO.
*/ */
if (alpha_to_one && color->Blend[0]._UsesDualSrc) { if (alpha_to_one && color->_BlendUsesDualSrc & 0x1) {
srcRGB = fix_dual_blend_alpha_to_one(srcRGB); srcRGB = fix_dual_blend_alpha_to_one(srcRGB);
srcA = fix_dual_blend_alpha_to_one(srcA); srcA = fix_dual_blend_alpha_to_one(srcA);
dstRGB = fix_dual_blend_alpha_to_one(dstRGB); dstRGB = fix_dual_blend_alpha_to_one(dstRGB);
@ -4843,7 +4843,7 @@ genX(upload_ps_blend)(struct brw_context *brw)
* so we just disable the blending to prevent possible issues. * so we just disable the blending to prevent possible issues.
*/ */
pb.ColorBufferBlendEnable = pb.ColorBufferBlendEnable =
!color->Blend[0]._UsesDualSrc || wm_prog_data->dual_src_blend; !(color->_BlendUsesDualSrc & 0x1) || wm_prog_data->dual_src_blend;
pb.SourceAlphaBlendFactor = brw_translate_blend_factor(srcA); pb.SourceAlphaBlendFactor = brw_translate_blend_factor(srcA);
pb.DestinationAlphaBlendFactor = brw_translate_blend_factor(dstA); pb.DestinationAlphaBlendFactor = brw_translate_blend_factor(dstA);
pb.SourceBlendFactor = brw_translate_blend_factor(srcRGB); pb.SourceBlendFactor = brw_translate_blend_factor(srcRGB);

View file

@ -168,7 +168,7 @@ blend_factor_is_dual_src(GLenum factor)
factor == GL_ONE_MINUS_SRC1_ALPHA); factor == GL_ONE_MINUS_SRC1_ALPHA);
} }
static void static bool
update_uses_dual_src(struct gl_context *ctx, int buf) update_uses_dual_src(struct gl_context *ctx, int buf)
{ {
bool uses_dual_src = bool uses_dual_src =
@ -177,10 +177,14 @@ update_uses_dual_src(struct gl_context *ctx, int buf)
blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) || blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) ||
blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA)); blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA));
if (ctx->Color.Blend[buf]._UsesDualSrc != uses_dual_src) { if (((ctx->Color._BlendUsesDualSrc >> buf) & 0x1) != uses_dual_src) {
ctx->Color.Blend[buf]._UsesDualSrc = uses_dual_src; if (uses_dual_src)
_mesa_update_valid_to_render_state(ctx); ctx->Color._BlendUsesDualSrc |= 1 << buf;
else
ctx->Color._BlendUsesDualSrc &= ~(1 << buf);
return true; /* changed state */
} }
return false; /* no change */
} }
@ -247,10 +251,16 @@ blend_func_separate(struct gl_context *ctx,
ctx->Color.Blend[buf].DstA = dfactorA; ctx->Color.Blend[buf].DstA = dfactorA;
} }
GLbitfield old_blend_uses_dual_src = ctx->Color._BlendUsesDualSrc;
update_uses_dual_src(ctx, 0); update_uses_dual_src(ctx, 0);
for (unsigned buf = 1; buf < numBuffers; buf++) { /* We have to replicate the bit to all color buffers. */
ctx->Color.Blend[buf]._UsesDualSrc = ctx->Color.Blend[0]._UsesDualSrc; if (ctx->Color._BlendUsesDualSrc & 0x1)
} ctx->Color._BlendUsesDualSrc |= BITFIELD_RANGE(1, numBuffers - 1);
else
ctx->Color._BlendUsesDualSrc = 0;
if (ctx->Color._BlendUsesDualSrc != old_blend_uses_dual_src)
_mesa_update_valid_to_render_state(ctx);
ctx->Color._BlendFuncPerBuffer = GL_FALSE; ctx->Color._BlendFuncPerBuffer = GL_FALSE;
@ -404,7 +414,8 @@ blend_func_separatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB;
ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].SrcA = sfactorA;
ctx->Color.Blend[buf].DstA = dfactorA; ctx->Color.Blend[buf].DstA = dfactorA;
update_uses_dual_src(ctx, buf); if (update_uses_dual_src(ctx, buf))
_mesa_update_valid_to_render_state(ctx);
ctx->Color._BlendFuncPerBuffer = GL_TRUE; ctx->Color._BlendFuncPerBuffer = GL_TRUE;
} }

View file

@ -96,11 +96,14 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx)
* has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
* color attachements." * color attachements."
*/ */
for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers; unsigned max_dual_source_buffers = ctx->Const.MaxDualSourceDrawBuffers;
i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { unsigned num_color_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
if (ctx->Color.Blend[i]._UsesDualSrc)
return; if (num_color_buffers > max_dual_source_buffers &&
} ctx->Color._BlendUsesDualSrc &
BITFIELD_RANGE(max_dual_source_buffers,
num_color_buffers - max_dual_source_buffers))
return;
if (ctx->Color.BlendEnabled && if (ctx->Color.BlendEnabled &&
ctx->Color._AdvancedBlendMode != BLEND_NONE) { ctx->Color._AdvancedBlendMode != BLEND_NONE) {
@ -119,7 +122,7 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx)
if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK)
return; return;
for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { for (unsigned i = 1; i < num_color_buffers; i++) {
if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE)
return; return;
} }

View file

@ -399,12 +399,9 @@ struct gl_colorbuffer_attrib
GLenum16 DstA; /**< Alpha blend dest term */ GLenum16 DstA; /**< Alpha blend dest term */
GLenum16 EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */ GLenum16 EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
GLenum16 EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */ GLenum16 EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
/**
* Set if any blend factor uses SRC1. Computed at the time blend factors
* get set.
*/
GLboolean _UsesDualSrc;
} Blend[MAX_DRAW_BUFFERS]; } Blend[MAX_DRAW_BUFFERS];
/** Bitfield of color buffers with enabled dual source blending. */
GLbitfield _BlendUsesDualSrc;
/** Are the blend func terms currently different for each buffer/target? */ /** Are the blend func terms currently different for each buffer/target? */
GLboolean _BlendFuncPerBuffer; GLboolean _BlendFuncPerBuffer;
/** Are the blend equations currently different for each buffer/target? */ /** Are the blend equations currently different for each buffer/target? */