mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
mesa: move blending validation from draws to state changes
This is a step towards removing _mesa_valid_to_render. 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:
parent
40341c5118
commit
bf9d61a3d4
2 changed files with 75 additions and 85 deletions
|
|
@ -32,6 +32,7 @@
|
|||
#include "glheader.h"
|
||||
#include "blend.h"
|
||||
#include "context.h"
|
||||
#include "draw_validate.h"
|
||||
#include "enums.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
|
|
@ -170,11 +171,16 @@ blend_factor_is_dual_src(GLenum factor)
|
|||
static void
|
||||
update_uses_dual_src(struct gl_context *ctx, int buf)
|
||||
{
|
||||
ctx->Color.Blend[buf]._UsesDualSrc =
|
||||
bool uses_dual_src =
|
||||
(blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcRGB) ||
|
||||
blend_factor_is_dual_src(ctx->Color.Blend[buf].DstRGB) ||
|
||||
blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) ||
|
||||
blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA));
|
||||
|
||||
if (ctx->Color.Blend[buf]._UsesDualSrc != uses_dual_src) {
|
||||
ctx->Color.Blend[buf]._UsesDualSrc = uses_dual_src;
|
||||
_mesa_update_valid_to_render_state(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -497,6 +503,16 @@ advanced_blend_mode(const struct gl_context *ctx, GLenum mode)
|
|||
advanced_blend_mode_from_gl_enum(mode) : BLEND_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_advanced_blend_mode(struct gl_context *ctx,
|
||||
enum gl_advanced_blend_mode advanced_mode)
|
||||
{
|
||||
if (ctx->Color._AdvancedBlendMode != advanced_mode) {
|
||||
ctx->Color._AdvancedBlendMode = advanced_mode;
|
||||
_mesa_update_valid_to_render_state(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is really an extension function! */
|
||||
void GLAPIENTRY
|
||||
_mesa_BlendEquation( GLenum mode )
|
||||
|
|
@ -546,7 +562,7 @@ _mesa_BlendEquation( GLenum mode )
|
|||
ctx->Color.Blend[buf].EquationA = mode;
|
||||
}
|
||||
ctx->Color._BlendEquationPerBuffer = GL_FALSE;
|
||||
ctx->Color._AdvancedBlendMode = advanced_mode;
|
||||
set_advanced_blend_mode(ctx, advanced_mode);
|
||||
|
||||
if (ctx->Driver.BlendEquationSeparate)
|
||||
ctx->Driver.BlendEquationSeparate(ctx, mode, mode);
|
||||
|
|
@ -571,7 +587,7 @@ blend_equationi(struct gl_context *ctx, GLuint buf, GLenum mode,
|
|||
ctx->Color._BlendEquationPerBuffer = GL_TRUE;
|
||||
|
||||
if (buf == 0)
|
||||
ctx->Color._AdvancedBlendMode = advanced_mode;
|
||||
set_advanced_blend_mode(ctx, advanced_mode);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -670,7 +686,7 @@ blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA,
|
|||
ctx->Color.Blend[buf].EquationA = modeA;
|
||||
}
|
||||
ctx->Color._BlendEquationPerBuffer = GL_FALSE;
|
||||
ctx->Color._AdvancedBlendMode = BLEND_NONE;
|
||||
set_advanced_blend_mode(ctx, BLEND_NONE);
|
||||
|
||||
if (ctx->Driver.BlendEquationSeparate)
|
||||
ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
|
||||
|
|
@ -729,7 +745,7 @@ blend_equation_separatei(struct gl_context *ctx, GLuint buf, GLenum modeRGB,
|
|||
ctx->Color.Blend[buf].EquationRGB = modeRGB;
|
||||
ctx->Color.Blend[buf].EquationA = modeA;
|
||||
ctx->Color._BlendEquationPerBuffer = GL_TRUE;
|
||||
ctx->Color._AdvancedBlendMode = BLEND_NONE;
|
||||
set_advanced_blend_mode(ctx, BLEND_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,82 +38,6 @@
|
|||
#include "program/prog_print.h"
|
||||
|
||||
|
||||
static bool
|
||||
check_blend_func_error(struct gl_context *ctx)
|
||||
{
|
||||
/* The ARB_blend_func_extended spec's ERRORS section says:
|
||||
*
|
||||
* "The error INVALID_OPERATION is generated by Begin or any procedure
|
||||
* that implicitly calls Begin if any draw buffer has a blend function
|
||||
* requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR,
|
||||
* SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that
|
||||
* has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
|
||||
* color attachements."
|
||||
*/
|
||||
for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers;
|
||||
i < ctx->DrawBuffer->_NumColorDrawBuffers;
|
||||
i++) {
|
||||
if (ctx->Color.Blend[i]._UsesDualSrc) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"dual source blend on illegal attachment");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Color.BlendEnabled &&
|
||||
ctx->Color._AdvancedBlendMode != BLEND_NONE) {
|
||||
/* The KHR_blend_equation_advanced spec says:
|
||||
*
|
||||
* "If any non-NONE draw buffer uses a blend equation found in table
|
||||
* X.1 or X.2, the error INVALID_OPERATION is generated by Begin or
|
||||
* any operation that implicitly calls Begin (such as DrawElements)
|
||||
* if:
|
||||
*
|
||||
* * the draw buffer for color output zero selects multiple color
|
||||
* buffers (e.g., FRONT_AND_BACK in the default framebuffer); or
|
||||
*
|
||||
* * the draw buffer for any other color output is not NONE."
|
||||
*/
|
||||
if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"advanced blending is active and draw buffer for color "
|
||||
"output zero selects multiple color buffers");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
|
||||
if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"advanced blending is active with multiple color "
|
||||
"draw buffers");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The KHR_blend_equation_advanced spec says:
|
||||
*
|
||||
* "Advanced blending equations require the use of a fragment shader
|
||||
* with a matching "blend_support" layout qualifier. If the current
|
||||
* blend equation is found in table X.1 or X.2, and the active
|
||||
* fragment shader does not include the layout qualifier matching
|
||||
* the blend equation or "blend_support_all_equations", the error
|
||||
* INVALID_OPERATION is generated [...]"
|
||||
*/
|
||||
const struct gl_program *prog = ctx->FragmentProgram._Current;
|
||||
const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport;
|
||||
|
||||
if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"fragment shader does not allow advanced blending mode "
|
||||
"(%s)",
|
||||
_mesa_enum_to_string(ctx->Color.Blend[0].EquationRGB));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prior to drawing anything with glBegin, glDrawArrays, etc. this function
|
||||
* is called to see if it's valid to render. This involves checking that
|
||||
|
|
@ -129,10 +53,6 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
|
|||
if (ctx->NewState)
|
||||
_mesa_update_state(ctx);
|
||||
|
||||
if (!check_blend_func_error(ctx)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -186,6 +106,60 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx)
|
|||
!_mesa_sampler_uniforms_are_valid(shader->ActiveProgram, NULL, 0))
|
||||
return;
|
||||
|
||||
/* The ARB_blend_func_extended spec's ERRORS section says:
|
||||
*
|
||||
* "The error INVALID_OPERATION is generated by Begin or any procedure
|
||||
* that implicitly calls Begin if any draw buffer has a blend function
|
||||
* requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR,
|
||||
* SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that
|
||||
* has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
|
||||
* color attachements."
|
||||
*/
|
||||
for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers;
|
||||
i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
|
||||
if (ctx->Color.Blend[i]._UsesDualSrc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->Color.BlendEnabled &&
|
||||
ctx->Color._AdvancedBlendMode != BLEND_NONE) {
|
||||
/* The KHR_blend_equation_advanced spec says:
|
||||
*
|
||||
* "If any non-NONE draw buffer uses a blend equation found in table
|
||||
* X.1 or X.2, the error INVALID_OPERATION is generated by Begin or
|
||||
* any operation that implicitly calls Begin (such as DrawElements)
|
||||
* if:
|
||||
*
|
||||
* * the draw buffer for color output zero selects multiple color
|
||||
* buffers (e.g., FRONT_AND_BACK in the default framebuffer); or
|
||||
*
|
||||
* * the draw buffer for any other color output is not NONE."
|
||||
*/
|
||||
if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK)
|
||||
return;
|
||||
|
||||
for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
|
||||
if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE)
|
||||
return;
|
||||
}
|
||||
|
||||
/* The KHR_blend_equation_advanced spec says:
|
||||
*
|
||||
* "Advanced blending equations require the use of a fragment shader
|
||||
* with a matching "blend_support" layout qualifier. If the current
|
||||
* blend equation is found in table X.1 or X.2, and the active
|
||||
* fragment shader does not include the layout qualifier matching
|
||||
* the blend equation or "blend_support_all_equations", the error
|
||||
* INVALID_OPERATION is generated [...]"
|
||||
*/
|
||||
const struct gl_program *prog =
|
||||
ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
|
||||
const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport;
|
||||
|
||||
if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->API == API_OPENGL_COMPAT) {
|
||||
if (!shader->CurrentProgram[MESA_SHADER_FRAGMENT]) {
|
||||
if (ctx->FragmentProgram.Enabled &&
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue