gpu: Add blitting support
Add GSK_GPU_IMAGE_NO_BLIT flag for textures that can't be blitted from. Use a blit op to do image copies otherwise.
This commit is contained in:
@@ -209,6 +209,8 @@ gsk_gpu_blit_op (GskGpuFrame *frame,
|
||||
{
|
||||
GskGpuBlitOp *self;
|
||||
|
||||
g_assert ((gsk_gpu_image_get_flags (src_image) & GSK_GPU_IMAGE_NO_BLIT) == 0);
|
||||
|
||||
self = (GskGpuBlitOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_BLIT_OP_CLASS);
|
||||
|
||||
self->src_image = g_object_ref (src_image);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "gskgpuborderopprivate.h"
|
||||
#include "gskgpuboxshadowopprivate.h"
|
||||
#include "gskgpublitopprivate.h"
|
||||
#include "gskgpubluropprivate.h"
|
||||
#include "gskgpuclearopprivate.h"
|
||||
#include "gskgpuclipprivate.h"
|
||||
@@ -571,9 +572,6 @@ gsk_gpu_node_processor_ensure_image (GskGpuNodeProcessor *self,
|
||||
GskGpuImageFlags flags, missing_flags;
|
||||
GskGpuImage *copy;
|
||||
gsize width, height;
|
||||
GskGpuNodeProcessor other;
|
||||
graphene_rect_t rect;
|
||||
guint32 descriptor;
|
||||
|
||||
g_assert ((required_flags & disallowed_flags) == 0);
|
||||
g_assert ((required_flags & (GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_STRAIGHT_ALPHA)) == 0);
|
||||
@@ -593,50 +591,63 @@ gsk_gpu_node_processor_ensure_image (GskGpuNodeProcessor *self,
|
||||
gdk_memory_format_get_depth (gsk_gpu_image_get_format (image)),
|
||||
width, height);
|
||||
|
||||
rect = GRAPHENE_RECT_INIT (0, 0, width, height);
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
|
||||
gsk_gpu_node_processor_init (&other,
|
||||
self->frame,
|
||||
self->desc,
|
||||
copy,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&rect);
|
||||
|
||||
gsk_gpu_render_pass_begin_op (other.frame,
|
||||
copy,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (&other, 0);
|
||||
|
||||
if (flags & GSK_GPU_IMAGE_STRAIGHT_ALPHA)
|
||||
if ((flags & (GSK_GPU_IMAGE_NO_BLIT | GSK_GPU_IMAGE_STRAIGHT_ALPHA)) == 0)
|
||||
{
|
||||
gsk_gpu_straight_alpha_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &rect),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&rect,
|
||||
&other.offset,
|
||||
&rect);
|
||||
gsk_gpu_blit_op (self->frame,
|
||||
image,
|
||||
copy,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
GSK_GPU_BLIT_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_texture_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &rect),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&rect,
|
||||
&other.offset,
|
||||
&rect);
|
||||
GskGpuNodeProcessor other;
|
||||
graphene_rect_t rect = GRAPHENE_RECT_INIT (0, 0, width, height);
|
||||
guint32 descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
|
||||
gsk_gpu_node_processor_init (&other,
|
||||
self->frame,
|
||||
self->desc,
|
||||
copy,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&rect);
|
||||
|
||||
gsk_gpu_render_pass_begin_op (other.frame,
|
||||
copy,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (&other, 0);
|
||||
|
||||
if (flags & GSK_GPU_IMAGE_STRAIGHT_ALPHA)
|
||||
{
|
||||
gsk_gpu_straight_alpha_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &rect),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&rect,
|
||||
&other.offset,
|
||||
&rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_texture_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &rect),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&rect,
|
||||
&other.offset,
|
||||
&rect);
|
||||
}
|
||||
|
||||
gsk_gpu_render_pass_end_op (other.frame,
|
||||
copy,
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
|
||||
gsk_gpu_node_processor_finish (&other);
|
||||
}
|
||||
|
||||
gsk_gpu_render_pass_end_op (other.frame,
|
||||
image,
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
|
||||
gsk_gpu_node_processor_finish (&other);
|
||||
|
||||
g_object_unref (image);
|
||||
|
||||
return copy;
|
||||
|
||||
@@ -20,6 +20,7 @@ typedef enum {
|
||||
GSK_GPU_IMAGE_EXTERNAL = (1 << 0),
|
||||
GSK_GPU_IMAGE_TOGGLE_REF = (1 << 1),
|
||||
GSK_GPU_IMAGE_STRAIGHT_ALPHA = (1 << 2),
|
||||
GSK_GPU_IMAGE_NO_BLIT = (1 << 3),
|
||||
} GskGpuImageFlags;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -458,7 +458,8 @@ gsk_vulkan_device_supports_format (GskVulkanDevice *device,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
gsize width,
|
||||
gsize height)
|
||||
gsize height,
|
||||
GskGpuImageFlags *out_flags)
|
||||
{
|
||||
VkDrmFormatModifierPropertiesEXT drm_mod_properties[100];
|
||||
VkDrmFormatModifierPropertiesListEXT drm_properties;
|
||||
@@ -545,6 +546,10 @@ gsk_vulkan_device_supports_format (GskVulkanDevice *device,
|
||||
image_properties.imageFormatProperties.maxExtent.height < height)
|
||||
return FALSE;
|
||||
|
||||
*out_flags = 0;
|
||||
if ((features & VK_FORMAT_FEATURE_BLIT_SRC_BIT) == 0)
|
||||
*out_flags |= GSK_GPU_IMAGE_NO_BLIT;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -593,6 +598,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
GskVulkanImage *self;
|
||||
VkDevice vk_device;
|
||||
const GskMemoryFormatInfo *vk_format;
|
||||
GskGpuImageFlags flags;
|
||||
|
||||
g_assert (width > 0 && height > 0);
|
||||
|
||||
@@ -613,7 +619,8 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
vk_format->format,
|
||||
0, 1,
|
||||
tiling, usage,
|
||||
width, height))
|
||||
width, height,
|
||||
&flags))
|
||||
break;
|
||||
|
||||
if (tiling != VK_IMAGE_TILING_OPTIMAL &&
|
||||
@@ -621,7 +628,8 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
vk_format->format,
|
||||
0, 1,
|
||||
VK_IMAGE_TILING_OPTIMAL, usage,
|
||||
width, height))
|
||||
width, height,
|
||||
&flags))
|
||||
{
|
||||
tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
break;
|
||||
@@ -650,7 +658,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
self->vk_access = access;
|
||||
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
|
||||
vk_format->flags,
|
||||
flags | vk_format->flags,
|
||||
format, width, height);
|
||||
|
||||
GSK_VK_CHECK (vkCreateImage, vk_device,
|
||||
@@ -664,7 +672,8 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
.arrayLayers = 1,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.tiling = tiling,
|
||||
.usage = usage,
|
||||
.usage = usage |
|
||||
(flags & GSK_GPU_IMAGE_NO_BLIT ? 0 : VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.initialLayout = self->vk_image_layout,
|
||||
},
|
||||
@@ -857,6 +866,7 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
gsize width, height;
|
||||
const GdkDmabuf *dmabuf;
|
||||
VkResult res;
|
||||
GskGpuImageFlags flags;
|
||||
gboolean is_yuv;
|
||||
|
||||
if (!gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_DMABUF))
|
||||
@@ -895,7 +905,8 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
dmabuf->n_planes,
|
||||
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
width, height))
|
||||
width, height,
|
||||
&flags))
|
||||
{
|
||||
GDK_DEBUG (DMABUF, "Vulkan driver does not support format %.4s::%016llx with %u planes",
|
||||
(char *) &dmabuf->fourcc, (unsigned long long) dmabuf->modifier, dmabuf->n_planes);
|
||||
@@ -923,7 +934,8 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
.arrayLayers = 1,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
||||
.usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
(flags & GSK_GPU_IMAGE_NO_BLIT ? 0 : VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.initialLayout = self->vk_image_layout,
|
||||
.pNext = &(VkExternalMemoryImageCreateInfo) {
|
||||
@@ -964,8 +976,9 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
}
|
||||
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
|
||||
flags |
|
||||
(gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0) |
|
||||
(is_yuv ? GSK_GPU_IMAGE_EXTERNAL : 0),
|
||||
(is_yuv ? (GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT) : 0),
|
||||
gdk_texture_get_format (texture),
|
||||
width, height);
|
||||
gsk_gpu_image_toggle_ref_texture (GSK_GPU_IMAGE (self), texture);
|
||||
|
||||
Reference in New Issue
Block a user