Merge branch 'wip/otte/vulkan-for-main' into 'main'

vulkan: Various smallish things

See merge request GNOME/gtk!6193
This commit is contained in:
Benjamin Otte
2023-07-19 19:51:57 +00:00
96 changed files with 613 additions and 273 deletions

View File

@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
workflow:
rules:

View File

@@ -32,6 +32,7 @@ RUN dnf -y install \
glib2-static \
glibc-devel \
glibc-headers \
glslc \
gnupg2 \
gobject-introspection-devel \
graphene-devel \

View File

@@ -32,7 +32,8 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject
mingw-w64-$MSYS2_ARCH-python-gobject \
mingw-w64-$MSYS2_ARCH-shaderc
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"

View File

@@ -700,6 +700,26 @@ gdk_memory_convert (guchar *dest_data,
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
g_assert (src_format < GDK_MEMORY_N_FORMATS);
if (src_format == dest_format)
{
gsize bytes_per_row = src_desc->bytes_per_pixel * width;
if (bytes_per_row == src_stride && bytes_per_row == dest_stride)
{
memcpy (dest_data, src_data, bytes_per_row * height);
}
else
{
for (y = 0; y < height; y++)
{
memcpy (dest_data, src_data, bytes_per_row);
src_data += src_stride;
dest_data += dest_stride;
}
}
return;
}
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)

View File

@@ -1050,6 +1050,7 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
{
g_warning_once ("Failed to create pipeline cache directory");
g_free (path);
g_free (data);
return FALSE;
}
g_free (path);
@@ -1085,6 +1086,7 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
}
g_clear_error (&error);
g_object_unref (file);
g_free (data);
/* try again */
return gdk_vulkan_save_pipeline_cache (display);
@@ -1093,10 +1095,12 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
g_warning ("Failed to save pipeline cache: %s", error->message);
g_clear_error (&error);
g_object_unref (file);
g_free (data);
return FALSE;
}
g_object_unref (file);
g_free (data);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
@@ -1132,12 +1136,15 @@ gdk_display_create_pipeline_cache (GdkDisplay *display)
{
display->vk_pipeline_cache = gdk_display_load_pipeline_cache (display);
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
},
NULL,
&display->vk_pipeline_cache);
if (display->vk_pipeline_cache == VK_NULL_HANDLE)
{
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
},
NULL,
&display->vk_pipeline_cache);
}
}
VkPipelineCache
@@ -1649,7 +1656,7 @@ gdk_display_unref_vulkan (GdkDisplay *display)
g_assert (display->vk_save_pipeline_cache_source == 0);
}
vkDestroyPipelineCache (display->vk_device, display->vk_pipeline_cache, NULL);
display->vk_device = VK_NULL_HANDLE;
display->vk_pipeline_cache = VK_NULL_HANDLE;
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
display->vk_pipeline_cache_size = 0;

View File

@@ -116,6 +116,7 @@ if have_vulkan
'vulkan/gskvulkancolormatrixop.c',
'vulkan/gskvulkancolorop.c',
'vulkan/gskvulkancommandpool.c',
'vulkan/gskvulkanconvertop.c',
'vulkan/gskvulkancrossfadeop.c',
'vulkan/gskvulkandownloadop.c',
'vulkan/gskvulkanglyphcache.c',

View File

@@ -0,0 +1,100 @@
#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);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "gskvulkanopprivate.h"
G_BEGIN_DECLS
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);
G_END_DECLS

View File

@@ -20,10 +20,12 @@ struct _GskVulkanImage
VkFormat vk_format;
gsize width;
gsize height;
VkImageTiling vk_tiling;
VkImageUsageFlags vk_usage;
VkImage vk_image;
VkImageView vk_image_view;
VkFramebuffer vk_framebuffer;
GskVulkanImagePostprocess postprocess;
VkPipelineStageFlags vk_pipeline_stage;
VkImageLayout vk_image_layout;
@@ -40,6 +42,7 @@ struct _GskMemoryFormatInfo
{
VkFormat format;
VkComponentMapping components;
GskVulkanImagePostprocess postprocess;
};
static const GskMemoryFormatInfo *
@@ -52,8 +55,8 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -62,7 +65,7 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -71,23 +74,53 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -96,8 +129,8 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -106,7 +139,7 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -115,20 +148,25 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -137,20 +175,25 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -159,33 +202,43 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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;
@@ -194,20 +247,25 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
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_G16A16:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R16G16_UNORM, SWIZZLE (R, R, R, G), GSK_VULKAN_IMAGE_PREMULTIPLY },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
case GDK_MEMORY_G16:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, ONE) },
{ VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, ONE), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
@@ -216,7 +274,7 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
case GDK_MEMORY_A8:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, R) },
{ VK_FORMAT_R8_UNORM, SWIZZLE (R, R, R, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
@@ -225,23 +283,7 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
case GDK_MEMORY_A16:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, R) },
{ 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:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R16_UNORM, SWIZZLE (R, R, R, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
@@ -262,53 +304,53 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
switch (format)
{
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_B8G8R8A8:
return GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
case GDK_MEMORY_A8R8G8B8:
return GDK_MEMORY_A8R8G8B8_PREMULTIPLIED;
case GDK_MEMORY_R8G8B8A8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_A8B8G8R8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_R8G8B8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_B8G8R8:
return GDK_MEMORY_R8G8B8;
case GDK_MEMORY_R16G16B16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16A16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_R16G16B16_FLOAT:
return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT:
return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_R32G32B32_FLOAT:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_G8A8_PREMULTIPLIED:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_G8A8:
return GDK_MEMORY_G8A8_PREMULTIPLIED;
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_G8:
return GDK_MEMORY_R8G8B8;
case GDK_MEMORY_G16A16_PREMULTIPLIED:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_G16A16:
return GDK_MEMORY_G16A16_PREMULTIPLIED;
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_G16:
return GDK_MEMORY_R16G16B16;
case GDK_MEMORY_A8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_A16:
@@ -321,20 +363,57 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
}
static gboolean
gsk_vulkan_context_supports_format (GdkVulkanContext *context,
VkFormat format)
gsk_vulkan_context_supports_format (GdkVulkanContext *context,
VkFormat format,
VkImageTiling tiling,
VkImageUsageFlags usage,
gsize width,
gsize height)
{
VkFormatProperties properties;
VkImageFormatProperties image_properties;
VkFormatFeatureFlags features, required;
VkResult res;
vkGetPhysicalDeviceFormatProperties (gdk_vulkan_context_get_physical_device (context),
format,
&properties);
if ((properties.linearTilingFeatures & (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) &&
(properties.optimalTilingFeatures & (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)))
return TRUE;
switch ((int) tiling)
{
case VK_IMAGE_TILING_OPTIMAL:
features = properties.optimalTilingFeatures;
break;
case VK_IMAGE_TILING_LINEAR:
features = properties.optimalTilingFeatures;
break;
default:
return FALSE;
}
required = 0;
if (usage & VK_IMAGE_USAGE_SAMPLED_BIT)
required |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
required |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
return FALSE;
if ((features & required) != required)
return FALSE;
res = vkGetPhysicalDeviceImageFormatProperties (gdk_vulkan_context_get_physical_device (context),
format,
VK_IMAGE_TYPE_2D,
tiling,
usage,
0,
&image_properties);
if (res != VK_SUCCESS)
return FALSE;
if (image_properties.maxExtent.width < width ||
image_properties.maxExtent.height < height)
return FALSE;
return TRUE;
}
static void
@@ -361,16 +440,17 @@ gsk_vulkan_image_create_view (GskVulkanImage *self,
}
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;
@@ -384,8 +464,24 @@ gsk_vulkan_image_new (GdkVulkanContext *context,
vk_format->format != VK_FORMAT_UNDEFINED;
vk_format++)
{
if (gsk_vulkan_context_supports_format (context, vk_format->format))
if (vk_format->postprocess & ~allowed_postprocess)
continue;
if (gsk_vulkan_context_supports_format (context,
vk_format->format,
tiling, usage,
width, height))
break;
if (tiling != VK_IMAGE_TILING_OPTIMAL &&
gsk_vulkan_context_supports_format (context,
vk_format->format,
VK_IMAGE_TILING_OPTIMAL, usage,
width, height))
{
tiling = VK_IMAGE_TILING_OPTIMAL;
break;
}
}
if (vk_format->format != VK_FORMAT_UNDEFINED)
break;
@@ -398,8 +494,10 @@ gsk_vulkan_image_new (GdkVulkanContext *context,
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_tiling = tiling;
self->vk_usage = usage;
self->vk_pipeline_stage = stage;
self->vk_image_layout = layout;
@@ -454,6 +552,7 @@ gsk_vulkan_image_new_for_upload (GdkVulkanContext *context,
format,
width,
height,
-1,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT,
@@ -471,6 +570,9 @@ gsk_vulkan_image_can_map (GskVulkanImage *self)
if (GSK_DEBUG_CHECK (STAGING))
return FALSE;
if (self->vk_tiling != VK_IMAGE_TILING_LINEAR)
return FALSE;
if (self->vk_image_layout != VK_IMAGE_LAYOUT_PREINITIALIZED &&
self->vk_image_layout != VK_IMAGE_LAYOUT_GENERAL)
return FALSE;
@@ -525,6 +627,7 @@ gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
self->vulkan = g_object_ref (context);
self->width = width;
self->height = height;
self->vk_tiling = VK_IMAGE_TILING_OPTIMAL;
self->vk_image = image;
self->vk_format = format;
self->vk_pipeline_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
@@ -555,6 +658,7 @@ gsk_vulkan_image_new_for_atlas (GdkVulkanContext *context,
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,
@@ -577,6 +681,7 @@ gsk_vulkan_image_new_for_offscreen (GdkVulkanContext *context,
preferred_format,
width,
height,
0,
VK_IMAGE_TILING_LINEAR,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
@@ -663,6 +768,12 @@ gsk_vulkan_image_get_height (GskVulkanImage *self)
return self->height;
}
GskVulkanImagePostprocess
gsk_vulkan_image_get_postprocess (GskVulkanImage *self)
{
return self->postprocess;
}
VkImage
gsk_vulkan_image_get_vk_image (GskVulkanImage *self)
{

View File

@@ -8,6 +8,12 @@
G_BEGIN_DECLS
/* required postprocessing steps before the image van be used */
typedef enum
{
GSK_VULKAN_IMAGE_PREMULTIPLY = (1 << 0),
} GskVulkanImagePostprocess;
#define GSK_TYPE_VULKAN_IMAGE (gsk_vulkan_image_get_type ())
G_DECLARE_FINAL_TYPE (GskVulkanImage, gsk_vulkan_image, GSK, VULKAN_IMAGE, GObject)
@@ -48,6 +54,8 @@ void gsk_vulkan_image_unmap (GskVulk
gsize gsk_vulkan_image_get_width (GskVulkanImage *self);
gsize gsk_vulkan_image_get_height (GskVulkanImage *self);
GskVulkanImagePostprocess
gsk_vulkan_image_get_postprocess (GskVulkanImage *self);
VkPipelineStageFlags gsk_vulkan_image_get_vk_pipeline_stage (GskVulkanImage *self);
VkImageLayout gsk_vulkan_image_get_vk_image_layout (GskVulkanImage *self);
VkAccessFlags gsk_vulkan_image_get_vk_access (GskVulkanImage *self);

View File

@@ -491,19 +491,33 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
GskVulkanDownloadFunc download_func,
gpointer download_data)
{
GskVulkanRenderPass *render_pass;
graphene_vec2_t scale;
cairo_rectangle_int_t extents;
graphene_vec2_init (&scale, self->scale, self->scale);
cairo_region_get_extents (self->clip, &extents);
gsk_vulkan_render_pass_op (self,
self->vulkan,
g_object_ref (self->target),
self->clip,
&scale,
&self->viewport,
node,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
gsk_vulkan_render_pass_begin_op (self,
g_object_ref (self->target),
&extents,
&self->viewport.size,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
render_pass = gsk_vulkan_render_pass_new ();
gsk_vulkan_render_pass_add (render_pass,
self,
&scale,
&self->viewport,
&extents,
node);
gsk_vulkan_render_pass_free (render_pass);
gsk_vulkan_render_pass_end_op (self,
g_object_ref (self->target),
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
if (download_func)
gsk_vulkan_download_op (self, self->target, download_func, download_data);
@@ -1007,6 +1021,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
gsk_vulkan_render_cleanup (self);
g_clear_pointer (&self->storage_buffer, gsk_vulkan_buffer_free);
g_clear_pointer (&self->vertex_buffer, gsk_vulkan_buffer_free);
device = gdk_vulkan_context_get_device (self->vulkan);

View File

@@ -16,6 +16,7 @@
#include "gskvulkanclipprivate.h"
#include "gskvulkancolormatrixopprivate.h"
#include "gskvulkancoloropprivate.h"
#include "gskvulkanconvertopprivate.h"
#include "gskvulkancrossfadeopprivate.h"
#include "gskvulkanglyphopprivate.h"
#include "gskvulkaninsetshadowopprivate.h"
@@ -42,13 +43,7 @@ typedef struct _GskVulkanParseState GskVulkanParseState;
struct _GskVulkanRenderPass
{
GdkVulkanContext *vulkan;
GskVulkanImage *target;
graphene_rect_t viewport;
cairo_region_t *clip;
graphene_vec2_t scale;
int empty;
};
struct _GskVulkanParseState
@@ -61,37 +56,12 @@ struct _GskVulkanParseState
GskVulkanClip clip;
};
#ifdef G_ENABLE_DEBUG
static GQuark fallback_pixels_quark;
static GQuark texture_pixels_quark;
#endif
GskVulkanRenderPass *
gsk_vulkan_render_pass_new (GdkVulkanContext *context,
GskVulkanRender *render,
GskVulkanImage *target,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
cairo_region_t *clip,
GskRenderNode *node)
gsk_vulkan_render_pass_new (void)
{
GskVulkanRenderPass *self;
self = g_new0 (GskVulkanRenderPass, 1);
self->vulkan = g_object_ref (context);
self->target = g_object_ref (target);
self->clip = cairo_region_copy (clip);
self->viewport = *viewport;
graphene_vec2_init_from_vec2 (&self->scale, scale);
#ifdef G_ENABLE_DEBUG
if (fallback_pixels_quark == 0)
{
fallback_pixels_quark = g_quark_from_static_string ("fallback-pixels");
texture_pixels_quark = g_quark_from_static_string ("texture-pixels");
}
#endif
return self;
}
@@ -99,10 +69,6 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context,
void
gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
{
g_object_unref (self->vulkan);
g_object_unref (self->target);
cairo_region_destroy (self->clip);
g_free (self);
}
@@ -175,6 +141,52 @@ gsk_vulkan_parse_rect_is_integer (const GskVulkanParseState *state,
&& 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,
@@ -193,7 +205,7 @@ gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass *self,
result = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (result == NULL)
{
result = gsk_vulkan_upload_texture_op (render, self->vulkan, texture);
result = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, result);
}
@@ -212,7 +224,6 @@ gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass *self,
return NULL;
result = gsk_vulkan_upload_cairo_op (render,
self->vulkan,
node,
&state->scale,
&clipped);
@@ -237,7 +248,6 @@ gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass *self,
*tex_bounds = clipped;
result = gsk_vulkan_render_pass_op_offscreen (render,
self->vulkan,
&state->scale,
&clipped,
node);
@@ -269,7 +279,6 @@ gsk_vulkan_render_pass_add_fallback_node (GskVulkanRenderPass *self,
return TRUE;
image = gsk_vulkan_upload_cairo_op (render,
self->vulkan,
node,
&state->scale,
&clipped);
@@ -471,7 +480,7 @@ gsk_vulkan_render_pass_add_texture_node (GskVulkanRenderPass *self,
image = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (image == NULL)
{
image = gsk_vulkan_upload_texture_op (render, self->vulkan, texture);
image = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, image);
}
@@ -514,7 +523,7 @@ gsk_vulkan_render_pass_add_texture_scale_node (GskVulkanRenderPass *self,
image = gsk_vulkan_renderer_get_texture_image (renderer, texture);
if (image == NULL)
{
image = gsk_vulkan_upload_texture_op (render, self->vulkan, texture);
image = gsk_vulkan_render_pass_upload_texture (render, texture);
gsk_vulkan_renderer_add_texture_image (renderer, texture, image);
}
@@ -901,7 +910,6 @@ gsk_vulkan_render_pass_add_repeat_node (GskVulkanRenderPass *self,
return TRUE;
image = gsk_vulkan_render_pass_op_offscreen (render,
self->vulkan,
&state->scale,
child_bounds,
gsk_repeat_node_get_child (node));
@@ -1292,31 +1300,33 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
}
void
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
GskRenderNode *node)
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
cairo_rectangle_int_t *clip,
GskRenderNode *node)
{
GskVulkanParseState state;
graphene_rect_t clip;
graphene_rect_t scaled_clip;
float scale_x, scale_y;
scale_x = 1 / graphene_vec2_get_x (&self->scale);
scale_y = 1 / graphene_vec2_get_y (&self->scale);
cairo_region_get_extents (self->clip, &state.scissor);
clip = GRAPHENE_RECT_INIT(state.scissor.x, state.scissor.y,
state.scissor.width, state.scissor.height);
graphene_rect_scale (&clip, scale_x, scale_y, &clip);
gsk_vulkan_clip_init_empty (&state.clip, &clip);
scale_x = 1 / graphene_vec2_get_x (scale);
scale_y = 1 / graphene_vec2_get_y (scale);
state.scissor = *clip;
scaled_clip = GRAPHENE_RECT_INIT(clip->x, clip->y, clip->width, clip->height);
graphene_rect_scale (&scaled_clip, scale_x, scale_y, &scaled_clip);
gsk_vulkan_clip_init_empty (&state.clip, &scaled_clip);
state.modelview = NULL;
graphene_matrix_init_ortho (&state.projection,
0, self->viewport.size.width,
0, self->viewport.size.height,
0, viewport->size.width,
0, viewport->size.height,
2 * ORTHO_NEAR_PLANE - ORTHO_FAR_PLANE,
ORTHO_FAR_PLANE);
graphene_vec2_init_from_vec2 (&state.scale, &self->scale);
state.offset = GRAPHENE_POINT_INIT (-self->viewport.origin.x * scale_x,
-self->viewport.origin.y * scale_y);
graphene_vec2_init_from_vec2 (&state.scale, scale);
state.offset = GRAPHENE_POINT_INIT (-viewport->origin.x * scale_x,
-viewport->origin.y * scale_y);
gsk_vulkan_render_pass_append_scissor (render, node, &state);
gsk_vulkan_render_pass_append_push_constants (render, node, &state);

View File

@@ -15,7 +15,6 @@ struct _GskVulkanRenderPassOp
GskVulkanOp op;
GskVulkanImage *image;
GskVulkanRenderPass *render_pass;
cairo_rectangle_int_t area;
graphene_size_t viewport_size;
@@ -29,7 +28,6 @@ gsk_vulkan_render_pass_op_finish (GskVulkanOp *op)
GskVulkanRenderPassOp *self = (GskVulkanRenderPassOp *) op;
g_object_unref (self->image);
gsk_vulkan_render_pass_free (self->render_pass);
}
static void
@@ -243,54 +241,47 @@ static const GskVulkanOpClass GSK_VULKAN_RENDER_PASS_END_OP_CLASS = {
};
void
gsk_vulkan_render_pass_op (GskVulkanRender *render,
GdkVulkanContext *context,
GskVulkanImage *image,
cairo_region_t *clip,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node,
VkImageLayout initial_layout,
VkImageLayout final_layout)
gsk_vulkan_render_pass_begin_op (GskVulkanRender *render,
GskVulkanImage *image,
const cairo_rectangle_int_t *area,
const graphene_size_t *viewport_size,
VkImageLayout initial_layout,
VkImageLayout final_layout)
{
GskVulkanRenderPassOp *self;
GskVulkanRenderPassEndOp *end;
self = (GskVulkanRenderPassOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_OP_CLASS);
self->image = image;
self->image = g_object_ref (image);
self->initial_layout = initial_layout;
self->final_layout = final_layout;
cairo_region_get_extents (clip, &self->area);
self->viewport_size = viewport->size;
self->area = *area;
self->viewport_size = *viewport_size;
}
self->render_pass = gsk_vulkan_render_pass_new (context,
render,
self->image,
scale,
viewport,
clip,
node);
void
gsk_vulkan_render_pass_end_op (GskVulkanRender *render,
GskVulkanImage *image,
VkImageLayout final_layout)
{
GskVulkanRenderPassEndOp *self;
/* This invalidates the self pointer */
gsk_vulkan_render_pass_add (self->render_pass, render, node);
self = (GskVulkanRenderPassEndOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_END_OP_CLASS);
end = (GskVulkanRenderPassEndOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_END_OP_CLASS);
end->image = g_object_ref (image);
end->final_layout = final_layout;
self->image = g_object_ref (image);
self->final_layout = final_layout;
}
GskVulkanImage *
gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
GdkVulkanContext *context,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node)
{
GskVulkanRenderPass *render_pass;
GdkVulkanContext *context;
graphene_rect_t view;
GskVulkanImage *image;
cairo_region_t *clip;
float scale_x, scale_y;
scale_x = graphene_vec2_get_x (scale);
@@ -300,28 +291,39 @@ gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
ceil (scale_x * viewport->size.width),
ceil (scale_y * viewport->size.height));
context = gsk_vulkan_render_get_context (render);
image = gsk_vulkan_image_new_for_offscreen (context,
gdk_vulkan_context_get_offscreen_format (context,
gsk_render_node_get_preferred_depth (node)),
view.size.width, view.size.height);
clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image)
});
gsk_vulkan_render_pass_begin_op (render,
image,
&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image)
},
&viewport->size,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
gsk_vulkan_render_pass_op (render,
context,
image,
clip,
scale,
&view,
node,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
render_pass = gsk_vulkan_render_pass_new ();
gsk_vulkan_render_pass_add (render_pass,
render,
scale,
viewport,
&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image)
},
node);
gsk_vulkan_render_pass_free (render_pass);
cairo_region_destroy (clip);
gsk_vulkan_render_pass_end_op (render,
image,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
return image;
}

View File

@@ -4,17 +4,18 @@
G_BEGIN_DECLS
void gsk_vulkan_render_pass_op (GskVulkanRender *render,
GdkVulkanContext *context,
void gsk_vulkan_render_pass_begin_op (GskVulkanRender *render,
GskVulkanImage *image,
cairo_region_t *clip,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node,
const cairo_rectangle_int_t *area,
const graphene_size_t *viewport_size,
VkImageLayout initial_layout,
VkImageLayout final_layout);
void gsk_vulkan_render_pass_end_op (GskVulkanRender *render,
GskVulkanImage *image,
VkImageLayout final_layout);
GskVulkanImage * gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
GdkVulkanContext *context,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
GskRenderNode *node);

View File

@@ -10,18 +10,15 @@
G_BEGIN_DECLS
GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context,
GskVulkanRender *render,
GskVulkanImage *target,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
cairo_region_t *clip,
GskRenderNode *node);
GskVulkanRenderPass * gsk_vulkan_render_pass_new (void);
void gsk_vulkan_render_pass_free (GskVulkanRenderPass *self);
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport,
cairo_rectangle_int_t *clip,
GskRenderNode *node);
G_END_DECLS

View File

@@ -214,7 +214,6 @@ static const GskVulkanOpClass GSK_VULKAN_UPLOAD_TEXTURE_OP_CLASS = {
GskVulkanImage *
gsk_vulkan_upload_texture_op (GskVulkanRender *render,
GdkVulkanContext *context,
GdkTexture *texture)
{
GskVulkanUploadTextureOp *self;
@@ -222,7 +221,7 @@ gsk_vulkan_upload_texture_op (GskVulkanRender *render,
self = (GskVulkanUploadTextureOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_UPLOAD_TEXTURE_OP_CLASS);
self->texture = g_object_ref (texture);
self->image = gsk_vulkan_image_new_for_upload (context,
self->image = gsk_vulkan_image_new_for_upload (gsk_vulkan_render_get_context (render),
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
@@ -327,7 +326,6 @@ static const GskVulkanOpClass GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS = {
GskVulkanImage *
gsk_vulkan_upload_cairo_op (GskVulkanRender *render,
GdkVulkanContext *context,
GskRenderNode *node,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport)
@@ -337,10 +335,11 @@ gsk_vulkan_upload_cairo_op (GskVulkanRender *render,
self = (GskVulkanUploadCairoOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS);
self->node = gsk_render_node_ref (node);
self->image = gsk_vulkan_image_new_for_upload (context,
self->image = gsk_vulkan_image_new_for_upload (gsk_vulkan_render_get_context (render),
GDK_MEMORY_DEFAULT,
ceil (graphene_vec2_get_x (scale) * viewport->size.width),
ceil (graphene_vec2_get_y (scale) * viewport->size.height));
g_assert (gsk_vulkan_image_get_postprocess (self->image) == 0);
self->viewport = *viewport;
return self->image;

View File

@@ -5,11 +5,9 @@
G_BEGIN_DECLS
GskVulkanImage * gsk_vulkan_upload_texture_op (GskVulkanRender *render,
GdkVulkanContext *context,
GdkTexture *texture);
GskVulkanImage * gsk_vulkan_upload_cairo_op (GskVulkanRender *render,
GdkVulkanContext *context,
GskRenderNode *node,
const graphene_vec2_t *scale,
const graphene_rect_t *viewport);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,29 @@
#version 450
#include "common.frag.glsl"
#include "clip.frag.glsl"
#include "rect.frag.glsl"
#define GSK_VULKAN_IMAGE_PREMULTIPLY (1 << 0)
#
layout(location = 0) in vec2 in_pos;
layout(location = 1) in Rect in_rect;
layout(location = 2) in vec2 in_tex_coord;
layout(location = 3) flat in uint in_tex_id;
layout(location = 4) in flat uint in_postprocess;
layout(location = 0) out vec4 color;
void main()
{
float alpha = rect_coverage (in_rect, in_pos);
/* warning: This breaks with filters other than nearest,
as linear filtering needs premultiplied alpha */
vec4 pixel = texture (get_sampler (in_tex_id), in_tex_coord);
if ((in_postprocess & GSK_VULKAN_IMAGE_PREMULTIPLY) != 0)
pixel.rgb *= pixel.a;
color = clip_scaled (in_pos, pixel * alpha);
}

View File

@@ -0,0 +1,26 @@
#version 450
#include "common.vert.glsl"
#include "rect.vert.glsl"
layout(location = 0) in vec4 in_rect;
layout(location = 1) in vec4 in_tex_rect;
layout(location = 2) in uint in_tex_id;
layout(location = 3) in uint in_postprocess;
layout(location = 0) out vec2 out_pos;
layout(location = 1) out flat Rect out_rect;
layout(location = 2) out vec2 out_tex_coord;
layout(location = 3) out flat uint out_tex_id;
layout(location = 4) out flat uint out_postprocess;
void main() {
Rect r = rect_from_gsk (in_rect);
vec2 pos = set_position_from_rect (r);
out_pos = pos;
out_rect = r;
out_tex_coord = scale_tex_coord (pos, r, in_tex_rect);
out_tex_id = in_tex_id;
out_postprocess = in_postprocess;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -17,6 +17,7 @@ gsk_private_vulkan_fragment_shaders = [
'border.frag',
'color.frag',
'color-matrix.frag',
'convert.frag',
'cross-fade.frag',
'glyph.frag',
'inset-shadow.frag',
@@ -32,6 +33,7 @@ gsk_private_vulkan_vertex_shaders = [
'border.vert',
'color.vert',
'color-matrix.vert',
'convert.vert',
'cross-fade.vert',
'glyph.vert',
'inset-shadow.vert',
@@ -44,7 +46,6 @@ gsk_private_vulkan_vertex_shaders = [
gsk_private_vulkan_shaders += gsk_private_vulkan_fragment_shaders
gsk_private_vulkan_shaders += gsk_private_vulkan_vertex_shaders
glslc = find_program('glslc', required: false)
foreach shader: gsk_private_vulkan_shaders
basefn = shader.split('.').get(0)
suffix = shader.split('.').get(1)
@@ -54,45 +55,41 @@ foreach shader: gsk_private_vulkan_shaders
clip_spv_shader = '@0@-clip.@1@.spv'.format(basefn, suffix)
clip_rounded_spv_shader = '@0@-clip-rounded.@1@.spv'.format(basefn, suffix)
if glslc.found()
compiled_shader = custom_target(spv_shader,
input: shader,
output: spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_NONE',
'@INPUT@',
'-o', '@OUTPUT@'
])
compiled_clip_shader = custom_target(clip_spv_shader,
input: shader,
output: clip_spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_RECT',
'@INPUT@',
'-o', '@OUTPUT@'
])
compiled_clip_rounded_shader = custom_target(clip_rounded_spv_shader,
input: shader,
output: clip_rounded_spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_ROUNDED_RECT',
'@INPUT@',
'-o', '@OUTPUT@'
])
gsk_private_vulkan_compiled_shaders_deps += [compiled_shader, compiled_clip_shader, compiled_clip_rounded_shader]
gsk_private_vulkan_compiled_shaders += [spv_shader, clip_spv_shader, clip_rounded_spv_shader]
else
gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
endif
compiled_shader = custom_target(spv_shader,
input: shader,
output: spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_NONE',
'@INPUT@',
'-o', '@OUTPUT@'
])
compiled_clip_shader = custom_target(clip_spv_shader,
input: shader,
output: clip_spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_RECT',
'@INPUT@',
'-o', '@OUTPUT@'
])
compiled_clip_rounded_shader = custom_target(clip_rounded_spv_shader,
input: shader,
output: clip_rounded_spv_shader,
depend_files: gsk_private_vulkan_include_shaders,
command: [
glslc,
stage_arg,
'-DCLIP_ROUNDED_RECT',
'@INPUT@',
'-o', '@OUTPUT@'
])
gsk_private_vulkan_compiled_shaders_deps += [compiled_shader, compiled_clip_shader, compiled_clip_rounded_shader]
gsk_private_vulkan_compiled_shaders += [spv_shader, clip_spv_shader, clip_rounded_spv_shader]
endforeach
foreach shader: gsk_private_vulkan_vertex_shaders

View File

@@ -599,6 +599,7 @@ endif
# to use a custom path for the Vulkan SDK. Bugs that are found with it should
# be reported upstream and fixed.
vulkan_dep = dependency('vulkan', required: get_option('vulkan'))
glslc = find_program('glslc', required: get_option('vulkan'))
if vulkan_dep.found()
have_vulkan = true
vulkan_pkg_found = vulkan_dep.type_name() == 'pkgconfig'