Compare commits
25 Commits
main
...
wip/otte/h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88e8e01156 | ||
|
|
fc3bd7894e | ||
|
|
93f175986b | ||
|
|
d1281ac3e7 | ||
|
|
fa6af928b8 | ||
|
|
16c231cf87 | ||
|
|
c5cfc99143 | ||
|
|
0226c216b2 | ||
|
|
07861c2474 | ||
|
|
c088578a9e | ||
|
|
f12de0bebc | ||
|
|
fdd3f7000b | ||
|
|
7149df64c4 | ||
|
|
acfb5c4122 | ||
|
|
78138167e7 | ||
|
|
19b36d90fe | ||
|
|
6d1db51c71 | ||
|
|
80341665db | ||
|
|
a2c8405699 | ||
|
|
6d37c6287c | ||
|
|
9287856f1d | ||
|
|
e6445f3e5e | ||
|
|
bc235d4c3d | ||
|
|
9ef0026f82 | ||
|
|
8b6d2d8a6b |
@@ -229,20 +229,6 @@ gdk_color_from_rgba (GdkColor *self,
|
||||
gdk_color_finish (&tmp);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_get_depth:
|
||||
* @self: a `GdkColor`
|
||||
*
|
||||
* Returns the preferred depth for the color state of @self.
|
||||
*
|
||||
* Returns: the preferred depth
|
||||
*/
|
||||
GdkMemoryDepth
|
||||
(gdk_color_get_depth) (const GdkColor *self)
|
||||
{
|
||||
return gdk_color_state_get_depth (self->color_state);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_print:
|
||||
* @self: the `GdkColor` to print
|
||||
|
||||
@@ -129,10 +129,3 @@ _gdk_color_to_float (const GdkColor *self,
|
||||
values);
|
||||
}
|
||||
|
||||
#define gdk_color_get_depth(self) _gdk_color_get_depth ((self))
|
||||
static inline GdkMemoryDepth
|
||||
_gdk_color_get_depth (const GdkColor *self)
|
||||
{
|
||||
return gdk_color_state_get_depth (self->color_state);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ gboolean gdk_color_equal (const GdkColor *color1,
|
||||
const GdkColor *color2);
|
||||
gboolean gdk_color_is_clear (const GdkColor *self);
|
||||
gboolean gdk_color_is_opaque (const GdkColor *self);
|
||||
GdkMemoryDepth gdk_color_get_depth (const GdkColor *self);
|
||||
|
||||
void gdk_color_convert (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
|
||||
@@ -45,9 +45,10 @@ typedef struct _GdkDisplayClass GdkDisplayClass;
|
||||
typedef enum {
|
||||
GDK_VULKAN_FEATURE_DMABUF = 1 << 0,
|
||||
GDK_VULKAN_FEATURE_YCBCR = 1 << 1,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 2,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 3,
|
||||
GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 4,
|
||||
GDK_VULKAN_FEATURE_SRGB = 1 << 2,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 3,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 4,
|
||||
GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 5,
|
||||
} GdkVulkanFeatures;
|
||||
|
||||
/* Tracks information about the device grab on this display */
|
||||
|
||||
@@ -638,10 +638,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
else
|
||||
*out_depth = GDK_MEMORY_U8;
|
||||
|
||||
if (*out_depth == GDK_MEMORY_U8_SRGB)
|
||||
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
|
||||
else
|
||||
*out_color_state = color_state;
|
||||
*out_color_state = color_state;
|
||||
#else
|
||||
*out_color_state = gdk_color_state_get_srgb ();
|
||||
*out_depth = GDK_MEMORY_U8;
|
||||
@@ -1711,10 +1708,13 @@ gdk_gl_context_check_features (GdkGLContext *context)
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
|
||||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage"))
|
||||
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_sRGB_write_control"))
|
||||
features |= GDK_GL_FEATURE_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
|
||||
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE |
|
||||
GDK_GL_FEATURE_SRGB;
|
||||
}
|
||||
|
||||
if (epoxy_has_gl_extension ("GL_KHR_debug"))
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef enum {
|
||||
GDK_GL_FEATURE_SYNC = 1 << 3,
|
||||
GDK_GL_FEATURE_BASE_INSTANCE = 1 << 4,
|
||||
GDK_GL_FEATURE_BUFFER_STORAGE = 1 << 5,
|
||||
GDK_GL_FEATURE_SRGB = 1 << 6,
|
||||
} GdkGLFeatures;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
static const GdkDebugKey gsk_vulkan_feature_keys[] = {
|
||||
{ "dmabuf", GDK_VULKAN_FEATURE_DMABUF, "Never import Dmabufs" },
|
||||
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures (also disables dmabufs)" },
|
||||
{ "srgb", GDK_VULKAN_FEATURE_SRGB, "Do not support SRGB images" },
|
||||
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
|
||||
{ "semaphore-import", GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT, "Disable sync of imported dmabufs" },
|
||||
{ "incremental-present", GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT, "Do not send damage regions" },
|
||||
@@ -303,6 +304,15 @@ surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
return "(unknown)";
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_vulkan_context_has_feature (GdkVulkanContext *self,
|
||||
GdkVulkanFeatures feature)
|
||||
{
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self));
|
||||
|
||||
return (display->vulkan_features & feature) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static const VkPresentModeKHR preferred_present_modes[] = {
|
||||
VK_PRESENT_MODE_MAILBOX_KHR,
|
||||
VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
@@ -457,8 +467,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
|
||||
&(VkSwapchainCreateInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.flags = priv->current_depth == GDK_MEMORY_U8_SRGB ? VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR : 0,
|
||||
.surface = priv->surface,
|
||||
.minImageCount = CLAMP (4,
|
||||
capabilities.minImageCount,
|
||||
@@ -477,7 +486,15 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
.compositeAlpha = composite_alpha,
|
||||
.presentMode = present_mode,
|
||||
.clipped = VK_FALSE,
|
||||
.oldSwapchain = priv->swapchain
|
||||
.oldSwapchain = priv->swapchain,
|
||||
.pNext = priv->current_depth == GDK_MEMORY_U8_SRGB ? &(VkImageFormatListCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
|
||||
.viewFormatCount = 2,
|
||||
.pViewFormats = (VkFormat[]) {
|
||||
priv->formats[priv->current_depth].vk_format.format,
|
||||
priv->formats[GDK_MEMORY_U8].vk_format.format,
|
||||
}
|
||||
} : NULL,
|
||||
},
|
||||
NULL,
|
||||
&new_swapchain);
|
||||
@@ -591,6 +608,9 @@ physical_device_check_features (VkPhysicalDevice device)
|
||||
physical_device_supports_extension (device, VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME))
|
||||
features |= GDK_VULKAN_FEATURE_DMABUF;
|
||||
|
||||
if (physical_device_supports_extension (device, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME))
|
||||
features |= GDK_VULKAN_FEATURE_SRGB;
|
||||
|
||||
if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME))
|
||||
{
|
||||
if (semaphore_props.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT)
|
||||
@@ -625,6 +645,9 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
color_state = gdk_surface_get_color_state (surface);
|
||||
depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (color_state));
|
||||
|
||||
if (depth == GDK_MEMORY_U8_SRGB && !gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_SRGB))
|
||||
depth = GDK_MEMORY_U8;
|
||||
|
||||
g_assert (depth != GDK_MEMORY_U8_SRGB || gdk_color_state_get_no_srgb_tf (color_state) != NULL);
|
||||
|
||||
if (depth != priv->current_depth && depth != GDK_MEMORY_NONE)
|
||||
@@ -678,10 +701,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
|
||||
cairo_region_union (region, priv->regions[priv->draw_index]);
|
||||
|
||||
if (priv->current_depth == GDK_MEMORY_U8_SRGB)
|
||||
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
|
||||
else
|
||||
*out_color_state = color_state;
|
||||
*out_color_state = color_state;
|
||||
*out_depth = priv->current_depth;
|
||||
}
|
||||
|
||||
@@ -692,11 +712,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkDisplay *display = gdk_draw_context_get_display (draw_context);
|
||||
VkRectLayerKHR *rectangles;
|
||||
int n_regions;
|
||||
|
||||
if (display->vulkan_features & GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT)
|
||||
if (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT))
|
||||
{
|
||||
double scale;
|
||||
|
||||
@@ -1529,6 +1548,10 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
|
||||
}
|
||||
if (features & GDK_VULKAN_FEATURE_SRGB)
|
||||
{
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME);
|
||||
}
|
||||
if (features & (GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT | GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT))
|
||||
{
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
|
||||
|
||||
@@ -33,6 +33,7 @@ struct _GskGpuDownloadOp
|
||||
GskGpuOp op;
|
||||
|
||||
GskGpuImage *image;
|
||||
GdkColorState *color_state;
|
||||
gboolean allow_dmabuf;
|
||||
GdkGpuDownloadOpCreateFunc create_func;
|
||||
GskGpuDownloadFunc func;
|
||||
@@ -118,6 +119,7 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
|
||||
guchar *data;
|
||||
gsize width, height, stride;
|
||||
GdkMemoryFormat format;
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
|
||||
data = gsk_gpu_buffer_map (self->buffer);
|
||||
width = gsk_gpu_image_get_width (self->image);
|
||||
@@ -125,11 +127,17 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
|
||||
format = gsk_gpu_image_get_format (self->image);
|
||||
stride = width * gdk_memory_format_bytes_per_pixel (format);
|
||||
bytes = g_bytes_new (data, stride * height);
|
||||
self->texture = gdk_memory_texture_new (width,
|
||||
height,
|
||||
format,
|
||||
bytes,
|
||||
stride);
|
||||
|
||||
builder = gdk_memory_texture_builder_new ();
|
||||
gdk_memory_texture_builder_set_width (builder, width);
|
||||
gdk_memory_texture_builder_set_height (builder, height);
|
||||
gdk_memory_texture_builder_set_format (builder, format);
|
||||
gdk_memory_texture_builder_set_bytes (builder, bytes);
|
||||
gdk_memory_texture_builder_set_stride (builder, stride);
|
||||
gdk_memory_texture_builder_set_color_state (builder, self->color_state);
|
||||
self->texture = gdk_memory_texture_builder_build (builder);
|
||||
|
||||
g_object_unref (builder);
|
||||
g_bytes_unref (bytes);
|
||||
gsk_gpu_buffer_unmap (self->buffer, 0);
|
||||
}
|
||||
@@ -144,7 +152,8 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op,
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
if (self->allow_dmabuf)
|
||||
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image));
|
||||
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image),
|
||||
self->color_state);
|
||||
if (self->texture)
|
||||
{
|
||||
GskGpuDevice *device = gsk_gpu_frame_get_device (frame);
|
||||
@@ -316,6 +325,7 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
|
||||
gdk_dmabuf_texture_builder_set_premultiplied (db, gdk_memory_format_get_premultiplied (gsk_gpu_image_get_format (self->image)));
|
||||
gdk_dmabuf_texture_builder_set_width (db, gsk_gpu_image_get_width (self->image));
|
||||
gdk_dmabuf_texture_builder_set_height (db, gsk_gpu_image_get_height (self->image));
|
||||
gdk_dmabuf_texture_builder_set_color_state (db, self->color_state);
|
||||
|
||||
self->texture = gdk_dmabuf_texture_builder_build (db, release_dmabuf_texture, texture, NULL);
|
||||
|
||||
@@ -340,6 +350,7 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
|
||||
gdk_gl_texture_builder_set_context (builder, context);
|
||||
gdk_gl_texture_builder_set_id (builder, data->texture_id);
|
||||
gdk_gl_texture_builder_set_format (builder, gsk_gpu_image_get_format (self->image));
|
||||
gdk_gl_texture_builder_set_color_state (builder, self->color_state);
|
||||
gdk_gl_texture_builder_set_width (builder, gsk_gpu_image_get_width (self->image));
|
||||
gdk_gl_texture_builder_set_height (builder, gsk_gpu_image_get_height (self->image));
|
||||
gdk_gl_texture_builder_set_sync (builder, data->sync);
|
||||
@@ -367,6 +378,7 @@ static const GskGpuOpClass GSK_GPU_DOWNLOAD_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_download_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *color_state,
|
||||
gboolean allow_dmabuf,
|
||||
GskGpuDownloadFunc func,
|
||||
gpointer user_data)
|
||||
@@ -376,6 +388,7 @@ gsk_gpu_download_op (GskGpuFrame *frame,
|
||||
self = (GskGpuDownloadOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_DOWNLOAD_OP_CLASS);
|
||||
|
||||
self->image = g_object_ref (image);
|
||||
self->color_state = gdk_color_state_ref (color_state);
|
||||
self->allow_dmabuf = allow_dmabuf;
|
||||
self->func = func,
|
||||
self->user_data = user_data;
|
||||
|
||||
@@ -9,6 +9,7 @@ typedef void (* GskGpuDownloadFunc) (gpointe
|
||||
|
||||
void gsk_gpu_download_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *color_state,
|
||||
gboolean allow_dmabuf,
|
||||
GskGpuDownloadFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
@@ -648,7 +648,7 @@ gsk_gpu_frame_record (GskGpuFrame *self,
|
||||
gsk_gpu_node_processor_process (self, target, target_color_state, clip, node, viewport, pass_type);
|
||||
|
||||
if (texture)
|
||||
gsk_gpu_download_op (self, target, TRUE, copy_texture, texture);
|
||||
gsk_gpu_download_op (self, target, target_color_state, TRUE, copy_texture, texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -755,6 +755,7 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self,
|
||||
|
||||
gsk_gpu_download_op (self,
|
||||
image,
|
||||
gdk_texture_get_color_state (texture),
|
||||
FALSE,
|
||||
do_download,
|
||||
g_memdup (&(Download) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -268,11 +268,17 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
|
||||
GskGpuFrame *frame;
|
||||
|
||||
max_size = gsk_gpu_device_get_max_image_size (priv->device);
|
||||
depth = gsk_render_node_get_preferred_depth (root);
|
||||
if (gsk_render_node_is_hdr (root))
|
||||
color_state = GDK_COLOR_STATE_REC2100_PQ;
|
||||
else
|
||||
color_state = GDK_COLOR_STATE_SRGB;
|
||||
depth = gdk_memory_depth_merge (gdk_color_state_get_depth (color_state),
|
||||
gsk_render_node_get_preferred_depth (root));
|
||||
|
||||
do
|
||||
{
|
||||
image = gsk_gpu_device_create_download_image (priv->device,
|
||||
gsk_render_node_get_preferred_depth (root),
|
||||
depth,
|
||||
MIN (max_size, rounded_viewport->size.width),
|
||||
MIN (max_size, rounded_viewport->size.height));
|
||||
max_size /= 2;
|
||||
@@ -300,11 +306,6 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
|
||||
MIN (image_width, width - x),
|
||||
MIN (image_height, height - y));
|
||||
|
||||
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
|
||||
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
|
||||
else
|
||||
color_state = GDK_COLOR_STATE_SRGB;
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
|
||||
0, 0,
|
||||
gsk_gpu_image_get_width (image),
|
||||
@@ -357,11 +358,19 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
GskGpuImage *image;
|
||||
GdkTexture *texture;
|
||||
graphene_rect_t rounded_viewport;
|
||||
GdkMemoryDepth depth;
|
||||
GdkColorState *color_state;
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
gsk_gpu_device_maybe_gc (priv->device);
|
||||
|
||||
if (gsk_render_node_is_hdr (root))
|
||||
color_state = GDK_COLOR_STATE_REC2100_PQ;
|
||||
else
|
||||
color_state = GDK_COLOR_STATE_SRGB;
|
||||
depth = gdk_memory_depth_merge (gdk_color_state_get_depth (color_state),
|
||||
gsk_render_node_get_preferred_depth (root));
|
||||
|
||||
gsk_gpu_renderer_make_current (self);
|
||||
|
||||
rounded_viewport = GRAPHENE_RECT_INIT (viewport->origin.x,
|
||||
@@ -369,18 +378,13 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
ceil (viewport->size.width),
|
||||
ceil (viewport->size.height));
|
||||
image = gsk_gpu_device_create_download_image (priv->device,
|
||||
gsk_render_node_get_preferred_depth (root),
|
||||
depth,
|
||||
rounded_viewport.size.width,
|
||||
rounded_viewport.size.height);
|
||||
|
||||
if (image == NULL)
|
||||
return gsk_gpu_renderer_fallback_render_texture (self, root, &rounded_viewport);
|
||||
|
||||
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
|
||||
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
|
||||
else
|
||||
color_state = GDK_COLOR_STATE_SRGB;
|
||||
|
||||
frame = gsk_gpu_renderer_create_frame (self);
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
|
||||
@@ -436,6 +440,8 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
|
||||
gsk_gpu_renderer_make_current (self);
|
||||
|
||||
depth = gsk_render_node_get_preferred_depth (root);
|
||||
if (gsk_render_node_is_hdr (root))
|
||||
depth = gdk_memory_depth_merge (depth, GDK_MEMORY_FLOAT16);
|
||||
frame = gsk_gpu_renderer_get_frame (self);
|
||||
scale = gsk_gpu_renderer_get_scale (self);
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@ struct _GskGpuRenderPassOp
|
||||
GskGpuOp op;
|
||||
|
||||
GskGpuImage *target;
|
||||
gboolean no_srgb;
|
||||
cairo_rectangle_int_t area;
|
||||
gboolean clear;
|
||||
GskGpuLoadOp load_op;
|
||||
float clear_color[4];
|
||||
GskRenderPassType pass_type;
|
||||
};
|
||||
@@ -45,8 +46,21 @@ gsk_gpu_render_pass_op_print (GskGpuOp *op,
|
||||
gsk_gpu_print_op (string, indent, "begin-render-pass");
|
||||
gsk_gpu_print_image (string, self->target);
|
||||
gsk_gpu_print_int_rect (string, &self->area);
|
||||
if (self->clear)
|
||||
gsk_gpu_print_rgba (string, self->clear_color);
|
||||
switch (self->load_op)
|
||||
{
|
||||
case GSK_GPU_LOAD_OP_LOAD:
|
||||
gsk_gpu_print_string (string, "load");
|
||||
break;
|
||||
case GSK_GPU_LOAD_OP_CLEAR:
|
||||
gsk_gpu_print_rgba (string, self->clear_color);
|
||||
break;
|
||||
case GSK_GPU_LOAD_OP_DONT_CARE:
|
||||
gsk_gpu_print_string (string, "dont-care");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
@@ -100,6 +114,21 @@ gsk_gpu_render_pass_op_do_barriers (GskGpuRenderPassOp *self,
|
||||
}
|
||||
}
|
||||
|
||||
static VkAttachmentLoadOp
|
||||
gsk_gpu_load_op_to_vk_load_op (GskGpuLoadOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case GSK_GPU_LOAD_OP_LOAD:
|
||||
return VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
case GSK_GPU_LOAD_OP_CLEAR:
|
||||
return VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
case GSK_GPU_LOAD_OP_DONT_CARE:
|
||||
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
default:
|
||||
g_return_val_if_reached (VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
}
|
||||
}
|
||||
static GskGpuOp *
|
||||
gsk_gpu_render_pass_op_vk_command (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
@@ -112,9 +141,10 @@ gsk_gpu_render_pass_op_vk_command (GskGpuOp *op,
|
||||
|
||||
gsk_gpu_render_pass_op_do_barriers (self, state);
|
||||
|
||||
state->vk_format = gsk_vulkan_image_get_vk_format (GSK_VULKAN_IMAGE (self->target));
|
||||
state->vk_format = gsk_vulkan_image_get_vk_format (GSK_VULKAN_IMAGE (self->target), self->no_srgb);
|
||||
state->vk_render_pass = gsk_vulkan_device_get_vk_render_pass (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
|
||||
state->vk_format,
|
||||
gsk_gpu_load_op_to_vk_load_op (self->load_op),
|
||||
gsk_vulkan_image_get_vk_image_layout (GSK_VULKAN_IMAGE (self->target)),
|
||||
gsk_gpu_render_pass_type_to_vk_image_layout (self->pass_type));
|
||||
|
||||
@@ -136,24 +166,25 @@ gsk_gpu_render_pass_op_vk_command (GskGpuOp *op,
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = state->vk_render_pass,
|
||||
.framebuffer = gsk_vulkan_image_get_vk_framebuffer (GSK_VULKAN_IMAGE(self->target),
|
||||
self->no_srgb,
|
||||
state->vk_render_pass),
|
||||
.renderArea = {
|
||||
{ self->area.x, self->area.y },
|
||||
{ self->area.width, self->area.height }
|
||||
},
|
||||
.clearValueCount = 1,
|
||||
.pClearValues = (VkClearValue [1]) {
|
||||
.clearValueCount = self->load_op == GSK_GPU_LOAD_OP_CLEAR ? 1 : 0,
|
||||
.pClearValues = self->load_op == GSK_GPU_LOAD_OP_CLEAR ? (VkClearValue [1]) {
|
||||
{
|
||||
.color = {
|
||||
.float32 = {
|
||||
self->clear ? self->clear_color[0] : 0,
|
||||
self->clear ? self->clear_color[1] : 0,
|
||||
self->clear ? self->clear_color[2] : 0,
|
||||
self->clear ? self->clear_color[3] : 0
|
||||
self->clear_color[0],
|
||||
self->clear_color[1],
|
||||
self->clear_color[2],
|
||||
self->clear_color[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} : NULL,
|
||||
},
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
@@ -186,6 +217,14 @@ gsk_gpu_render_pass_op_gl_command (GskGpuOp *op,
|
||||
else
|
||||
state->flip_y = 0;
|
||||
|
||||
if (gsk_gpu_image_get_flags (self->target) & GSK_GPU_IMAGE_SRGB)
|
||||
{
|
||||
if (self->no_srgb)
|
||||
glDisable (GL_FRAMEBUFFER_SRGB);
|
||||
else
|
||||
glEnable (GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
||||
glViewport (0, 0,
|
||||
gsk_gpu_image_get_width (self->target),
|
||||
gsk_gpu_image_get_height (self->target));
|
||||
@@ -194,7 +233,7 @@ gsk_gpu_render_pass_op_gl_command (GskGpuOp *op,
|
||||
glScissor (self->area.x, state->flip_y - self->area.y - self->area.height, self->area.width, self->area.height);
|
||||
else
|
||||
glScissor (self->area.x, self->area.y, self->area.width, self->area.height);
|
||||
if (self->clear)
|
||||
if (self->load_op == GSK_GPU_LOAD_OP_CLEAR)
|
||||
{
|
||||
glClearColor (self->clear_color[0], self->clear_color[1], self->clear_color[2], self->clear_color[3]);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
@@ -328,19 +367,25 @@ static const GskGpuOpClass GSK_GPU_RENDER_PASS_END_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_render_pass_begin_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
gboolean no_srgb,
|
||||
const cairo_rectangle_int_t *area,
|
||||
float clear_color_or_null[4],
|
||||
GskGpuLoadOp load_op,
|
||||
float clear_color[4],
|
||||
GskRenderPassType pass_type)
|
||||
{
|
||||
GskGpuRenderPassOp *self;
|
||||
|
||||
g_assert (load_op != GSK_GPU_LOAD_OP_CLEAR || clear_color != NULL);
|
||||
g_assert (!no_srgb || gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB);
|
||||
|
||||
self = (GskGpuRenderPassOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_RENDER_PASS_OP_CLASS);
|
||||
|
||||
self->target = g_object_ref (image);
|
||||
self->no_srgb = no_srgb;
|
||||
self->area = *area;
|
||||
self->clear = clear_color_or_null != NULL;
|
||||
if (clear_color_or_null)
|
||||
gsk_gpu_vec4_to_float (clear_color_or_null, self->clear_color);
|
||||
self->load_op = load_op;
|
||||
if (self->load_op == GSK_GPU_LOAD_OP_CLEAR)
|
||||
gsk_gpu_vec4_to_float (clear_color, self->clear_color);
|
||||
self->pass_type = pass_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_render_pass_begin_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
gboolean no_srgb,
|
||||
const cairo_rectangle_int_t *area,
|
||||
float clear_color_or_null[4],
|
||||
GskGpuLoadOp load_op,
|
||||
float clear_color[4],
|
||||
GskRenderPassType pass_type);
|
||||
void gsk_gpu_render_pass_end_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
|
||||
@@ -64,6 +64,13 @@ typedef enum
|
||||
GSK_RENDER_PASS_EXPORT
|
||||
} GskRenderPassType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSK_GPU_LOAD_OP_LOAD,
|
||||
GSK_GPU_LOAD_OP_CLEAR,
|
||||
GSK_GPU_LOAD_OP_DONT_CARE
|
||||
} GskGpuLoadOp;
|
||||
|
||||
typedef enum {
|
||||
GSK_GPU_PATTERN_DONE,
|
||||
GSK_GPU_PATTERN_COLOR,
|
||||
|
||||
@@ -91,23 +91,28 @@ static GskGpuImage *
|
||||
gsk_ngl_renderer_get_backbuffer (GskGpuRenderer *renderer)
|
||||
{
|
||||
GskNglRenderer *self = GSK_NGL_RENDERER (renderer);
|
||||
GdkMemoryFormat format;
|
||||
GdkMemoryDepth depth;
|
||||
GdkDrawContext *context;
|
||||
GdkSurface *surface;
|
||||
double scale;
|
||||
|
||||
context = gsk_gpu_renderer_get_context (renderer);
|
||||
surface = gdk_draw_context_get_surface (context);
|
||||
depth = gdk_draw_context_get_depth (context);
|
||||
format = gdk_memory_depth_get_format (depth);
|
||||
scale = gsk_gpu_renderer_get_scale (renderer);
|
||||
|
||||
if (self->backbuffer == NULL ||
|
||||
!!(gsk_gpu_image_get_flags (self->backbuffer) & GSK_GPU_IMAGE_SRGB) != gdk_surface_get_gl_is_srgb (surface) ||
|
||||
gsk_gpu_image_get_format (self->backbuffer) != format ||
|
||||
gsk_gpu_image_get_width (self->backbuffer) != ceil (gdk_surface_get_width (surface) * scale) ||
|
||||
gsk_gpu_image_get_height (self->backbuffer) != ceil (gdk_surface_get_height (surface) * scale))
|
||||
{
|
||||
gsk_ngl_renderer_free_backbuffer (self);
|
||||
self->backbuffer = gsk_gl_image_new_backbuffer (GSK_GL_DEVICE (gsk_gpu_renderer_get_device (renderer)),
|
||||
GDK_GL_CONTEXT (context),
|
||||
GDK_MEMORY_DEFAULT /* FIXME */,
|
||||
format,
|
||||
gdk_surface_get_gl_is_srgb (surface),
|
||||
ceil (gdk_surface_get_width (surface) * scale),
|
||||
ceil (gdk_surface_get_height (surface) * scale));
|
||||
|
||||
@@ -74,6 +74,7 @@ struct _PipelineCacheKey
|
||||
struct _RenderPassCacheKey
|
||||
{
|
||||
VkFormat format;
|
||||
VkAttachmentLoadOp vk_load_op;
|
||||
VkImageLayout from_layout;
|
||||
VkImageLayout to_layout;
|
||||
VkRenderPass render_pass;
|
||||
@@ -114,8 +115,9 @@ render_pass_cache_key_hash (gconstpointer data)
|
||||
{
|
||||
const RenderPassCacheKey *key = data;
|
||||
|
||||
return (key->from_layout << 20) ^
|
||||
(key->to_layout << 16) ^
|
||||
return (key->from_layout << 26) ^
|
||||
(key->to_layout << 18) ^
|
||||
(key->vk_load_op << 16) ^
|
||||
(key->format);
|
||||
}
|
||||
|
||||
@@ -128,6 +130,7 @@ render_pass_cache_key_equal (gconstpointer a,
|
||||
|
||||
return keya->from_layout == keyb->from_layout &&
|
||||
keya->to_layout == keyb->to_layout &&
|
||||
keya->vk_load_op == keyb->vk_load_op &&
|
||||
keya->format == keyb->format;
|
||||
}
|
||||
|
||||
@@ -706,10 +709,11 @@ gsk_vulkan_device_remove_ycbcr (GskVulkanDevice *self,
|
||||
}
|
||||
|
||||
VkRenderPass
|
||||
gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
VkFormat format,
|
||||
VkImageLayout from_layout,
|
||||
VkImageLayout to_layout)
|
||||
gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
VkFormat format,
|
||||
VkAttachmentLoadOp vk_load_op,
|
||||
VkImageLayout from_layout,
|
||||
VkImageLayout to_layout)
|
||||
{
|
||||
RenderPassCacheKey cache_key;
|
||||
RenderPassCacheKey *cached_result;
|
||||
@@ -718,6 +722,7 @@ gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
|
||||
cache_key = (RenderPassCacheKey) {
|
||||
.format = format,
|
||||
.vk_load_op = vk_load_op,
|
||||
.from_layout = from_layout,
|
||||
.to_layout = to_layout,
|
||||
};
|
||||
@@ -735,7 +740,7 @@ gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
{
|
||||
.format = format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.loadOp = vk_load_op,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.initialLayout = from_layout,
|
||||
.finalLayout = to_layout
|
||||
|
||||
@@ -53,6 +53,7 @@ void gsk_vulkan_device_remove_ycbcr (GskVulk
|
||||
|
||||
VkRenderPass gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
VkFormat format,
|
||||
VkAttachmentLoadOp vk_load_op,
|
||||
VkImageLayout from_layout,
|
||||
VkImageLayout to_layout);
|
||||
VkPipeline gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
|
||||
@@ -19,19 +19,24 @@
|
||||
#include <linux/dma-buf.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
DEFAULT = 0,
|
||||
NO_SRGB = 1
|
||||
};
|
||||
|
||||
struct _GskVulkanImage
|
||||
{
|
||||
GskGpuImage parent_instance;
|
||||
|
||||
GskVulkanDevice *device;
|
||||
|
||||
VkFormat vk_format;
|
||||
VkFormat vk_format[2];
|
||||
VkImageTiling vk_tiling;
|
||||
VkImageUsageFlags vk_usage;
|
||||
VkImage vk_image;
|
||||
VkImageView vk_image_view;
|
||||
VkFramebuffer vk_framebuffer;
|
||||
VkImageView vk_framebuffer_image_view;
|
||||
VkFramebuffer vk_framebuffer[2];
|
||||
VkImageView vk_framebuffer_image_view[2];
|
||||
GskVulkanYcbcr *ycbcr;
|
||||
VkSemaphore vk_semaphore;
|
||||
struct {
|
||||
@@ -278,11 +283,15 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
/* all fine */
|
||||
}
|
||||
else if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
else if (gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkMemoryFormat rgba_format;
|
||||
|
||||
@@ -296,11 +305,15 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
/* all fine */
|
||||
}
|
||||
else if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
else if (gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
const GdkMemoryFormat *fallbacks;
|
||||
gsize i;
|
||||
@@ -316,7 +329,6 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
}
|
||||
@@ -324,6 +336,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
}
|
||||
@@ -335,7 +348,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
}
|
||||
}
|
||||
|
||||
if (vk_format == vk_srgb_format)
|
||||
if (vk_srgb_format != VK_FORMAT_UNDEFINED)
|
||||
flags |= GSK_GPU_IMAGE_SRGB;
|
||||
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
@@ -354,7 +367,11 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
self = g_object_new (GSK_TYPE_VULKAN_IMAGE, NULL);
|
||||
|
||||
self->device = g_object_ref (device);
|
||||
self->vk_format = vk_format;
|
||||
self->vk_format[NO_SRGB] = vk_format;
|
||||
if (flags & GSK_GPU_IMAGE_SRGB)
|
||||
self->vk_format[DEFAULT] = vk_srgb_format;
|
||||
else
|
||||
self->vk_format[DEFAULT] = vk_format;
|
||||
self->vk_tiling = tiling;
|
||||
self->vk_usage = usage;
|
||||
self->vk_pipeline_stage = stage;
|
||||
@@ -366,7 +383,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
GSK_VK_CHECK (vkCreateImage, vk_device,
|
||||
&(VkImageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.flags = (flags & GSK_GPU_IMAGE_SRGB) ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT : 0,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = vk_format,
|
||||
.extent = { width, height, 1 },
|
||||
@@ -378,6 +395,15 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
(flags & GSK_GPU_IMAGE_NO_BLIT ? 0 : VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.initialLayout = self->vk_image_layout,
|
||||
.pNext = (flags & GSK_GPU_IMAGE_SRGB) ? &(VkImageFormatListCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.viewFormatCount = 2,
|
||||
.pViewFormats = (VkFormat[]) {
|
||||
vk_format,
|
||||
vk_srgb_format
|
||||
}
|
||||
} : NULL,
|
||||
},
|
||||
NULL,
|
||||
&self->vk_image);
|
||||
@@ -477,8 +503,8 @@ gsk_vulkan_image_get_data (GskVulkanImage *self,
|
||||
GskGpuImage *
|
||||
gsk_vulkan_image_new_for_swapchain (GskVulkanDevice *device,
|
||||
VkImage image,
|
||||
VkFormat format,
|
||||
GdkMemoryFormat memory_format,
|
||||
VkFormat vk_format,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -490,19 +516,25 @@ gsk_vulkan_image_new_for_swapchain (GskVulkanDevice *device,
|
||||
self->device = g_object_ref (device);
|
||||
self->vk_tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
self->vk_image = image;
|
||||
self->vk_format = format;
|
||||
self->vk_format[0] = vk_format;
|
||||
if (vk_format == gdk_memory_format_vk_srgb_format (format))
|
||||
{
|
||||
self->vk_format[1] = gdk_memory_format_vk_format (format, NULL);
|
||||
flags |= GSK_GPU_IMAGE_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->vk_format[1] = vk_format;
|
||||
}
|
||||
self->vk_pipeline_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
self->vk_image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
self->vk_access = 0;
|
||||
|
||||
if (format == gdk_memory_format_vk_srgb_format (memory_format))
|
||||
flags |= GSK_GPU_IMAGE_SRGB;
|
||||
|
||||
/* FIXME: The flags here are very suboptimal */
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self), flags, memory_format, width, height);
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self), flags, format, width, height);
|
||||
|
||||
gsk_vulkan_image_create_view (self,
|
||||
format,
|
||||
vk_format,
|
||||
&(VkComponentMapping) {
|
||||
VK_COMPONENT_SWIZZLE_R,
|
||||
VK_COMPONENT_SWIZZLE_G,
|
||||
@@ -759,7 +791,8 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
|
||||
self->device = g_object_ref (device);
|
||||
self->vk_tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
self->vk_format = vk_format;
|
||||
self->vk_format[0] = vk_format;
|
||||
self->vk_format[1] = vk_format;
|
||||
self->vk_pipeline_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
self->vk_image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
self->vk_access = 0;
|
||||
@@ -775,7 +808,7 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
res = vkCreateImage (vk_device,
|
||||
&(VkImageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.flags = (vk_format == vk_srgb_format) ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT : 0,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = vk_format,
|
||||
.extent = { width, height, 1 },
|
||||
@@ -793,7 +826,16 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
.pNext = &(VkImageDrmFormatModifierListCreateInfoEXT) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
|
||||
.drmFormatModifierCount = n_modifiers,
|
||||
.pDrmFormatModifiers = modifiers
|
||||
.pDrmFormatModifiers = modifiers,
|
||||
.pNext = (vk_format == vk_srgb_format) ? &(VkImageFormatListCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.viewFormatCount = 2,
|
||||
.pViewFormats = (VkFormat[]) {
|
||||
vk_format,
|
||||
gdk_memory_format_vk_format (format, NULL),
|
||||
}
|
||||
} : NULL,
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -911,7 +953,8 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
|
||||
self->device = g_object_ref (device);
|
||||
self->vk_tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
|
||||
self->vk_format = vk_format;
|
||||
self->vk_format[0] = vk_format;
|
||||
self->vk_format[1] = vk_format;
|
||||
self->vk_pipeline_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
self->vk_image_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
self->vk_access = 0;
|
||||
@@ -1163,7 +1206,7 @@ gsk_vulkan_image_get_n_planes (GskVulkanImage *self,
|
||||
gsize i;
|
||||
|
||||
vkGetPhysicalDeviceFormatProperties2 (gsk_vulkan_device_get_vk_physical_device (self->device),
|
||||
self->vk_format,
|
||||
self->vk_format[0],
|
||||
&properties);
|
||||
|
||||
for (i = 0; i < drm_properties.drmFormatModifierCount; i++)
|
||||
@@ -1176,7 +1219,8 @@ gsk_vulkan_image_get_n_planes (GskVulkanImage *self,
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
|
||||
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
|
||||
GdkColorState *color_state)
|
||||
{
|
||||
GskGpuImage *image = GSK_GPU_IMAGE (self);
|
||||
GdkDmabufTextureBuilder *builder;
|
||||
@@ -1230,6 +1274,7 @@ gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
|
||||
gdk_dmabuf_texture_builder_set_modifier (builder, properties.drmFormatModifier);
|
||||
gdk_dmabuf_texture_builder_set_premultiplied (builder, !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA));
|
||||
gdk_dmabuf_texture_builder_set_n_planes (builder, n_planes);
|
||||
gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
|
||||
|
||||
for (plane = 0; plane < n_planes; plane++)
|
||||
{
|
||||
@@ -1306,12 +1351,14 @@ gsk_vulkan_image_finalize (GObject *object)
|
||||
self->descriptor_sets[i].vk_descriptor_set);
|
||||
}
|
||||
|
||||
if (self->vk_framebuffer != VK_NULL_HANDLE)
|
||||
vkDestroyFramebuffer (vk_device, self->vk_framebuffer, NULL);
|
||||
|
||||
if (self->vk_framebuffer_image_view != VK_NULL_HANDLE &&
|
||||
self->vk_framebuffer_image_view != self->vk_image_view)
|
||||
vkDestroyImageView (vk_device, self->vk_framebuffer_image_view, NULL);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (self->vk_framebuffer[i] != VK_NULL_HANDLE)
|
||||
vkDestroyFramebuffer (vk_device, self->vk_framebuffer[0], NULL);
|
||||
if (self->vk_framebuffer_image_view[i] != VK_NULL_HANDLE &&
|
||||
self->vk_framebuffer_image_view[i] != self->vk_image_view)
|
||||
vkDestroyImageView (vk_device, self->vk_framebuffer_image_view[i], NULL);
|
||||
}
|
||||
|
||||
if (self->vk_image_view != VK_NULL_HANDLE)
|
||||
vkDestroyImageView (vk_device, self->vk_image_view, NULL);
|
||||
@@ -1351,23 +1398,32 @@ gsk_vulkan_image_init (GskVulkanImage *self)
|
||||
|
||||
VkFramebuffer
|
||||
gsk_vulkan_image_get_vk_framebuffer (GskVulkanImage *self,
|
||||
gboolean no_srgb,
|
||||
VkRenderPass render_pass)
|
||||
{
|
||||
VkDevice vk_device;
|
||||
GskGpuImageFlags flags;
|
||||
guint id;
|
||||
|
||||
if (self->vk_framebuffer)
|
||||
return self->vk_framebuffer;
|
||||
flags = gsk_gpu_image_get_flags (GSK_GPU_IMAGE (self));
|
||||
if (flags & GSK_GPU_IMAGE_SRGB)
|
||||
id = no_srgb ? NO_SRGB : DEFAULT;
|
||||
else
|
||||
id = DEFAULT;
|
||||
|
||||
if (self->vk_framebuffer[id])
|
||||
return self->vk_framebuffer[id];
|
||||
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self->device);
|
||||
|
||||
if (gsk_gpu_image_get_flags (GSK_GPU_IMAGE (self)) & GSK_GPU_IMAGE_CAN_MIPMAP)
|
||||
if (flags & (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_SRGB))
|
||||
{
|
||||
GSK_VK_CHECK (vkCreateImageView, vk_device,
|
||||
&(VkImageViewCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.image = self->vk_image,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = self->vk_format,
|
||||
.format = self->vk_format[id],
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
@@ -1377,11 +1433,11 @@ gsk_vulkan_image_get_vk_framebuffer (GskVulkanImage *self,
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&self->vk_framebuffer_image_view);
|
||||
&self->vk_framebuffer_image_view[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->vk_framebuffer_image_view = self->vk_image_view;
|
||||
self->vk_framebuffer_image_view[id] = self->vk_image_view;
|
||||
}
|
||||
|
||||
GSK_VK_CHECK (vkCreateFramebuffer, vk_device,
|
||||
@@ -1390,16 +1446,16 @@ gsk_vulkan_image_get_vk_framebuffer (GskVulkanImage *self,
|
||||
.renderPass = render_pass,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = (VkImageView[1]) {
|
||||
self->vk_framebuffer_image_view,
|
||||
self->vk_framebuffer_image_view[id],
|
||||
},
|
||||
.width = gsk_gpu_image_get_width (GSK_GPU_IMAGE (self)),
|
||||
.height = gsk_gpu_image_get_height (GSK_GPU_IMAGE (self)),
|
||||
.layers = 1
|
||||
},
|
||||
NULL,
|
||||
&self->vk_framebuffer);
|
||||
&self->vk_framebuffer[id]);
|
||||
|
||||
return self->vk_framebuffer;
|
||||
return self->vk_framebuffer[id];
|
||||
}
|
||||
|
||||
VkDescriptorSet
|
||||
@@ -1531,8 +1587,9 @@ gsk_vulkan_image_transition (GskVulkanImage *self,
|
||||
}
|
||||
|
||||
VkFormat
|
||||
gsk_vulkan_image_get_vk_format (GskVulkanImage *self)
|
||||
gsk_vulkan_image_get_vk_format (GskVulkanImage *self,
|
||||
gboolean no_srgb)
|
||||
{
|
||||
return self->vk_format;
|
||||
return self->vk_format[no_srgb ? NO_SRGB : DEFAULT];
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulk
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean premultiplied);
|
||||
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self);
|
||||
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
|
||||
GdkColorState *color_state);
|
||||
#endif
|
||||
|
||||
guchar * gsk_vulkan_image_get_data (GskVulkanImage *self,
|
||||
@@ -72,8 +73,10 @@ void gsk_vulkan_image_transition (GskVulk
|
||||
|
||||
VkImage gsk_vulkan_image_get_vk_image (GskVulkanImage *self);
|
||||
VkImageView gsk_vulkan_image_get_vk_image_view (GskVulkanImage *self);
|
||||
VkFormat gsk_vulkan_image_get_vk_format (GskVulkanImage *self);
|
||||
VkFormat gsk_vulkan_image_get_vk_format (GskVulkanImage *self,
|
||||
gboolean no_srgb);
|
||||
VkFramebuffer gsk_vulkan_image_get_vk_framebuffer (GskVulkanImage *self,
|
||||
gboolean no_srgb,
|
||||
VkRenderPass pass);
|
||||
|
||||
static inline guint
|
||||
|
||||
@@ -161,6 +161,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
graphene_rect_t opaque_tmp;
|
||||
const graphene_rect_t *opaque;
|
||||
GdkColorState *ccs;
|
||||
cairo_t *cr;
|
||||
|
||||
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
|
||||
@@ -189,9 +190,15 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
ccs = gdk_draw_context_get_color_state (GDK_DRAW_CONTEXT (self->cairo_context));
|
||||
if (gdk_draw_context_get_depth (GDK_DRAW_CONTEXT (self->cairo_context)) == GDK_MEMORY_U8_SRGB)
|
||||
{
|
||||
ccs = gdk_color_state_get_no_srgb_tf (ccs);
|
||||
g_assert (ccs);
|
||||
}
|
||||
gsk_cairo_renderer_do_render (renderer,
|
||||
cr,
|
||||
gdk_draw_context_get_color_state (GDK_DRAW_CONTEXT (self->cairo_context)),
|
||||
ccs,
|
||||
root);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
@@ -81,14 +81,6 @@ gsk_color_stops_are_opaque (const GskColorStop *stops,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* FIXME: Replace this once GdkColor lands */
|
||||
static inline GdkMemoryDepth
|
||||
my_color_stops_get_depth (const GskColorStop *stops,
|
||||
gsize n_stops)
|
||||
{
|
||||
return gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
color_state_is_hdr (GdkColorState *color_state)
|
||||
{
|
||||
@@ -324,7 +316,7 @@ gsk_color_node_new2 (const GdkColor *color,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gdk_color_is_opaque (color);
|
||||
node->preferred_depth = gdk_color_get_depth (color);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
node->is_hdr = color_state_is_hdr (color->color_state);
|
||||
|
||||
gdk_color_init_copy (&self->color, color);
|
||||
@@ -505,7 +497,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gsk_color_stops_are_opaque (color_stops, n_color_stops);
|
||||
node->preferred_depth = my_color_stops_get_depth (color_stops, n_color_stops);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
@@ -561,7 +553,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gsk_color_stops_are_opaque (color_stops, n_color_stops);
|
||||
node->preferred_depth = my_color_stops_get_depth (color_stops, n_color_stops);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
@@ -845,7 +837,7 @@ gsk_radial_gradient_node_new (const graphene_rect_t *bounds,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gsk_color_stops_are_opaque (color_stops, n_color_stops);
|
||||
node->preferred_depth = my_color_stops_get_depth (color_stops, n_color_stops);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
@@ -917,7 +909,7 @@ gsk_repeating_radial_gradient_node_new (const graphene_rect_t *bounds,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gsk_color_stops_are_opaque (color_stops, n_color_stops);
|
||||
node->preferred_depth = my_color_stops_get_depth (color_stops, n_color_stops);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
@@ -1319,7 +1311,7 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gsk_color_stops_are_opaque (color_stops, n_color_stops);
|
||||
node->preferred_depth = my_color_stops_get_depth (color_stops, n_color_stops);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
@@ -1789,11 +1781,7 @@ gsk_border_node_new2 (const GskRoundedRect *outline,
|
||||
self = gsk_render_node_alloc (GSK_BORDER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->preferred_depth = gdk_memory_depth_merge (
|
||||
gdk_memory_depth_merge (gdk_color_get_depth (&border_color[0]),
|
||||
gdk_color_get_depth (&border_color[1])),
|
||||
gdk_memory_depth_merge (gdk_color_get_depth (&border_color[2]),
|
||||
gdk_color_get_depth (&border_color[3])));
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
memcpy (self->border_width, border_width, sizeof (self->border_width));
|
||||
@@ -2811,7 +2799,7 @@ gsk_inset_shadow_node_new2 (const GskRoundedRect *outline,
|
||||
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->preferred_depth = gdk_color_get_depth (color);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
gdk_color_init_copy (&self->color, color);
|
||||
@@ -3207,7 +3195,7 @@ gsk_outset_shadow_node_new2 (const GskRoundedRect *outline,
|
||||
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->preferred_depth = gdk_color_get_depth (color);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
gdk_color_init_copy (&self->color, color);
|
||||
@@ -5799,7 +5787,6 @@ gsk_shadow_node_new2 (GskRenderNode *child,
|
||||
GskShadowNode *self;
|
||||
GskRenderNode *node;
|
||||
gsize i;
|
||||
GdkMemoryDepth depth;
|
||||
gboolean is_hdr;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
|
||||
@@ -5814,7 +5801,6 @@ gsk_shadow_node_new2 (GskRenderNode *child,
|
||||
self->n_shadows = n_shadows;
|
||||
self->shadows = g_new (GskShadow2, n_shadows);
|
||||
|
||||
depth = gsk_render_node_get_preferred_depth (child);
|
||||
is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
@@ -5822,11 +5808,10 @@ gsk_shadow_node_new2 (GskRenderNode *child,
|
||||
gdk_color_init_copy (&self->shadows[i].color, &shadows[i].color);
|
||||
graphene_point_init_from_point (&self->shadows[i].offset, &shadows[i].offset);
|
||||
self->shadows[i].radius = shadows[i].radius;
|
||||
depth = gdk_memory_depth_merge (depth, gdk_color_get_depth (&shadows[i].color));
|
||||
is_hdr = is_hdr || color_state_is_hdr (shadows[i].color.color_state);
|
||||
}
|
||||
|
||||
node->preferred_depth = depth;
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = is_hdr;
|
||||
|
||||
gsk_shadow_node_get_bounds (self, &node->bounds);
|
||||
@@ -6518,7 +6503,7 @@ gsk_text_node_new2 (PangoFont *font,
|
||||
self = gsk_render_node_alloc (GSK_TEXT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->preferred_depth = gdk_color_get_depth (color);
|
||||
node->preferred_depth = GDK_MEMORY_NONE;
|
||||
node->is_hdr = color_state_is_hdr (color->color_state);
|
||||
|
||||
self->fontmap = g_object_ref (pango_font_get_font_map (font));
|
||||
|
||||
18
testsuite/gsk/compare/bug-rgba8-offscreen-in-high-depth.node
Normal file
18
testsuite/gsk/compare/bug-rgba8-offscreen-in-high-depth.node
Normal file
@@ -0,0 +1,18 @@
|
||||
color-matrix {
|
||||
matrix: matrix3d(65535, 0, 0, 0, 0, 65535, 0, 0, 0, 0, 65535, 0, 0, 0, 0, 1);
|
||||
child: blend {
|
||||
mode: difference;
|
||||
bottom: texture {
|
||||
bounds: 0 0 10 10;
|
||||
texture: url("data:image/png;base64,\
|
||||
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKEAYAAADdohP+AAAAAXNSR0IArs4c6QAAAARjSUNQAQ0A\
|
||||
AZxpOzIAAAAfSURBVCiRY/w/n4GBgeH/fwYqASZqGTRq4KiBg8lAAH3dA7DFgV4pAAAAAElFTkSu\
|
||||
QmCC\
|
||||
");
|
||||
}
|
||||
top: color {
|
||||
bounds: 0 0 10 10;
|
||||
color: color(srgb 0.999 0 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
testsuite/gsk/compare/bug-rgba8-offscreen-in-high-depth.png
Normal file
BIN
testsuite/gsk/compare/bug-rgba8-offscreen-in-high-depth.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 B |
@@ -31,6 +31,7 @@ compare_render_tests = [
|
||||
'border-zero-width-color',
|
||||
'borders-rotated',
|
||||
'borders-scaled',
|
||||
'bug-rgba8-offscreen-in-high-depth',
|
||||
'clip-contained',
|
||||
'clip-coordinates-2d',
|
||||
'clip-coordinates-nocairo',
|
||||
|
||||
Reference in New Issue
Block a user