vulkan: Make the effect renderer take matrix + offset

This is in preparation for the new color matrix node.

I don't think keeping support for a separate opacity shader is worth it.
This commit is contained in:
Benjamin Otte 2016-12-31 13:24:21 +01:00
parent 0259312142
commit 1aa0f79e8b
25 changed files with 154 additions and 70 deletions

View File

@ -13,7 +13,8 @@ struct _GskVulkanEffectInstance
{
float rect[4];
float tex_rect[4];
float value;
float color_matrix[16];
float color_offset[4];
};
G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE)
@ -45,7 +46,31 @@ gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, value),
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 4,
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 8,
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 12,
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_offset),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
@ -100,7 +125,8 @@ void
gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline,
guchar *data,
const graphene_rect_t *rect,
float value)
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset)
{
GskVulkanEffectInstance *instance = (GskVulkanEffectInstance *) data;
@ -112,7 +138,8 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin
instance->tex_rect[1] = 0.0;
instance->tex_rect[2] = 1.0;
instance->tex_rect[3] = 1.0;
instance->value = value;
graphene_matrix_to_float (color_matrix, instance->color_matrix);
graphene_vec4_to_float (color_offset, instance->color_offset);
}
gsize

View File

@ -21,7 +21,8 @@ gsize gsk_vulkan_effect_pipeline_count_vertex_data (GskVulk
void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline,
guchar *data,
const graphene_rect_t *rect,
float value);
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset);
gsize gsk_vulkan_effect_pipeline_draw (GskVulkanEffectPipeline *pipeline,
VkCommandBuffer command_buffer,
gsize offset,

View File

@ -321,9 +321,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
{ "linear", gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip", gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip-rounded", gsk_vulkan_linear_gradient_pipeline_new },
{ "opacity", gsk_vulkan_effect_pipeline_new },
{ "opacity-clip", gsk_vulkan_effect_pipeline_new },
{ "opacity-clip-rounded", gsk_vulkan_effect_pipeline_new }
{ "color-matrix", gsk_vulkan_effect_pipeline_new },
{ "color-matrix-clip", gsk_vulkan_effect_pipeline_new },
{ "color-matrix-clip-rounded", gsk_vulkan_effect_pipeline_new }
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);

View File

@ -171,11 +171,11 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
case GSK_OPACITY_NODE:
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
pipeline_type = GSK_VULKAN_PIPELINE_OPACITY;
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
pipeline_type = GSK_VULKAN_PIPELINE_OPACITY_CLIP;
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP;
else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
pipeline_type = GSK_VULKAN_PIPELINE_OPACITY_CLIP_ROUNDED;
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
else
FALLBACK ("Opacity nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_OPACITY;
@ -554,11 +554,22 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
case GSK_VULKAN_OP_OPACITY:
{
graphene_matrix_t color_matrix;
graphene_vec4_t color_offset;
graphene_matrix_init_from_float (&color_matrix,
(float[16]) {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, gsk_opacity_node_get_opacity (op->render.node)
});
graphene_vec4_init (&color_offset, 0.0, 0.0, 0.0, 0.0);
op->render.vertex_offset = offset + n_bytes;
gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline),
data + n_bytes + offset,
&op->render.node->bounds,
gsk_opacity_node_get_opacity (op->render.node));
&color_matrix,
&color_offset);
n_bytes += op->render.vertex_count;
}
break;

View File

@ -17,9 +17,9 @@ typedef enum {
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_OPACITY,
GSK_VULKAN_PIPELINE_OPACITY_CLIP,
GSK_VULKAN_PIPELINE_OPACITY_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_COLOR_MATRIX,
GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP,
GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED,
/* add more */
GSK_VULKAN_N_PIPELINES
} GskVulkanPipelineType;

View File

@ -7,9 +7,10 @@ struct RoundedRect {
layout(location = 0) in vec2 inPos;
layout(location = 1) in vec2 inTexCoord;
layout(location = 2) in flat float inOpacity;
layout(location = 3) in flat vec4 inClipBounds;
layout(location = 4) in flat vec4 inClipWidths;
layout(location = 2) in flat vec4 inClipBounds;
layout(location = 3) in flat vec4 inClipWidths;
layout(location = 4) in flat mat4 inColorMatrix;
layout(location = 8) in flat vec4 inColorOffset;
layout(set = 0, binding = 0) uniform sampler2D inTexture;
@ -51,14 +52,25 @@ float clip(vec2 pos, RoundedRect r) {
}
vec4
opacity (vec4 color, float value)
color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
{
return color * value;
/* unpremultiply */
if (color.a != 0.0)
color.rgb /= color.a;
color = color_matrix * color + color_offset;
color = clamp(color, 0.0, 1.0);
/* premultiply */
if (color.a != 0.0)
color.rgb *= color.a;
return color;
}
void main()
{
RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
color = opacity (texture (inTexture, inTexCoord), inOpacity) * clip (inPos, r);
color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset) * clip (inPos, r);
}

View File

@ -2,7 +2,8 @@
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inTexRect;
layout(location = 2) in float inOpacity;
layout(location = 2) in mat4 inColorMatrix;
layout(location = 6) in vec4 inColorOffset;
layout(push_constant) uniform PushConstants {
mat4 mvp;
@ -13,9 +14,10 @@ layout(push_constant) uniform PushConstants {
layout(location = 0) out vec2 outPos;
layout(location = 1) out vec2 outTexCoord;
layout(location = 2) out flat float outOpacity;
layout(location = 3) out flat vec4 outClipBounds;
layout(location = 4) out flat vec4 outClipWidths;
layout(location = 2) out flat vec4 outClipBounds;
layout(location = 3) out flat vec4 outClipWidths;
layout(location = 4) out flat mat4 outColorMatrix;
layout(location = 8) out flat vec4 outColorOffset;
out gl_PerVertex {
vec4 gl_Position;
@ -52,5 +54,6 @@ void main() {
texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
inTexRect.zw * texrect.zw);
outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
outOpacity = inOpacity;
outColorMatrix = inColorMatrix;
outColorOffset = inColorOffset;
}

View File

@ -0,0 +1,31 @@
#version 420 core
layout(location = 0) in vec2 inTexCoord;
layout(location = 1) in flat mat4 inColorMatrix;
layout(location = 5) in flat vec4 inColorOffset;
layout(set = 0, binding = 0) uniform sampler2D inTexture;
layout(location = 0) out vec4 color;
vec4
color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
{
/* unpremultiply */
if (color.a != 0.0)
color.rgb /= color.a;
color = color_matrix * color + color_offset;
color = clamp(color, 0.0, 1.0);
/* premultiply */
if (color.a != 0.0)
color.rgb *= color.a;
return color;
}
void main()
{
color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset);
}

Binary file not shown.

View File

@ -2,7 +2,8 @@
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inTexRect;
layout(location = 2) in float inOpacity;
layout(location = 2) in mat4 inColorMatrix;
layout(location = 6) in vec4 inColorOffset;
layout(push_constant) uniform PushConstants {
mat4 mvp;
@ -12,7 +13,8 @@ layout(push_constant) uniform PushConstants {
} push;
layout(location = 0) out vec2 outTexCoord;
layout(location = 1) out flat float outOpacity;
layout(location = 1) out flat mat4 outColorMatrix;
layout(location = 5) out flat vec4 outColorOffset;
out gl_PerVertex {
vec4 gl_Position;
@ -45,5 +47,6 @@ void main() {
texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
inTexRect.zw * texrect.zw);
outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
outOpacity = inOpacity;
outColorMatrix = inColorMatrix;
outColorOffset = inColorOffset;
}

Binary file not shown.

View File

@ -0,0 +1,31 @@
#version 420 core
layout(location = 0) in vec2 inTexCoord;
layout(location = 1) in flat mat4 inColorMatrix;
layout(location = 5) in flat vec4 inColorOffset;
layout(set = 0, binding = 0) uniform sampler2D inTexture;
layout(location = 0) out vec4 color;
vec4
color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
{
/* unpremultiply */
if (color.a != 0.0)
color.rgb /= color.a;
color = color_matrix * color + color_offset;
color = clamp(color, 0.0, 1.0);
/* premultiply */
if (color.a != 0.0)
color.rgb *= color.a;
return color;
}
void main()
{
color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset);
}

Binary file not shown.

View File

@ -2,7 +2,8 @@
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inTexRect;
layout(location = 2) in float inOpacity;
layout(location = 2) in mat4 inColorMatrix;
layout(location = 6) in vec4 inColorOffset;
layout(push_constant) uniform PushConstants {
mat4 mvp;
@ -12,7 +13,8 @@ layout(push_constant) uniform PushConstants {
} push;
layout(location = 0) out vec2 outTexCoord;
layout(location = 1) out flat float outOpacity;
layout(location = 1) out flat mat4 outColorMatrix;
layout(location = 5) out flat vec4 outColorOffset;
out gl_PerVertex {
vec4 gl_Position;
@ -30,5 +32,6 @@ void main() {
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outTexCoord = inTexRect.xy + inTexRect.zw * offsets[gl_VertexIndex];
outOpacity = inOpacity;
outColorMatrix = inColorMatrix;
outColorOffset = inColorOffset;
}

Binary file not shown.

View File

@ -1,19 +0,0 @@
#version 420 core
layout(location = 0) in vec2 inTexCoord;
layout(location = 1) in flat float inOpacity;
layout(set = 0, binding = 0) uniform sampler2D inTexture;
layout(location = 0) out vec4 color;
vec4
opacity (vec4 color, float value)
{
return color * value;
}
void main()
{
color = opacity (texture (inTexture, inTexCoord), inOpacity);
}

View File

@ -1,19 +0,0 @@
#version 420 core
layout(location = 0) in vec2 inTexCoord;
layout(location = 1) in flat float inOpacity;
layout(set = 0, binding = 0) uniform sampler2D inTexture;
layout(location = 0) out vec4 color;
vec4
opacity (vec4 color, float value)
{
return color * value;
}
void main()
{
color = opacity (texture (inTexture, inTexCoord), inOpacity);
}