--- /dev/null
+#include "config.h"
+
+#include "gskvulkanconvertopprivate.h"
+
+#include "gskvulkanprivate.h"
+#include "gskvulkanshaderopprivate.h"
+
+#include "vulkan/resources/convert.vert.h"
+
+typedef struct _GskVulkanConvertOp GskVulkanConvertOp;
+
+struct _GskVulkanConvertOp
+{
+ GskVulkanShaderOp op;
+
+ graphene_rect_t rect;
+ graphene_rect_t tex_rect;
+
+ guint32 image_descriptor;
+};
+
+static void
+gsk_vulkan_convert_op_print (GskVulkanOp *op,
+ GString *string,
+ guint indent)
+{
+ GskVulkanConvertOp *self = (GskVulkanConvertOp *) op;
+ GskVulkanShaderOp *shader = (GskVulkanShaderOp *) op;
+
+ print_indent (string, indent);
+ print_rect (string, &self->rect);
+ g_string_append (string, "convert ");
+ print_image (string, shader->images[0]);
+ print_newline (string);
+}
+
+static void
+gsk_vulkan_convert_op_collect_vertex_data (GskVulkanOp *op,
+ guchar *data)
+{
+ GskVulkanConvertOp *self = (GskVulkanConvertOp *) op;
+ GskVulkanConvertInstance *instance = (GskVulkanConvertInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
+ GskVulkanShaderOp *shader = (GskVulkanShaderOp *) op;
+
+ instance->rect[0] = self->rect.origin.x;
+ instance->rect[1] = self->rect.origin.y;
+ instance->rect[2] = self->rect.size.width;
+ instance->rect[3] = self->rect.size.height;
+ instance->tex_rect[0] = self->tex_rect.origin.x;
+ instance->tex_rect[1] = self->tex_rect.origin.y;
+ instance->tex_rect[2] = self->tex_rect.size.width;
+ instance->tex_rect[3] = self->tex_rect.size.height;
+ instance->tex_id = self->image_descriptor;
+ instance->postprocess = gsk_vulkan_image_get_postprocess (shader->images[0]);
+}
+
+static void
+gsk_vulkan_convert_op_reserve_descriptor_sets (GskVulkanOp *op,
+ GskVulkanRender *render)
+{
+ GskVulkanConvertOp *self = (GskVulkanConvertOp *) op;
+ GskVulkanShaderOp *shader = (GskVulkanShaderOp *) op;
+
+ self->image_descriptor = gsk_vulkan_render_get_image_descriptor (render, shader->images[0], GSK_VULKAN_SAMPLER_NEAREST);
+}
+
+static const GskVulkanShaderOpClass GSK_VULKAN_CONVERT_OP_CLASS = {
+ {
+ GSK_VULKAN_OP_SIZE (GskVulkanConvertOp),
+ GSK_VULKAN_STAGE_SHADER,
+ gsk_vulkan_shader_op_finish,
+ gsk_vulkan_convert_op_print,
+ gsk_vulkan_shader_op_count_vertex_data,
+ gsk_vulkan_convert_op_collect_vertex_data,
+ gsk_vulkan_convert_op_reserve_descriptor_sets,
+ gsk_vulkan_shader_op_command
+ },
+ "convert",
+ 1,
+ &gsk_vulkan_convert_info,
+};
+
+void
+gsk_vulkan_convert_op (GskVulkanRender *render,
+ GskVulkanShaderClip clip,
+ GskVulkanImage *image,
+ const graphene_rect_t *rect,
+ const graphene_point_t *offset,
+ const graphene_rect_t *tex_rect)
+{
+ GskVulkanConvertOp *self;
+
+ self = (GskVulkanConvertOp *) gsk_vulkan_shader_op_alloc (render,
+ &GSK_VULKAN_CONVERT_OP_CLASS,
+ clip,
+ &image);
+
+ graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
+ gsk_vulkan_normalize_tex_coords (&self->tex_rect, rect, tex_rect);
+}
VkImage vk_image;
VkImageView vk_image_view;
VkFramebuffer vk_framebuffer;
+ GskVulkanImagePostprocess postprocess;
VkPipelineStageFlags vk_pipeline_stage;
VkImageLayout vk_image_layout;
{
VkFormat format;
VkComponentMapping components;
+ GskVulkanImagePostprocess postprocess;
};
static const GskMemoryFormatInfo *
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_B8G8R8A8_UNORM, DEFAULT_SWIZZLE },
- { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(B, G, R, A) },
+ { VK_FORMAT_B8G8R8A8_UNORM, DEFAULT_SWIZZLE, 0 },
+ { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(B, G, R, A), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(G, B, A, R) },
+ { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(G, B, A, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8G8B8A8_UNORM, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R8G8B8A8_UNORM, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_B8G8R8A8,
- GDK_MEMORY_A8R8G8B8,
- GDK_MEMORY_R8G8B8A8,
- GDK_MEMORY_A8B8G8R8,
-#endif
+ case GDK_MEMORY_B8G8R8A8:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_B8G8R8A8_UNORM, DEFAULT_SWIZZLE, GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(B, G, R, A), GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
+
+ case GDK_MEMORY_A8R8G8B8:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(G, B, A, R), GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
+
+ case GDK_MEMORY_R8G8B8A8:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R8G8B8A8_UNORM, DEFAULT_SWIZZLE, GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
+
+ case GDK_MEMORY_A8B8G8R8:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(A, B, G, R), GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
case GDK_MEMORY_R8G8B8:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8G8B8_UNORM, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R8G8B8_UNORM, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_B8G8R8:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_B8G8R8_UNORM, DEFAULT_SWIZZLE },
- { VK_FORMAT_R8G8B8_UNORM, SWIZZLE(B, G, R, A) },
+ { VK_FORMAT_B8G8R8_UNORM, DEFAULT_SWIZZLE, 0 },
+ { VK_FORMAT_R8G8B8_UNORM, SWIZZLE(B, G, R, A), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_R16G16B16:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16G16B16_UNORM, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R16G16B16_UNORM, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16G16B16A16_UNORM, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R16G16B16A16_UNORM, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_R16G16B16A16,
-#endif
+ case GDK_MEMORY_R16G16B16A16:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R16G16B16A16_UNORM, DEFAULT_SWIZZLE, GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
case GDK_MEMORY_R16G16B16_FLOAT:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16G16B16_SFLOAT, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R16G16B16_SFLOAT, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16G16B16A16_SFLOAT, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R16G16B16A16_SFLOAT, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_R16G16B16A16_FLOAT,
-#endif
+ case GDK_MEMORY_R16G16B16A16_FLOAT:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R16G16B16A16_SFLOAT, DEFAULT_SWIZZLE, GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
case GDK_MEMORY_R32G32B32_FLOAT:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R32G32B32_SFLOAT, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R32G32B32_SFLOAT, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R32G32B32A32_SFLOAT, DEFAULT_SWIZZLE },
+ { VK_FORMAT_R32G32B32A32_SFLOAT, DEFAULT_SWIZZLE, 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_R32G32B32A32_FLOAT,
-#endif
+ case GDK_MEMORY_R32G32B32A32_FLOAT:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R32G32B32A32_SFLOAT, DEFAULT_SWIZZLE, GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
case GDK_MEMORY_G8A8_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8G8_UNORM, SWIZZLE (R, R, R, G) },
+ { VK_FORMAT_R8G8_UNORM, SWIZZLE (R, R, R, G), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_G8A8,
-#endif
+ case GDK_MEMORY_G8A8:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R8G8_UNORM, SWIZZLE (R, R, R, G), GSK_VULKAN_IMAGE_PREMULTIPLY },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
case GDK_MEMORY_G8:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, ONE) },
+ { VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, ONE), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
case GDK_MEMORY_G16A16_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16G16_UNORM, SWIZZLE (R, R, R, G) },
+ { VK_FORMAT_R16G16_UNORM, SWIZZLE (R, R, R, G), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
-#if 0
- GDK_MEMORY_G16A16
-#endif
-
- case GDK_MEMORY_G16:
+ case GDK_MEMORY_G16A16:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, ONE) },
+ { VK_FORMAT_R16G16_UNORM, SWIZZLE (R, R, R, G), GSK_VULKAN_IMAGE_PREMULTIPLY },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
- case GDK_MEMORY_A8:
+ case GDK_MEMORY_G16:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, R) },
+ { VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, ONE), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
- case GDK_MEMORY_A16:
+ case GDK_MEMORY_A8:
{
static const GskMemoryFormatInfo info[] = {
- { VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, R) },
+ { VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
- case GDK_MEMORY_B8G8R8A8:
- case GDK_MEMORY_A8R8G8B8:
- case GDK_MEMORY_R8G8B8A8:
- case GDK_MEMORY_A8B8G8R8:
- case GDK_MEMORY_R16G16B16A16:
- case GDK_MEMORY_R16G16B16A16_FLOAT:
- case GDK_MEMORY_R32G32B32A32_FLOAT:
- case GDK_MEMORY_G8A8:
- case GDK_MEMORY_G16A16:
+ case GDK_MEMORY_A16:
{
static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
static GskVulkanImage *
-gsk_vulkan_image_new (GdkVulkanContext *context,
- GdkMemoryFormat format,
- gsize width,
- gsize height,
- VkImageTiling tiling,
- VkImageUsageFlags usage,
- VkPipelineStageFlags stage,
- VkImageLayout layout,
- VkAccessFlags access,
- VkMemoryPropertyFlags memory)
+gsk_vulkan_image_new (GdkVulkanContext *context,
+ GdkMemoryFormat format,
+ gsize width,
+ gsize height,
+ GskVulkanImagePostprocess allowed_postprocess,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkPipelineStageFlags stage,
+ VkImageLayout layout,
+ VkAccessFlags access,
+ VkMemoryPropertyFlags memory)
{
VkMemoryRequirements requirements;
GskVulkanImage *self;
vk_format->format != VK_FORMAT_UNDEFINED;
vk_format++)
{
+ if (vk_format->postprocess & ~allowed_postprocess)
+ continue;
+
if (gsk_vulkan_context_supports_format (context, vk_format->format))
break;
}
self->vulkan = g_object_ref (context);
self->format = format;
self->vk_format = vk_format->format;
+ self->postprocess = vk_format->postprocess;
self->width = width;
self->height = height;
self->vk_usage = usage;
format,
width,
height,
+ -1,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT,
GDK_MEMORY_DEFAULT,
width,
height,
+ 0,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
preferred_format,
width,
height,
+ 0,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
return self->height;
}
+GskVulkanImagePostprocess
+gsk_vulkan_image_get_postprocess (GskVulkanImage *self)
+{
+ return self->postprocess;
+}
+
VkImage
gsk_vulkan_image_get_vk_image (GskVulkanImage *self)
{
#include "gskvulkanclipprivate.h"
#include "gskvulkancolormatrixopprivate.h"
#include "gskvulkancoloropprivate.h"
+#include "gskvulkanconvertopprivate.h"
#include "gskvulkancrossfadeopprivate.h"
#include "gskvulkanglyphopprivate.h"
#include "gskvulkaninsetshadowopprivate.h"
&& int_rect->height == rect->size.height * scale_y;
}
+static GskVulkanImage *
+gsk_vulkan_render_pass_upload_texture (GskVulkanRender *render,
+ GdkTexture *texture)
+{
+ GskVulkanImage *image, *better_image;
+ int width, height;
+ GskVulkanImagePostprocess postproc;
+ graphene_matrix_t projection;
+ graphene_vec2_t scale;
+
+ image = gsk_vulkan_upload_texture_op (render, texture);
+ postproc = gsk_vulkan_image_get_postprocess (image);
+ if (postproc == 0)
+ return image;
+
+ width = gdk_texture_get_width (texture);
+ height = gdk_texture_get_height (texture);
+ better_image = gsk_vulkan_image_new_for_offscreen (gsk_vulkan_render_get_context (render),
+ gdk_texture_get_format (texture),
+ width, height);
+ gsk_vulkan_render_pass_begin_op (render,
+ g_object_ref (better_image),
+ &(cairo_rectangle_int_t) { 0, 0, width, height },
+ &GRAPHENE_SIZE_INIT(width, height),
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ gsk_vulkan_scissor_op (render, &(cairo_rectangle_int_t) { 0, 0, width, height });
+ graphene_matrix_init_ortho (&projection,
+ 0, width,
+ 0, height,
+ 2 * ORTHO_NEAR_PLANE - ORTHO_FAR_PLANE,
+ ORTHO_FAR_PLANE);
+ graphene_vec2_init (&scale, 1.0, 1.0);
+ gsk_vulkan_push_constants_op (render, &scale, &projection, &GSK_ROUNDED_RECT_INIT(0, 0, width, height));
+ gsk_vulkan_convert_op (render,
+ GSK_VULKAN_SHADER_CLIP_NONE,
+ image,
+ &GRAPHENE_RECT_INIT (0, 0, width, height),
+ &GRAPHENE_POINT_INIT (0, 0),
+ &GRAPHENE_RECT_INIT (0, 0, width, height));
+ gsk_vulkan_render_pass_end_op (render,
+ better_image,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ return better_image;
+}
+
static GskVulkanImage *
gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass *self,
GskVulkanRender *render,
result = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (result == NULL)
{
- result = gsk_vulkan_upload_texture_op (render, texture);
+ result = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, result);
}
image = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (image == NULL)
{
- image = gsk_vulkan_upload_texture_op (render, texture);
+ image = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, image);
}
image = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (image == NULL)
{
- image = gsk_vulkan_upload_texture_op (render, texture);
+ image = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, image);
}