compiler/mesa/st: Move gl_advanced_blend_mode to util/blend.h

Rename gl_advanced_blend_mode to pipe_advanced_blend_mode and move it
to src/util/blend.h so it can be shared between OpenGL and Vulkan
drivers.

This prepares for implementing VK_EXT_blend_operation_advanced by
providing a common enum for advanced blend modes across APIs.

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38929>
This commit is contained in:
Christian Gmeiner 2025-11-25 23:19:38 +01:00 committed by Marge Bot
parent 74f1d4f47b
commit 1eed6960c5
9 changed files with 97 additions and 98 deletions

View file

@ -303,7 +303,7 @@ set_lum_sat(nir_builder *b,
}
static nir_def *
is_mode(nir_builder *b, nir_variable *mode, enum gl_advanced_blend_mode q)
is_mode(nir_builder *b, nir_variable *mode, enum pipe_advanced_blend_mode q)
{
return nir_ieq_imm(b, nir_load_var(b, mode), (unsigned) q);
}
@ -318,7 +318,7 @@ calc_blend_result(nir_builder *b,
nir_variable *result = add_temp_var(b, "__blend_result", glsl_vec4_type());
/* If we're not doing advanced blending, just write the original value. */
nir_if *if_blending = nir_push_if(b, is_mode(b, mode, BLEND_NONE));
nir_if *if_blending = nir_push_if(b, is_mode(b, mode, PIPE_ADVANCED_BLEND_NONE));
nir_store_var(b, result, blend_src, ~0);
nir_push_else(b, if_blending);
@ -362,58 +362,58 @@ calc_blend_result(nir_builder *b,
unsigned choices = blend_qualifiers;
while (choices) {
enum gl_advanced_blend_mode choice = (enum gl_advanced_blend_mode)u_bit_scan(&choices);
enum pipe_advanced_blend_mode choice = (enum pipe_advanced_blend_mode)u_bit_scan(&choices);
nir_if *iff = nir_push_if(b, is_mode(b, mode, choice));
nir_def *val = NULL;
switch (choice) {
case BLEND_MULTIPLY:
case PIPE_ADVANCED_BLEND_MULTIPLY:
val = blend_multiply(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_SCREEN:
case PIPE_ADVANCED_BLEND_SCREEN:
val = blend_screen(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_OVERLAY:
case PIPE_ADVANCED_BLEND_OVERLAY:
val = blend_overlay(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_DARKEN:
case PIPE_ADVANCED_BLEND_DARKEN:
val = blend_darken(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_LIGHTEN:
case PIPE_ADVANCED_BLEND_LIGHTEN:
val = blend_lighten(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_COLORDODGE:
case PIPE_ADVANCED_BLEND_COLORDODGE:
val = blend_colordodge(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_COLORBURN:
case PIPE_ADVANCED_BLEND_COLORBURN:
val = blend_colorburn(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_HARDLIGHT:
case PIPE_ADVANCED_BLEND_HARDLIGHT:
val = blend_hardlight(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_SOFTLIGHT:
case PIPE_ADVANCED_BLEND_SOFTLIGHT:
val = blend_softlight(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_DIFFERENCE:
case PIPE_ADVANCED_BLEND_DIFFERENCE:
val = blend_difference(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_EXCLUSION:
case PIPE_ADVANCED_BLEND_EXCLUSION:
val = blend_exclusion(b, src_rgb_def, dst_rgb_def);
break;
case BLEND_HSL_HUE:
case PIPE_ADVANCED_BLEND_HSL_HUE:
set_lum_sat(b, factor, src_rgb, dst_rgb, dst_rgb);
break;
case BLEND_HSL_SATURATION:
case PIPE_ADVANCED_BLEND_HSL_SATURATION:
set_lum_sat(b, factor, dst_rgb, src_rgb, dst_rgb);
break;
case BLEND_HSL_COLOR:
case PIPE_ADVANCED_BLEND_HSL_COLOR:
set_lum(b, factor, src_rgb, dst_rgb);
break;
case BLEND_HSL_LUMINOSITY:
case PIPE_ADVANCED_BLEND_HSL_LUMINOSITY:
set_lum(b, factor, dst_rgb, src_rgb);
break;
case BLEND_NONE:
case PIPE_ADVANCED_BLEND_NONE:
UNREACHABLE("not real cases");
}

View file

@ -32,6 +32,7 @@
#include "ast.h"
#include "glsl_parser_extras.h"
#include "compiler/glsl_types.h"
#include "util/blend.h"
#include "util/u_string.h"
#include "util/format/u_format.h"
#include "main/consts_exts.h"
@ -1612,22 +1613,22 @@ layout_qualifier_id:
const char *s;
uint32_t mask;
} map[] = {
{ "blend_support_multiply", BITFIELD_BIT(BLEND_MULTIPLY) },
{ "blend_support_screen", BITFIELD_BIT(BLEND_SCREEN) },
{ "blend_support_overlay", BITFIELD_BIT(BLEND_OVERLAY) },
{ "blend_support_darken", BITFIELD_BIT(BLEND_DARKEN) },
{ "blend_support_lighten", BITFIELD_BIT(BLEND_LIGHTEN) },
{ "blend_support_colordodge", BITFIELD_BIT(BLEND_COLORDODGE) },
{ "blend_support_colorburn", BITFIELD_BIT(BLEND_COLORBURN) },
{ "blend_support_hardlight", BITFIELD_BIT(BLEND_HARDLIGHT) },
{ "blend_support_softlight", BITFIELD_BIT(BLEND_SOFTLIGHT) },
{ "blend_support_difference", BITFIELD_BIT(BLEND_DIFFERENCE) },
{ "blend_support_exclusion", BITFIELD_BIT(BLEND_EXCLUSION) },
{ "blend_support_hsl_hue", BITFIELD_BIT(BLEND_HSL_HUE) },
{ "blend_support_hsl_saturation", BITFIELD_BIT(BLEND_HSL_SATURATION) },
{ "blend_support_hsl_color", BITFIELD_BIT(BLEND_HSL_COLOR) },
{ "blend_support_hsl_luminosity", BITFIELD_BIT(BLEND_HSL_LUMINOSITY) },
{ "blend_support_all_equations", (1u << (BLEND_HSL_LUMINOSITY + 1)) - 2 },
{ "blend_support_multiply", BITFIELD_BIT(PIPE_ADVANCED_BLEND_MULTIPLY) },
{ "blend_support_screen", BITFIELD_BIT(PIPE_ADVANCED_BLEND_SCREEN) },
{ "blend_support_overlay", BITFIELD_BIT(PIPE_ADVANCED_BLEND_OVERLAY) },
{ "blend_support_darken", BITFIELD_BIT(PIPE_ADVANCED_BLEND_DARKEN) },
{ "blend_support_lighten", BITFIELD_BIT(PIPE_ADVANCED_BLEND_LIGHTEN) },
{ "blend_support_colordodge", BITFIELD_BIT(PIPE_ADVANCED_BLEND_COLORDODGE) },
{ "blend_support_colorburn", BITFIELD_BIT(PIPE_ADVANCED_BLEND_COLORBURN) },
{ "blend_support_hardlight", BITFIELD_BIT(PIPE_ADVANCED_BLEND_HARDLIGHT) },
{ "blend_support_softlight", BITFIELD_BIT(PIPE_ADVANCED_BLEND_SOFTLIGHT) },
{ "blend_support_difference", BITFIELD_BIT(PIPE_ADVANCED_BLEND_DIFFERENCE) },
{ "blend_support_exclusion", BITFIELD_BIT(PIPE_ADVANCED_BLEND_EXCLUSION) },
{ "blend_support_hsl_hue", BITFIELD_BIT(PIPE_ADVANCED_BLEND_HSL_HUE) },
{ "blend_support_hsl_saturation", BITFIELD_BIT(PIPE_ADVANCED_BLEND_HSL_SATURATION) },
{ "blend_support_hsl_color", BITFIELD_BIT(PIPE_ADVANCED_BLEND_HSL_COLOR) },
{ "blend_support_hsl_luminosity", BITFIELD_BIT(PIPE_ADVANCED_BLEND_HSL_LUMINOSITY) },
{ "blend_support_all_equations", (1u << (PIPE_ADVANCED_BLEND_HSL_LUMINOSITY + 1)) - 2 },
};
for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
if (match_layout_qualifier($1, map[i].s, state) == 0) {

View file

@ -1256,29 +1256,6 @@ enum gl_access_qualifier
ACCESS_FUSED_EU_DISABLE_INTEL = (1 << 19),
};
/**
* \brief Blend support qualifiers
*/
enum gl_advanced_blend_mode
{
BLEND_NONE = 0,
BLEND_MULTIPLY,
BLEND_SCREEN,
BLEND_OVERLAY,
BLEND_DARKEN,
BLEND_LIGHTEN,
BLEND_COLORDODGE,
BLEND_COLORBURN,
BLEND_HARDLIGHT,
BLEND_SOFTLIGHT,
BLEND_DIFFERENCE,
BLEND_EXCLUSION,
BLEND_HSL_HUE,
BLEND_HSL_SATURATION,
BLEND_HSL_COLOR,
BLEND_HSL_LUMINOSITY,
};
enum gl_tess_spacing
{
TESS_SPACING_UNSPECIFIED,

View file

@ -455,61 +455,62 @@ legal_simple_blend_equation(const struct gl_context *ctx, GLenum mode)
}
}
static enum gl_advanced_blend_mode
static enum pipe_advanced_blend_mode
advanced_blend_mode_from_gl_enum(GLenum mode)
{
switch (mode) {
case GL_MULTIPLY_KHR:
return BLEND_MULTIPLY;
return PIPE_ADVANCED_BLEND_MULTIPLY;
case GL_SCREEN_KHR:
return BLEND_SCREEN;
return PIPE_ADVANCED_BLEND_SCREEN;
case GL_OVERLAY_KHR:
return BLEND_OVERLAY;
return PIPE_ADVANCED_BLEND_OVERLAY;
case GL_DARKEN_KHR:
return BLEND_DARKEN;
return PIPE_ADVANCED_BLEND_DARKEN;
case GL_LIGHTEN_KHR:
return BLEND_LIGHTEN;
return PIPE_ADVANCED_BLEND_LIGHTEN;
case GL_COLORDODGE_KHR:
return BLEND_COLORDODGE;
return PIPE_ADVANCED_BLEND_COLORDODGE;
case GL_COLORBURN_KHR:
return BLEND_COLORBURN;
return PIPE_ADVANCED_BLEND_COLORBURN;
case GL_HARDLIGHT_KHR:
return BLEND_HARDLIGHT;
return PIPE_ADVANCED_BLEND_HARDLIGHT;
case GL_SOFTLIGHT_KHR:
return BLEND_SOFTLIGHT;
return PIPE_ADVANCED_BLEND_SOFTLIGHT;
case GL_DIFFERENCE_KHR:
return BLEND_DIFFERENCE;
return PIPE_ADVANCED_BLEND_DIFFERENCE;
case GL_EXCLUSION_KHR:
return BLEND_EXCLUSION;
return PIPE_ADVANCED_BLEND_EXCLUSION;
case GL_HSL_HUE_KHR:
return BLEND_HSL_HUE;
return PIPE_ADVANCED_BLEND_HSL_HUE;
case GL_HSL_SATURATION_KHR:
return BLEND_HSL_SATURATION;
return PIPE_ADVANCED_BLEND_HSL_SATURATION;
case GL_HSL_COLOR_KHR:
return BLEND_HSL_COLOR;
return PIPE_ADVANCED_BLEND_HSL_COLOR;
case GL_HSL_LUMINOSITY_KHR:
return BLEND_HSL_LUMINOSITY;
return PIPE_ADVANCED_BLEND_HSL_LUMINOSITY;
default:
return BLEND_NONE;
return PIPE_ADVANCED_BLEND_NONE;
}
}
/**
* If \p mode is one of the advanced blending equations defined by
* GL_KHR_blend_equation_advanced (and the extension is supported),
* return the corresponding BLEND_* enum. Otherwise, return BLEND_NONE
* (which can also be treated as false).
* return the corresponding PIPE_ADVANCED_BLEND_* enum.
* Otherwise, return PIPE_ADVANCED_BLEND_NONE (which can also be
* treated as false).
*/
static enum gl_advanced_blend_mode
static enum pipe_advanced_blend_mode
advanced_blend_mode(const struct gl_context *ctx, GLenum mode)
{
return _mesa_has_KHR_blend_equation_advanced(ctx) ?
advanced_blend_mode_from_gl_enum(mode) : BLEND_NONE;
advanced_blend_mode_from_gl_enum(mode) : PIPE_ADVANCED_BLEND_NONE;
}
static void
set_advanced_blend_mode(struct gl_context *ctx,
enum gl_advanced_blend_mode advanced_mode)
enum pipe_advanced_blend_mode advanced_mode)
{
if (ctx->Color._AdvancedBlendMode != advanced_mode) {
ctx->Color._AdvancedBlendMode = advanced_mode;
@ -525,7 +526,7 @@ _mesa_BlendEquation( GLenum mode )
const unsigned numBuffers = num_buffers(ctx);
unsigned buf;
bool changed = false;
enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
enum pipe_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquation(%s)\n",
@ -575,7 +576,7 @@ _mesa_BlendEquation( GLenum mode )
*/
static void
blend_equationi(struct gl_context *ctx, GLuint buf, GLenum mode,
enum gl_advanced_blend_mode advanced_mode)
enum pipe_advanced_blend_mode advanced_mode)
{
if (ctx->Color.Blend[buf].EquationRGB == mode &&
ctx->Color.Blend[buf].EquationA == mode)
@ -597,7 +598,7 @@ _mesa_BlendEquationiARB_no_error(GLuint buf, GLenum mode)
{
GET_CURRENT_CONTEXT(ctx);
enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
enum pipe_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
blend_equationi(ctx, buf, mode, advanced_mode);
}
@ -606,7 +607,7 @@ void GLAPIENTRY
_mesa_BlendEquationiARB(GLuint buf, GLenum mode)
{
GET_CURRENT_CONTEXT(ctx);
enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
enum pipe_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
@ -687,7 +688,7 @@ blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA,
ctx->Color.Blend[buf].EquationA = modeA;
}
ctx->Color._BlendEquationPerBuffer = GL_FALSE;
set_advanced_blend_mode(ctx, BLEND_NONE);
set_advanced_blend_mode(ctx, PIPE_ADVANCED_BLEND_NONE);
}
@ -743,7 +744,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;
set_advanced_blend_mode(ctx, BLEND_NONE);
set_advanced_blend_mode(ctx, PIPE_ADVANCED_BLEND_NONE);
}
@ -824,7 +825,7 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
* \param func alpha comparison function.
* \param ref reference value.
*
* Verifies the parameters and updates gl_colorbuffer_attrib.
* Verifies the parameters and updates gl_colorbuffer_attrib.
* On a change, flushes the vertices and notifies the driver via
* dd_function_table::AlphaFunc callback.
*/

View file

@ -33,6 +33,7 @@
#define BLEND_H
#include "util/blend.h"
#include "util/glheader.h"
#include "context.h"
#include "formats.h"
@ -63,21 +64,21 @@ extern void
_mesa_update_clamp_vertex_color(struct gl_context *ctx,
const struct gl_framebuffer *drawFb);
extern void
extern void
_mesa_init_color( struct gl_context * ctx );
static inline enum gl_advanced_blend_mode
static inline enum pipe_advanced_blend_mode
_mesa_get_advanced_blend_sh_constant(GLbitfield blend_enabled,
enum gl_advanced_blend_mode mode)
enum pipe_advanced_blend_mode mode)
{
return blend_enabled ? mode : BLEND_NONE;
return blend_enabled ? mode : PIPE_ADVANCED_BLEND_NONE;
}
static inline bool
_mesa_advanded_blend_sh_constant_changed(struct gl_context *ctx,
GLbitfield new_blend_enabled,
enum gl_advanced_blend_mode new_mode)
enum pipe_advanced_blend_mode new_mode)
{
return _mesa_get_advanced_blend_sh_constant(new_blend_enabled, new_mode) !=
_mesa_get_advanced_blend_sh_constant(ctx->Color.BlendEnabled,
@ -94,7 +95,7 @@ _mesa_flush_vertices_for_blend_state(struct gl_context *ctx)
static inline void
_mesa_flush_vertices_for_blend_adv(struct gl_context *ctx,
GLbitfield new_blend_enabled,
enum gl_advanced_blend_mode new_mode)
enum pipe_advanced_blend_mode new_mode)
{
/* The advanced blend mode needs _NEW_COLOR to update the state constant. */
if (_mesa_has_KHR_blend_equation_advanced(ctx) &&

View file

@ -121,7 +121,7 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx)
return;
if (ctx->Color.BlendEnabled &&
ctx->Color._AdvancedBlendMode != BLEND_NONE) {
ctx->Color._AdvancedBlendMode != PIPE_ADVANCED_BLEND_NONE) {
/* The KHR_blend_equation_advanced spec says:
*
* "If any non-NONE draw buffer uses a blend equation found in table

View file

@ -292,7 +292,7 @@ struct gl_colorbuffer_attrib
* draw buffer, and NVX_blend_equation_advanced_multi_draw_buffer still
* requires all draw buffers to match, so we only need a single value.
*/
enum gl_advanced_blend_mode _AdvancedBlendMode;
enum pipe_advanced_blend_mode _AdvancedBlendMode;
/** Coherency requested via glEnable(GL_BLEND_ADVANCED_COHERENT_KHR)? */
bool BlendCoherent;

View file

@ -262,7 +262,7 @@ st_update_blend( struct st_context *st )
blend->rt[i].colormask = colormask;
}
if (ctx->Color._AdvancedBlendMode != BLEND_NONE) {
if (ctx->Color._AdvancedBlendMode != PIPE_ADVANCED_BLEND_NONE) {
blend->blend_coherent = ctx->Color.BlendCoherent;
}
@ -272,11 +272,11 @@ st_update_blend( struct st_context *st )
blend->logicop_func = ctx->Color._LogicOp;
}
else if (ctx->Color.BlendEnabled &&
ctx->Color._AdvancedBlendMode != BLEND_NONE) {
ctx->Color._AdvancedBlendMode != PIPE_ADVANCED_BLEND_NONE) {
blend->advanced_blend_func = ctx->Color._AdvancedBlendMode;
}
else if (ctx->Color.BlendEnabled &&
ctx->Color._AdvancedBlendMode == BLEND_NONE) {
ctx->Color._AdvancedBlendMode == PIPE_ADVANCED_BLEND_NONE) {
/* blending enabled */
for (i = 0, j = 0; i < num_state; i++) {
if (!(ctx->Color.BlendEnabled & (1 << i)) ||

View file

@ -118,6 +118,25 @@ enum pipe_logicop {
PIPE_LOGICOP_SET,
};
enum pipe_advanced_blend_mode {
PIPE_ADVANCED_BLEND_NONE = 0,
PIPE_ADVANCED_BLEND_MULTIPLY,
PIPE_ADVANCED_BLEND_SCREEN,
PIPE_ADVANCED_BLEND_OVERLAY,
PIPE_ADVANCED_BLEND_DARKEN,
PIPE_ADVANCED_BLEND_LIGHTEN,
PIPE_ADVANCED_BLEND_COLORDODGE,
PIPE_ADVANCED_BLEND_COLORBURN,
PIPE_ADVANCED_BLEND_HARDLIGHT,
PIPE_ADVANCED_BLEND_SOFTLIGHT,
PIPE_ADVANCED_BLEND_DIFFERENCE,
PIPE_ADVANCED_BLEND_EXCLUSION,
PIPE_ADVANCED_BLEND_HSL_HUE,
PIPE_ADVANCED_BLEND_HSL_SATURATION,
PIPE_ADVANCED_BLEND_HSL_COLOR,
PIPE_ADVANCED_BLEND_HSL_LUMINOSITY,
};
/**
* When faking RGBX render target formats with RGBA ones, the blender is still
* supposed to treat the destination's alpha channel as 1 instead of the