mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
gpu: Make blend modes configurable
For now, we only have OVER and ADD blend modes. This commit doesn't use ADD, it just sets up all the machinery and refactors things.
This commit is contained in:
parent
a031011e5e
commit
5cf3c70db0
@ -146,11 +146,7 @@ gsk_gl_frame_submit (GskGpuFrame *frame,
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
|
||||
/* Pre-multiplied alpha */
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation (GL_FUNC_ADD);
|
||||
|
||||
if (vertex_buffer)
|
||||
gsk_gl_buffer_bind (GSK_GL_BUFFER (vertex_buffer));
|
||||
|
103
gsk/gpu/gskgpublendop.c
Normal file
103
gsk/gpu/gskgpublendop.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskgpublendopprivate.h"
|
||||
|
||||
#include "gskgpuopprivate.h"
|
||||
#include "gskgpuprintprivate.h"
|
||||
|
||||
typedef struct _GskGpuBlendOp GskGpuBlendOp;
|
||||
|
||||
struct _GskGpuBlendOp
|
||||
{
|
||||
GskGpuOp op;
|
||||
|
||||
GskGpuBlend blend;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_blend_op_finish (GskGpuOp *op)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_blend_op_print (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GskGpuBlendOp *self = (GskGpuBlendOp *) op;
|
||||
|
||||
gsk_gpu_print_op (string, indent, "blend");
|
||||
switch (self->blend)
|
||||
{
|
||||
case GSK_GPU_BLEND_OVER:
|
||||
gsk_gpu_print_string (string, "over");
|
||||
break;
|
||||
case GSK_GPU_BLEND_ADD:
|
||||
gsk_gpu_print_string (string, "add");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
static GskGpuOp *
|
||||
gsk_gpu_blend_op_vk_command (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GskVulkanCommandState *state)
|
||||
{
|
||||
GskGpuBlendOp *self = (GskGpuBlendOp *) op;
|
||||
|
||||
state->blend = self->blend;
|
||||
|
||||
return op->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
static GskGpuOp *
|
||||
gsk_gpu_blend_op_gl_command (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GskGLCommandState *state)
|
||||
{
|
||||
GskGpuBlendOp *self = (GskGpuBlendOp *) op;
|
||||
|
||||
switch (self->blend)
|
||||
{
|
||||
case GSK_GPU_BLEND_OVER:
|
||||
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case GSK_GPU_BLEND_ADD:
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return op->next;
|
||||
}
|
||||
|
||||
static const GskGpuOpClass GSK_GPU_BLEND_OP_CLASS = {
|
||||
GSK_GPU_OP_SIZE (GskGpuBlendOp),
|
||||
GSK_GPU_STAGE_COMMAND,
|
||||
gsk_gpu_blend_op_finish,
|
||||
gsk_gpu_blend_op_print,
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
gsk_gpu_blend_op_vk_command,
|
||||
#endif
|
||||
gsk_gpu_blend_op_gl_command
|
||||
};
|
||||
|
||||
void
|
||||
gsk_gpu_blend_op (GskGpuFrame *frame,
|
||||
GskGpuBlend blend)
|
||||
{
|
||||
GskGpuBlendOp *self;
|
||||
|
||||
self = (GskGpuBlendOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_BLEND_OP_CLASS);
|
||||
|
||||
self->blend = blend;
|
||||
}
|
12
gsk/gpu/gskgpublendopprivate.h
Normal file
12
gsk/gpu/gskgpublendopprivate.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_blend_op (GskGpuFrame *frame,
|
||||
GskGpuBlend blend);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "gskgpuborderopprivate.h"
|
||||
#include "gskgpuboxshadowopprivate.h"
|
||||
#include "gskgpublendopprivate.h"
|
||||
#include "gskgpublitopprivate.h"
|
||||
#include "gskgpubluropprivate.h"
|
||||
#include "gskgpuclearopprivate.h"
|
||||
@ -89,6 +90,7 @@ typedef enum {
|
||||
GSK_GPU_GLOBAL_SCALE = (1 << 1),
|
||||
GSK_GPU_GLOBAL_CLIP = (1 << 2),
|
||||
GSK_GPU_GLOBAL_SCISSOR = (1 << 3),
|
||||
GSK_GPU_GLOBAL_BLEND = (1 << 4),
|
||||
} GskGpuGlobals;
|
||||
|
||||
struct _GskGpuNodeProcessor
|
||||
@ -96,6 +98,7 @@ struct _GskGpuNodeProcessor
|
||||
GskGpuFrame *frame;
|
||||
GskGpuDescriptors *desc;
|
||||
cairo_rectangle_int_t scissor;
|
||||
GskGpuBlend blend;
|
||||
graphene_point_t offset;
|
||||
graphene_matrix_t projection;
|
||||
graphene_vec2_t scale;
|
||||
@ -154,6 +157,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
|
||||
self->desc = NULL;
|
||||
|
||||
self->scissor = *clip;
|
||||
self->blend = GSK_GPU_BLEND_OVER;
|
||||
gsk_gpu_clip_init_empty (&self->clip, &GRAPHENE_RECT_INIT (0, 0, viewport->size.width, viewport->size.height));
|
||||
|
||||
self->modelview = NULL;
|
||||
@ -163,7 +167,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
|
||||
self->offset = GRAPHENE_POINT_INIT (-viewport->origin.x,
|
||||
-viewport->origin.y);
|
||||
self->opacity = 1.0;
|
||||
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR;
|
||||
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -195,6 +199,13 @@ gsk_gpu_node_processor_emit_scissor_op (GskGpuNodeProcessor *self)
|
||||
self->pending_globals &= ~GSK_GPU_GLOBAL_SCISSOR;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_emit_blend_op (GskGpuNodeProcessor *self)
|
||||
{
|
||||
gsk_gpu_blend_op (self->frame, self->blend);
|
||||
self->pending_globals &= ~GSK_GPU_GLOBAL_BLEND;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_sync_globals (GskGpuNodeProcessor *self,
|
||||
GskGpuGlobals ignored)
|
||||
@ -207,6 +218,8 @@ gsk_gpu_node_processor_sync_globals (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_node_processor_emit_globals_op (self);
|
||||
if (required & GSK_GPU_GLOBAL_SCISSOR)
|
||||
gsk_gpu_node_processor_emit_scissor_op (self);
|
||||
if (required & GSK_GPU_GLOBAL_BLEND)
|
||||
gsk_gpu_node_processor_emit_blend_op (self);
|
||||
}
|
||||
|
||||
static guint32
|
||||
@ -3075,7 +3088,7 @@ static const struct
|
||||
NULL,
|
||||
},
|
||||
[GSK_TRANSFORM_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_transform_node,
|
||||
gsk_gpu_node_processor_create_transform_pattern,
|
||||
@ -3099,13 +3112,13 @@ static const struct
|
||||
gsk_gpu_node_processor_create_repeat_pattern
|
||||
},
|
||||
[GSK_CLIP_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_clip_node,
|
||||
gsk_gpu_node_processor_create_clip_pattern,
|
||||
},
|
||||
[GSK_ROUNDED_CLIP_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_rounded_clip_node,
|
||||
NULL,
|
||||
@ -3141,7 +3154,7 @@ static const struct
|
||||
NULL,
|
||||
},
|
||||
[GSK_DEBUG_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_debug_node,
|
||||
gsk_gpu_node_processor_create_debug_pattern,
|
||||
@ -3177,7 +3190,7 @@ static const struct
|
||||
NULL,
|
||||
},
|
||||
[GSK_SUBSURFACE_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_subsurface_node,
|
||||
gsk_gpu_node_processor_create_subsurface_pattern,
|
||||
|
@ -37,6 +37,7 @@ struct _GskVulkanCommandState
|
||||
VkRenderPass vk_render_pass;
|
||||
VkFormat vk_format;
|
||||
VkCommandBuffer vk_command_buffer;
|
||||
GskGpuBlend blend;
|
||||
|
||||
GskVulkanDescriptors *desc;
|
||||
GskVulkanSemaphores *semaphores;
|
||||
|
@ -22,6 +22,14 @@ gsk_gpu_print_op (GString *string,
|
||||
g_string_append_c (string, ' ');
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_print_string (GString *string,
|
||||
const char *s)
|
||||
{
|
||||
g_string_append (string, s);
|
||||
g_string_append_c (string, ' ');
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_print_rect (GString *string,
|
||||
const float rect[4])
|
||||
|
@ -15,6 +15,8 @@ void gsk_gpu_print_op (GString
|
||||
|
||||
void gsk_gpu_print_newline (GString *string);
|
||||
|
||||
void gsk_gpu_print_string (GString *string,
|
||||
const char *s);
|
||||
void gsk_gpu_print_rect (GString *string,
|
||||
const float rect[4]);
|
||||
void gsk_gpu_print_int_rect (GString *string,
|
||||
|
@ -71,6 +71,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
|
||||
gsk_vulkan_descriptors_get_pipeline_layout (state->desc),
|
||||
shader_op_class,
|
||||
self->clip,
|
||||
state->blend,
|
||||
state->vk_format,
|
||||
state->vk_render_pass));
|
||||
|
||||
|
@ -47,6 +47,11 @@ typedef enum {
|
||||
GSK_GPU_SHADER_CLIP_ROUNDED
|
||||
} GskGpuShaderClip;
|
||||
|
||||
typedef enum {
|
||||
GSK_GPU_BLEND_OVER,
|
||||
GSK_GPU_BLEND_ADD
|
||||
} GskGpuBlend;
|
||||
|
||||
typedef enum {
|
||||
GSK_GPU_PATTERN_DONE,
|
||||
GSK_GPU_PATTERN_COLOR,
|
||||
|
@ -77,6 +77,7 @@ struct _PipelineCacheKey
|
||||
{
|
||||
const GskGpuShaderOpClass *op_class;
|
||||
GskGpuShaderClip clip;
|
||||
GskGpuBlend blend;
|
||||
VkFormat format;
|
||||
};
|
||||
|
||||
@ -112,7 +113,8 @@ pipeline_cache_key_hash (gconstpointer data)
|
||||
|
||||
return GPOINTER_TO_UINT (key->op_class) ^
|
||||
key->clip ^
|
||||
(key->format << 2);
|
||||
(key->blend << 2) ^
|
||||
(key->format << 4);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -124,6 +126,7 @@ pipeline_cache_key_equal (gconstpointer a,
|
||||
|
||||
return keya->op_class == keyb->op_class &&
|
||||
keya->clip == keyb->clip &&
|
||||
keya->blend == keyb->blend &&
|
||||
keya->format == keyb->format;
|
||||
}
|
||||
|
||||
@ -879,11 +882,41 @@ struct _GskVulkanShaderSpecialization
|
||||
guint32 n_buffers;
|
||||
};
|
||||
|
||||
static VkPipelineColorBlendAttachmentState blend_attachment_states[2] = {
|
||||
[GSK_GPU_BLEND_OVER] = {
|
||||
.blendEnable = VK_TRUE,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_A_BIT
|
||||
| VK_COLOR_COMPONENT_R_BIT
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
},
|
||||
[GSK_GPU_BLEND_ADD] = {
|
||||
.blendEnable = VK_TRUE,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_A_BIT
|
||||
| VK_COLOR_COMPONENT_R_BIT
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
},
|
||||
};
|
||||
|
||||
VkPipeline
|
||||
gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout,
|
||||
const GskGpuShaderOpClass *op_class,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuBlend blend,
|
||||
VkFormat format,
|
||||
VkRenderPass render_pass)
|
||||
{
|
||||
@ -896,6 +929,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
cache_key = (PipelineCacheKey) {
|
||||
.op_class = op_class,
|
||||
.clip = clip,
|
||||
.blend = blend,
|
||||
.format = format,
|
||||
};
|
||||
pipeline = g_hash_table_lookup (layout->pipeline_cache, &cache_key);
|
||||
@ -1035,21 +1069,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = (VkPipelineColorBlendAttachmentState []) {
|
||||
{
|
||||
.blendEnable = VK_TRUE,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_A_BIT
|
||||
| VK_COLOR_COMPONENT_R_BIT
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
},
|
||||
}
|
||||
.pAttachments = &blend_attachment_states[blend],
|
||||
},
|
||||
.pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
|
@ -74,6 +74,7 @@ VkPipeline gsk_vulkan_device_get_vk_pipeline (GskVulk
|
||||
GskVulkanPipelineLayout*layout,
|
||||
const GskGpuShaderOpClass *op_class,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuBlend blend,
|
||||
VkFormat format,
|
||||
VkRenderPass render_pass);
|
||||
|
||||
|
@ -316,6 +316,7 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
state.vk_command_buffer = self->vk_command_buffer;
|
||||
state.vk_render_pass = VK_NULL_HANDLE;
|
||||
state.vk_format = VK_FORMAT_UNDEFINED;
|
||||
state.blend = GSK_GPU_BLEND_OVER; /* should we have a BLEND_NONE? */
|
||||
state.desc = GSK_VULKAN_DESCRIPTORS (gsk_descriptors_get (&self->descriptors, 0));
|
||||
state.semaphores = &semaphores;
|
||||
|
||||
|
@ -72,6 +72,7 @@ gsk_private_sources = files([
|
||||
'gpu/gskgldescriptors.c',
|
||||
'gpu/gskglframe.c',
|
||||
'gpu/gskglimage.c',
|
||||
'gpu/gskgpublendop.c',
|
||||
'gpu/gskgpublitop.c',
|
||||
'gpu/gskgpublurop.c',
|
||||
'gpu/gskgpuborderop.c',
|
||||
|
Loading…
Reference in New Issue
Block a user