gpu: Pass color states as specialization constant

This adds a GdkColorStates that encodes 2 of the default GdkColorStates
and wether their values are premultiplied or not.

Neither do the shaders do anything with this information yet, nor do the
shaders do anything with it yet, this is just the plumbing.
This commit is contained in:
Benjamin Otte 2024-07-03 07:41:26 +02:00
parent d85ec2cbb4
commit 6c5ae48a05
27 changed files with 131 additions and 18 deletions

View File

@ -34,6 +34,7 @@ typedef struct _GLProgramKey GLProgramKey;
struct _GLProgramKey
{
const GskGpuShaderOpClass *op_class;
GskGpuColorStates color_states;
guint32 variation;
GskGpuShaderClip clip;
guint n_external_textures;
@ -49,7 +50,8 @@ gl_program_key_hash (gconstpointer data)
return GPOINTER_TO_UINT (key->op_class) ^
key->clip ^
(key->variation << 2) ^
(key->n_external_textures << 24);
(key->n_external_textures << 24) ^
key->color_states;
}
static gboolean
@ -60,6 +62,7 @@ gl_program_key_equal (gconstpointer a,
const GLProgramKey *keyb = b;
return keya->op_class == keyb->op_class &&
keya->color_states == keyb->color_states &&
keya->variation == keyb->variation &&
keya->clip == keyb->clip &&
keya->n_external_textures == keyb->n_external_textures;
@ -371,13 +374,14 @@ print_shader_info (const char *prefix,
}
static GLuint
gsk_gl_device_load_shader (GskGLDevice *self,
const char *program_name,
GLenum shader_type,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures,
GError **error)
gsk_gl_device_load_shader (GskGLDevice *self,
const char *program_name,
GLenum shader_type,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures,
GError **error)
{
GString *preamble;
char *resource_name;
@ -421,6 +425,7 @@ gsk_gl_device_load_shader (GskGLDevice *self,
return 0;
}
g_string_append_printf (preamble, "#define GSK_COLOR_STATES %uu\n", color_states);
g_string_append_printf (preamble, "#define GSK_VARIATION %uu\n", variation);
switch (clip)
@ -474,6 +479,7 @@ gsk_gl_device_load_shader (GskGLDevice *self,
static GLuint
gsk_gl_device_load_program (GskGLDevice *self,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures,
@ -483,11 +489,11 @@ gsk_gl_device_load_program (GskGLDevice *self,
GLuint vertex_shader_id, fragment_shader_id, program_id;
GLint link_status;
vertex_shader_id = gsk_gl_device_load_shader (self, op_class->shader_name, GL_VERTEX_SHADER, variation, clip, n_external_textures, error);
vertex_shader_id = gsk_gl_device_load_shader (self, op_class->shader_name, GL_VERTEX_SHADER, color_states, variation, clip, n_external_textures, error);
if (vertex_shader_id == 0)
return 0;
fragment_shader_id = gsk_gl_device_load_shader (self, op_class->shader_name, GL_FRAGMENT_SHADER, variation, clip, n_external_textures, error);
fragment_shader_id = gsk_gl_device_load_shader (self, op_class->shader_name, GL_FRAGMENT_SHADER, color_states, variation, clip, n_external_textures, error);
if (fragment_shader_id == 0)
return 0;
@ -545,6 +551,7 @@ gsk_gl_device_load_program (GskGLDevice *self,
void
gsk_gl_device_use_program (GskGLDevice *self,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures)
@ -553,6 +560,7 @@ gsk_gl_device_use_program (GskGLDevice *self,
GLuint program_id;
GLProgramKey key = {
.op_class = op_class,
.color_states = color_states,
.variation = variation,
.clip = clip,
.n_external_textures = n_external_textures
@ -566,7 +574,7 @@ gsk_gl_device_use_program (GskGLDevice *self,
return;
}
program_id = gsk_gl_device_load_program (self, op_class, variation, clip, n_external_textures, &error);
program_id = gsk_gl_device_load_program (self, op_class, color_states, variation, clip, n_external_textures, &error);
if (program_id == 0)
{
g_critical ("Failed to load shader program: %s", error->message);

View File

@ -13,6 +13,7 @@ GskGpuDevice * gsk_gl_device_get_for_display (GdkDisp
void gsk_gl_device_use_program (GskGLDevice *self,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures);

View File

@ -245,6 +245,7 @@ gsk_gl_frame_init (GskGLFrame *self)
void
gsk_gl_frame_use_program (GskGLFrame *self,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures)
@ -253,6 +254,7 @@ gsk_gl_frame_use_program (GskGLFrame *self,
gsk_gl_device_use_program (GSK_GL_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self))),
op_class,
color_states,
variation,
clip,
n_external_textures);

View File

@ -10,6 +10,7 @@ G_DECLARE_FINAL_TYPE (GskGLFrame, gsk_gl_frame, GSK, GL_FRAME, GskGpuFrame)
void gsk_gl_frame_use_program (GskGLFrame *self,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
guint n_external_textures);

View File

@ -68,6 +68,7 @@ gsk_gpu_blend_mode_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BLEND_MODE_OP_CLASS,
DEFAULT_COLOR_STATES,
blend_mode,
clip,
desc,

View File

@ -68,6 +68,7 @@ gsk_gpu_blur_op_full (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BLUR_OP_CLASS,
DEFAULT_COLOR_STATES,
variation,
clip,
desc,

View File

@ -107,6 +107,7 @@ gsk_gpu_border_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BORDER_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
NULL,

View File

@ -91,6 +91,7 @@ gsk_gpu_box_shadow_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BOX_SHADOW_OP_CLASS,
DEFAULT_COLOR_STATES,
inset ? VARIATION_INSET : 0,
clip,
NULL,

View File

@ -62,6 +62,7 @@ gsk_gpu_colorize_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_COLORIZE_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
descriptors,

View File

@ -62,6 +62,7 @@ gsk_gpu_color_matrix_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_COLOR_MATRIX_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
desc,

View File

@ -59,6 +59,7 @@ gsk_gpu_color_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_COLOR_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
NULL,

View File

@ -0,0 +1,52 @@
#pragma once
#include "gskgputypesprivate.h"
#include "gdk/gdkcolorstateprivate.h"
#define COLOR_SPACE_OUTPUT_PREMULTIPLIED (1u << 2)
#define COLOR_SPACE_ALT_PREMULTIPLIED (1u << 3)
#define COLOR_SPACE_OUTPUT_SHIFT 8u
#define COLOR_SPACE_ALT_SHIFT 16u
#define COLOR_SPACE_COLOR_STATE_MASK 0xFFu
static inline GskGpuColorStates
gsk_gpu_color_states_create (GdkColorState *output_color_state,
gboolean output_is_premultiplied,
GdkColorState *alt_color_state,
gboolean alt_is_premultiplied)
{
g_assert (GDK_IS_DEFAULT_COLOR_STATE (output_color_state));
g_assert (GDK_IS_DEFAULT_COLOR_STATE (alt_color_state));
return (GDK_DEFAULT_COLOR_STATE_ID (output_color_state) << COLOR_SPACE_OUTPUT_SHIFT) |
(output_is_premultiplied ? COLOR_SPACE_OUTPUT_PREMULTIPLIED : 0) |
(GDK_DEFAULT_COLOR_STATE_ID (alt_color_state) << COLOR_SPACE_ALT_SHIFT) |
(alt_is_premultiplied ? COLOR_SPACE_ALT_PREMULTIPLIED : 0);
}
static inline GdkColorState *
gsk_gpu_color_states_get_output (GskGpuColorStates self)
{
return ((GdkColorState *) &gdk_default_color_states[(self >> COLOR_SPACE_OUTPUT_SHIFT) & COLOR_SPACE_COLOR_STATE_MASK]);
}
static inline gboolean
gsk_gpu_color_states_is_output_premultiplied (GskGpuColorStates self)
{
return !!(self & COLOR_SPACE_OUTPUT_PREMULTIPLIED);
}
static inline GdkColorState *
gsk_gpu_color_states_get_alt (GskGpuColorStates self)
{
return ((GdkColorState *) &gdk_default_color_states[(self >> COLOR_SPACE_ALT_SHIFT) & COLOR_SPACE_COLOR_STATE_MASK]);
}
static inline gboolean
gsk_gpu_color_states_is_alt_premultiplied (GskGpuColorStates self)
{
return !!(self & COLOR_SPACE_ALT_PREMULTIPLIED);
}
#define DEFAULT_COLOR_STATES (gsk_gpu_color_states_create (GDK_COLOR_STATE_SRGB, TRUE, GDK_COLOR_STATE_SRGB, TRUE))

View File

@ -65,6 +65,7 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_CONIC_GRADIENT_OP_CLASS,
DEFAULT_COLOR_STATES,
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,
NULL,

View File

@ -133,6 +133,7 @@ gsk_gpu_convert_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_CONVERT_OP_CLASS,
DEFAULT_COLOR_STATES,
variation,
clip,
desc,

View File

@ -66,6 +66,7 @@ gsk_gpu_cross_fade_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_CROSS_FADE_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
desc,

View File

@ -69,6 +69,7 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_LINEAR_GRADIENT_OP_CLASS,
DEFAULT_COLOR_STATES,
(repeating ? VARIATION_REPEATING : 0) |
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,

View File

@ -67,6 +67,7 @@ gsk_gpu_mask_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_MASK_OP_CLASS,
DEFAULT_COLOR_STATES,
mask_mode,
clip,
desc,

View File

@ -25,6 +25,7 @@ struct _GskGLCommandState
gsize flip_y;
struct {
const GskGpuOpClass *op_class;
GskGpuColorStates color_states;
guint32 variation;
GskGpuShaderClip clip;
gsize n_external;

View File

@ -71,6 +71,7 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_RADIAL_GRADIENT_OP_CLASS,
DEFAULT_COLOR_STATES,
(repeating ? VARIATION_REPEATING : 0) |
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
clip,

View File

@ -59,6 +59,7 @@ gsk_gpu_rounded_color_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_ROUNDED_COLOR_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
NULL,

View File

@ -93,6 +93,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
if (next->op_class != op->op_class ||
next_shader->desc != self->desc ||
next_shader->color_states != self->color_states ||
next_shader->variation != self->variation ||
next_shader->clip != self->clip ||
next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size)
@ -106,6 +107,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
gsk_vulkan_device_get_vk_pipeline (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
gsk_vulkan_descriptors_get_pipeline_layout (state->desc),
shader_op_class,
self->color_states,
self->variation,
self->clip,
state->blend,
@ -150,16 +152,19 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op,
n_external = 0;
if (state->current_program.op_class != op->op_class ||
state->current_program.color_states != self->color_states ||
state->current_program.variation != self->variation ||
state->current_program.clip != self->clip ||
state->current_program.n_external != n_external)
{
state->current_program.op_class = op->op_class;
state->current_program.color_states = self->color_states;
state->current_program.variation = self->variation;
state->current_program.clip = self->clip;
state->current_program.n_external = n_external;
gsk_gl_frame_use_program (GSK_GL_FRAME (frame),
shader_op_class,
self->color_states,
self->variation,
self->clip,
n_external);
@ -183,6 +188,7 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op,
if (next->op_class != op->op_class ||
next_shader->desc != self->desc ||
next_shader->color_states != self->color_states ||
next_shader->variation != self->variation ||
next_shader->clip != self->clip ||
next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size)
@ -227,6 +233,7 @@ gsk_gpu_shader_op_gl_command (GskGpuOp *op,
void
gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
GskGpuDescriptors *desc,
@ -244,6 +251,7 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
if (last &&
last->op_class == (const GskGpuOpClass *) op_class &&
last_shader->desc == desc &&
last_shader->color_states == color_states &&
last_shader->variation == variation &&
last_shader->clip == clip &&
last_shader->vertex_offset + last_shader->n_ops * op_class->vertex_size == vertex_offset)
@ -255,6 +263,7 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
GskGpuShaderOp *self;
self = (GskGpuShaderOp *) gsk_gpu_op_alloc (frame, &op_class->parent_class);
self->color_states = color_states;
self->variation = variation;
self->clip = clip;
self->vertex_offset = vertex_offset;

View File

@ -3,6 +3,7 @@
#include "gskgpuopprivate.h"
#include "gskgputypesprivate.h"
#include "gskgpucolorstatesprivate.h"
G_BEGIN_DECLS
@ -11,6 +12,7 @@ struct _GskGpuShaderOp
GskGpuOp parent_op;
GskGpuDescriptors *desc;
GskGpuColorStates color_states;
guint32 variation;
GskGpuShaderClip clip;
gsize vertex_offset;
@ -35,6 +37,7 @@ struct _GskGpuShaderOpClass
void gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
GskGpuDescriptors *desc,

View File

@ -60,6 +60,7 @@ gsk_gpu_texture_op (GskGpuFrame *frame,
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_TEXTURE_OP_CLASS,
DEFAULT_COLOR_STATES,
0,
clip,
desc,

View File

@ -10,6 +10,7 @@
typedef struct _GskGLDescriptors GskGLDescriptors;
typedef struct _GskGpuBuffer GskGpuBuffer;
typedef struct _GskGpuCache GskGpuCache;
typedef guint32 GskGpuColorStates;
typedef struct _GskGpuDescriptors GskGpuDescriptors;
typedef struct _GskGpuDevice GskGpuDevice;
typedef struct _GskGpuFrame GskGpuFrame;

View File

@ -77,6 +77,7 @@ struct _ConversionCacheEntry
struct _PipelineCacheKey
{
const GskGpuShaderOpClass *op_class;
GskGpuColorStates color_states;
guint32 variation;
GskGpuShaderClip clip;
GskGpuBlend blend;
@ -905,6 +906,7 @@ struct _GskVulkanShaderSpecialization
guint32 n_immutable_samplers;
guint32 n_samplers;
guint32 n_buffers;
guint32 color_states;
guint32 variation;
};
@ -954,6 +956,7 @@ VkPipeline
gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
GskVulkanPipelineLayout *layout,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
GskGpuBlend blend,
@ -972,6 +975,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
cache_key = (PipelineCacheKey) {
.op_class = op_class,
.color_states = color_states,
.variation = variation,
.clip = clip,
.blend = blend,
@ -1011,8 +1015,8 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
.module = gdk_display_get_vk_shader_module (display, vertex_shader_name),
.pName = "main",
.pSpecializationInfo = &(VkSpecializationInfo) {
.mapEntryCount = 5,
.pMapEntries = (VkSpecializationMapEntry[5]) {
.mapEntryCount = 6,
.pMapEntries = (VkSpecializationMapEntry[6]) {
{
.constantID = 0,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, clip),
@ -1035,6 +1039,11 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
},
{
.constantID = 4,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, color_states),
.size = sizeof (guint32),
},
{
.constantID = 5,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, variation),
.size = sizeof (guint32),
},
@ -1045,6 +1054,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
.n_immutable_samplers = MAX (1, layout->setup.n_immutable_samplers),
.n_samplers = layout->setup.n_samplers - MAX (3 * layout->setup.n_immutable_samplers, 1),
.n_buffers = layout->setup.n_buffers,
.color_states = color_states,
.variation = variation,
},
},
@ -1055,8 +1065,8 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
.module = gdk_display_get_vk_shader_module (display, fragment_shader_name),
.pName = "main",
.pSpecializationInfo = &(VkSpecializationInfo) {
.mapEntryCount = 5,
.pMapEntries = (VkSpecializationMapEntry[5]) {
.mapEntryCount = 6,
.pMapEntries = (VkSpecializationMapEntry[6]) {
{
.constantID = 0,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, clip),
@ -1079,6 +1089,11 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
},
{
.constantID = 4,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, color_states),
.size = sizeof (guint32),
},
{
.constantID = 5,
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, variation),
.size = sizeof (guint32),
},
@ -1089,6 +1104,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
.n_immutable_samplers = MAX (1, layout->setup.n_immutable_samplers),
.n_samplers = layout->setup.n_samplers - MAX (3 * layout->setup.n_immutable_samplers, 1),
.n_buffers = layout->setup.n_buffers,
.color_states = color_states,
.variation = variation,
},
},
@ -1146,18 +1162,20 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
&pipeline);
gdk_profiler_end_markf (begin_time,
"Create Vulkan pipeline", "%s version=%s variation=%u clip=%s blend=%s format=%u",
"Create Vulkan pipeline", "%s version=%s color states=%u variation=%u clip=%s blend=%s format=%u",
op_class->shader_name,
version_string + 1,
color_states,
variation,
clip_name[clip],
blend_name[blend],
format);
GSK_DEBUG (SHADERS,
"Create Vulkan pipeline (%s %s, %u/%s/%s/%u) for layout (%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT ")",
"Create Vulkan pipeline (%s %s, %u/%u/%s/%s/%u) for layout (%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT ")",
op_class->shader_name,
version_string + 1,
color_states,
variation,
clip_name[clip],
blend_name[blend],

View File

@ -73,6 +73,7 @@ VkRenderPass gsk_vulkan_device_get_vk_render_pass (GskVulk
VkPipeline gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
GskVulkanPipelineLayout*layout,
const GskGpuShaderOpClass *op_class,
GskGpuColorStates color_states,
guint32 variation,
GskGpuShaderClip clip,
GskGpuBlend blend,

View File

@ -14,7 +14,8 @@ layout(constant_id=0) const uint GSK_SHADER_CLIP = GSK_GPU_SHADER_CLIP_NONE;
layout(constant_id=1) const uint GSK_N_IMMUTABLE_SAMPLERS = 32;
layout(constant_id=2) const uint GSK_N_SAMPLERS = 32;
layout(constant_id=3) const uint GSK_N_BUFFERS = 32;
layout(constant_id=4) const uint GSK_VARIATION = 0;
layout(constant_id=4) const uint GSK_COLOR_STATES = 0;
layout(constant_id=5) const uint GSK_VARIATION = 0;
#define GSK_GLOBAL_MVP push.mvp
#define GSK_GLOBAL_CLIP push.clip