diff --git a/gsk/gpu/gskgpuimage.c b/gsk/gpu/gskgpuimage.c index c3dfb8c3a2..e43a7d173b 100644 --- a/gsk/gpu/gskgpuimage.c +++ b/gsk/gpu/gskgpuimage.c @@ -30,9 +30,40 @@ gsk_gpu_image_get_default_projection_matrix (GskGpuImage *self, ORTHO_FAR_PLANE); } +static void +gsk_gpu_image_texture_toggle_ref_cb (gpointer texture, + GObject *image, + gboolean is_last_ref) +{ + if (is_last_ref) + g_object_unref (texture); + else + g_object_ref (texture); +} + +static void +gsk_gpu_image_dispose (GObject *object) +{ + GskGpuImage *self = GSK_GPU_IMAGE (object); + GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self); + + if (priv->flags & GSK_GPU_IMAGE_TOGGLE_REF) + { + priv->flags &= ~GSK_GPU_IMAGE_TOGGLE_REF; + G_OBJECT (self)->ref_count++; + g_object_remove_toggle_ref (G_OBJECT (self), gsk_gpu_image_texture_toggle_ref_cb, NULL); + } + + G_OBJECT_CLASS (gsk_gpu_image_parent_class)->dispose (object); +} + static void gsk_gpu_image_class_init (GskGpuImageClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gsk_gpu_image_dispose; + klass->get_projection_matrix = gsk_gpu_image_get_default_projection_matrix; } @@ -55,6 +86,34 @@ gsk_gpu_image_setup (GskGpuImage *self, priv->width = width; priv->height = height; } + +/* + * gsk_gpu_image_toggle_ref_texture: + * @self: a GskGpuImage + * @texture: the texture owning @self + * + * This function must be called whenever the texture owns the data + * used by the image. It will then add a toggle ref, so that ref'ing + * the image will ref the texture and unrefing the image will unref it + * again. + * + * This ensures that whenever the image is used, the texture will keep + * being referenced and not go away. But once all the image's references + * get unref'ed, the texture is free to go away. + **/ +void +gsk_gpu_image_toggle_ref_texture (GskGpuImage *self, + GdkTexture *texture) +{ + GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self); + + g_assert ((priv->flags & GSK_GPU_IMAGE_TOGGLE_REF) == 0); + + priv->flags |= GSK_GPU_IMAGE_TOGGLE_REF; + g_object_ref (texture); + g_object_add_toggle_ref (G_OBJECT (self), gsk_gpu_image_texture_toggle_ref_cb, texture); + g_object_unref (self); +} GdkMemoryFormat gsk_gpu_image_get_format (GskGpuImage *self) diff --git a/gsk/gpu/gskgpuimageprivate.h b/gsk/gpu/gskgpuimageprivate.h index a4b1405c77..da4a58e870 100644 --- a/gsk/gpu/gskgpuimageprivate.h +++ b/gsk/gpu/gskgpuimageprivate.h @@ -35,6 +35,8 @@ void gsk_gpu_image_setup (GskGpuI GdkMemoryFormat format, gsize width, gsize height); +void gsk_gpu_image_toggle_ref_texture (GskGpuImage *self, + GdkTexture *texture); GdkMemoryFormat gsk_gpu_image_get_format (GskGpuImage *self); gsize gsk_gpu_image_get_width (GskGpuImage *self); diff --git a/gsk/gpu/gskgputypesprivate.h b/gsk/gpu/gskgputypesprivate.h index c4d9fadb44..2e8fdf6ae1 100644 --- a/gsk/gpu/gskgputypesprivate.h +++ b/gsk/gpu/gskgputypesprivate.h @@ -18,6 +18,7 @@ typedef struct _GskGpuShaderOpClass GskGpuShaderOpClass; typedef enum { GSK_GPU_IMAGE_EXTERNAL = (1 << 0), + GSK_GPU_IMAGE_TOGGLE_REF = (1 << 1), } GskGpuImageFlags; typedef enum { diff --git a/gsk/gpu/gskvulkandevice.c b/gsk/gpu/gskvulkandevice.c index 5f5fe87aaf..daa1f42c40 100644 --- a/gsk/gpu/gskvulkandevice.c +++ b/gsk/gpu/gskvulkandevice.c @@ -522,6 +522,12 @@ gsk_vulkan_device_get_vk_queue (GskVulkanDevice *self) return gsk_gpu_device_get_display (GSK_GPU_DEVICE (self))->vk_queue; } +uint32_t +gsk_vulkan_device_get_vk_queue_family_index (GskVulkanDevice *self) +{ + return gsk_gpu_device_get_display (GSK_GPU_DEVICE (self))->vk_queue_family_index; +} + VkDescriptorSetLayout gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self, GskVulkanPipelineLayout *layout) diff --git a/gsk/gpu/gskvulkandeviceprivate.h b/gsk/gpu/gskvulkandeviceprivate.h index 05a065954b..0bc4179ac1 100644 --- a/gsk/gpu/gskvulkandeviceprivate.h +++ b/gsk/gpu/gskvulkandeviceprivate.h @@ -35,6 +35,7 @@ gboolean gsk_vulkan_device_has_feature (GskVulk VkDevice gsk_vulkan_device_get_vk_device (GskVulkanDevice *self) G_GNUC_PURE; VkPhysicalDevice gsk_vulkan_device_get_vk_physical_device (GskVulkanDevice *self) G_GNUC_PURE; VkQueue gsk_vulkan_device_get_vk_queue (GskVulkanDevice *self) G_GNUC_PURE; +uint32_t gsk_vulkan_device_get_vk_queue_family_index (GskVulkanDevice *self) G_GNUC_PURE; VkDescriptorSetLayout gsk_vulkan_device_get_vk_buffer_set_layout (GskVulkanDevice *self) G_GNUC_PURE; VkCommandPool gsk_vulkan_device_get_vk_command_pool (GskVulkanDevice *self) G_GNUC_PURE; VkSampler gsk_vulkan_device_get_vk_sampler (GskVulkanDevice *self, diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index c4ff64a52e..a8eb766f75 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -9,6 +9,7 @@ #include "gskvulkanimageprivate.h" #include "gdk/gdkdisplayprivate.h" +#include "gdk/gdkdmabuftextureprivate.h" #define GDK_ARRAY_NAME gsk_descriptor_image_infos #define GDK_ARRAY_TYPE_NAME GskDescriptorImageInfos @@ -155,6 +156,23 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame) GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->cleanup (frame); } +static GskGpuImage * +gsk_vulkan_frame_upload_texture (GskGpuFrame *frame, + GdkTexture *texture) +{ +#ifdef HAVE_DMABUF + if (GDK_IS_DMABUF_TEXTURE (texture)) + { + GskGpuImage *image = gsk_vulkan_image_new_for_dmabuf (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), + texture); + if (image) + return image; + } +#endif + + return GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->upload_texture (frame, texture); +} + guint32 gsk_vulkan_frame_add_image (GskVulkanFrame *self, GskGpuImage *image, @@ -410,6 +428,7 @@ gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass) gpu_frame_class->is_busy = gsk_vulkan_frame_is_busy; gpu_frame_class->setup = gsk_vulkan_frame_setup; gpu_frame_class->cleanup = gsk_vulkan_frame_cleanup; + gpu_frame_class->upload_texture = gsk_vulkan_frame_upload_texture; gpu_frame_class->create_descriptors = gsk_vulkan_frame_create_descriptors; gpu_frame_class->create_vertex_buffer = gsk_vulkan_frame_create_vertex_buffer; gpu_frame_class->create_storage_buffer = gsk_vulkan_frame_create_storage_buffer; diff --git a/gsk/gpu/gskvulkanimage.c b/gsk/gpu/gskvulkanimage.c index 5b3a2fcfd5..f7c770fef3 100644 --- a/gsk/gpu/gskvulkanimage.c +++ b/gsk/gpu/gskvulkanimage.c @@ -6,9 +6,12 @@ #include "gskvulkanmemoryprivate.h" #include "gdk/gdkdisplayprivate.h" +#include "gdk/gdkdmabuftextureprivate.h" #include "gdk/gdkvulkancontextprivate.h" #include "gdk/gdkmemoryformatprivate.h" +#include "gdk/gdkvulkancontextprivate.h" +#include #include struct _GskVulkanImage @@ -451,22 +454,32 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format) static gboolean gsk_vulkan_device_supports_format (GskVulkanDevice *device, VkFormat format, + uint64_t modifier, + guint n_planes, VkImageTiling tiling, VkImageUsageFlags usage, gsize width, gsize height) { + VkDrmFormatModifierPropertiesEXT drm_mod_properties[100]; + VkDrmFormatModifierPropertiesListEXT drm_properties; VkPhysicalDevice vk_phys_device; VkFormatProperties2 properties; VkImageFormatProperties2 image_properties; VkFormatFeatureFlags features, required; VkResult res; + gsize i; vk_phys_device = gsk_vulkan_device_get_vk_physical_device (device); + drm_properties = (VkDrmFormatModifierPropertiesListEXT) { + .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, + .drmFormatModifierCount = G_N_ELEMENTS (drm_mod_properties), + .pDrmFormatModifierProperties = drm_mod_properties, + }; properties = (VkFormatProperties2) { .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, - .pNext = NULL + .pNext = (tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ? NULL : &drm_properties }; vkGetPhysicalDeviceFormatProperties2 (vk_phys_device, format, @@ -480,6 +493,20 @@ gsk_vulkan_device_supports_format (GskVulkanDevice *device, case VK_IMAGE_TILING_LINEAR: features = properties.formatProperties.linearTilingFeatures; break; + case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: + features = 0; + for (i = 0; i < drm_properties.drmFormatModifierCount; i++) + { + if (drm_mod_properties[i].drmFormatModifier == modifier && + drm_mod_properties[i].drmFormatModifierPlaneCount == n_planes) + { + features = drm_mod_properties[i].drmFormatModifierTilingFeatures; + break; + } + } + if (features == 0) + return FALSE; + break; default: return FALSE; } @@ -494,17 +521,22 @@ gsk_vulkan_device_supports_format (GskVulkanDevice *device, image_properties = (VkImageFormatProperties2) { .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, - .pNext = NULL, }; res = vkGetPhysicalDeviceImageFormatProperties2 (vk_phys_device, &(VkPhysicalDeviceImageFormatInfo2) { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - .pNext = NULL, .format = format, .type = VK_IMAGE_TYPE_2D, .tiling = tiling, .usage = usage, .flags = 0, + .pNext = (tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ? NULL : &(VkPhysicalDeviceImageDrmFormatModifierInfoEXT) { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .drmFormatModifier = modifier, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = (uint32_t[1]) { gsk_vulkan_device_get_vk_queue_family_index (device) }, + } }, &image_properties); if (res != VK_SUCCESS) @@ -580,6 +612,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device, if (gsk_vulkan_device_supports_format (device, vk_format->format, + 0, 1, tiling, usage, width, height)) break; @@ -587,6 +620,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device, if (tiling != VK_IMAGE_TILING_OPTIMAL && gsk_vulkan_device_supports_format (device, vk_format->format, + 0, 1, VK_IMAGE_TILING_OPTIMAL, usage, width, height)) { @@ -807,6 +841,271 @@ gsk_vulkan_image_new_for_offscreen (GskVulkanDevice *device, return GSK_GPU_IMAGE (self); } +#ifdef HAVE_DMABUF +GskGpuImage * +gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device, + GdkTexture *texture) +{ + GskVulkanImage *self; + VkDevice vk_device; + VkFormat vk_format; + VkComponentMapping vk_components; + VkSamplerYcbcrConversion vk_conversion; + PFN_vkGetMemoryFdPropertiesKHR func_vkGetMemoryFdPropertiesKHR; + gsize i; + int fd; + gsize width, height; + const GdkDmabuf *dmabuf; + VkResult res; + gboolean is_yuv; + + if (!gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_DMABUF)) + { + GDK_DEBUG (DMABUF, "Vulkan does not support dmabufs"); + return NULL; + } + + width = gdk_texture_get_width (texture); + height = gdk_texture_get_height (texture); + dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)); + vk_device = gsk_vulkan_device_get_vk_device (device); + func_vkGetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR) vkGetDeviceProcAddr (vk_device, "vkGetMemoryFdPropertiesKHR"); + + vk_format = gdk_dmabuf_get_vk_format (dmabuf->fourcc, &vk_components); + if (vk_format == VK_FORMAT_UNDEFINED) + { + GDK_DEBUG (DMABUF, "GTK's Vulkan doesn't support fourcc %.4s", (char *) &dmabuf->fourcc); + return NULL; + } + if (!gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv)) + { + g_assert_not_reached (); + } + + /* FIXME: Add support for disjoint images */ + if (gdk_dmabuf_is_disjoint (dmabuf)) + { + GDK_DEBUG (DMABUF, "FIXME: Add support for disjoint dmabufs to Vulkan"); + return NULL; + } + + if (!gsk_vulkan_device_supports_format (device, + vk_format, + dmabuf->modifier, + dmabuf->n_planes, + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, + VK_IMAGE_USAGE_SAMPLED_BIT, + width, height)) + { + 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); + return NULL; + } + + self = g_object_new (GSK_TYPE_VULKAN_IMAGE, NULL); + + self->display = g_object_ref (gsk_gpu_device_get_display (GSK_GPU_DEVICE (device))); + gdk_display_ref_vulkan (self->display); + self->vk_tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; + self->vk_format = 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; + + res = vkCreateImage (vk_device, + &(VkImageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .flags = 0, //disjoint ? VK_IMAGE_CREATE_DISJOINT_BIT : 0, + .imageType = VK_IMAGE_TYPE_2D, + .format = vk_format, + .extent = { width, height, 1 }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .initialLayout = self->vk_image_layout, + .pNext = &(VkExternalMemoryImageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + .pNext = &(VkImageDrmFormatModifierExplicitCreateInfoEXT) { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT, + .drmFormatModifier = dmabuf->modifier, + .drmFormatModifierPlaneCount = dmabuf->n_planes, + .pPlaneLayouts = (VkSubresourceLayout[4]) { + { + .offset = dmabuf->planes[0].offset, + .rowPitch = dmabuf->planes[0].stride, + }, + { + .offset = dmabuf->planes[1].offset, + .rowPitch = dmabuf->planes[1].stride, + }, + { + .offset = dmabuf->planes[2].offset, + .rowPitch = dmabuf->planes[2].stride, + }, + { + .offset = dmabuf->planes[3].offset, + .rowPitch = dmabuf->planes[3].stride, + }, + }, + } + }, + }, + NULL, + &self->vk_image); + if (res != VK_SUCCESS) + { + gsk_vulkan_handle_result (res, "vkCreateImage"); + GDK_DEBUG (DMABUF, "vkCreateImage() failed: %s", gdk_vulkan_strerror (res)); + return NULL; + } + + gsk_gpu_image_setup (GSK_GPU_IMAGE (self), + is_yuv ? GSK_GPU_IMAGE_EXTERNAL : 0, + gdk_texture_get_format (texture), + width, height); + gsk_gpu_image_toggle_ref_texture (GSK_GPU_IMAGE (self), texture); + + self->allocator = gsk_vulkan_device_get_external_allocator (device); + gsk_vulkan_allocator_ref (self->allocator); + + fd = fcntl (dmabuf->planes[0].fd, F_DUPFD_CLOEXEC, (int) 3); + if (fd < 0) + { + GDK_DEBUG (DMABUF, "Vulkan failed to dup() fd: %s", g_strerror (errno)); + vkDestroyImage (vk_device, self->vk_image, NULL); + return NULL; + } + + for (i = 0; i < 1 /* disjoint ? dmabuf->n_planes : 1 */; i++) + { + VkMemoryFdPropertiesKHR fd_props = { + .sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR, + }; + VkMemoryRequirements2 requirements = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + }; + + GSK_VK_CHECK (func_vkGetMemoryFdPropertiesKHR, vk_device, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + fd, + &fd_props); + + vkGetImageMemoryRequirements2 (vk_device, + &(VkImageMemoryRequirementsInfo2) { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, + .image = self->vk_image, + //.pNext = !disjoint ? NULL : &(VkImagePlaneMemoryRequirementsInfo) { + // .sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, + // .planeAspect = aspect_flags[i] + //}, + }, + &requirements); + + gsk_vulkan_alloc (self->allocator, + requirements.memoryRequirements.size, + requirements.memoryRequirements.alignment, + &self->allocation); + GSK_VK_CHECK (vkAllocateMemory, vk_device, + &(VkMemoryAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = requirements.memoryRequirements.size, + .memoryTypeIndex = g_bit_nth_lsf (fd_props.memoryTypeBits, -1), + .pNext = &(VkImportMemoryFdInfoKHR) { + .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + .fd = fd, + .pNext = &(VkMemoryDedicatedAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .image = self->vk_image, + } + } + }, + NULL, + &self->allocation.vk_memory); + } + +#if 1 + GSK_VK_CHECK (vkBindImageMemory2, self->display->vk_device, + 1, + &(VkBindImageMemoryInfo) { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + .image = self->vk_image, + .memory = self->allocation.vk_memory, + .memoryOffset = self->allocation.offset, + }); +#else + GSK_VK_CHECK (vkBindImageMemory2, self->display->vk_device, + dmabuf->n_planes, + (VkBindImageMemoryInfo[4]) { + { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + .image = self->vk_image, + .memory = self->allocation.vk_memory, + .memoryOffset = dmabuf->planes[0].offset, + .pNext = &(VkBindImagePlaneMemoryInfo) { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + .planeAspect = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT, + }, + }, + { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + .image = self->vk_image, + .memory = self->allocation.vk_memory, + .memoryOffset = dmabuf->planes[1].offset, + .pNext = &(VkBindImagePlaneMemoryInfo) { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + .planeAspect = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT, + }, + + }, + { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + .image = self->vk_image, + .memory = self->allocation.vk_memory, + .memoryOffset = dmabuf->planes[2].offset, + .pNext = &(VkBindImagePlaneMemoryInfo) { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + .planeAspect = VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT, + }, + }, + { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + .image = self->vk_image, + .memory = self->allocation.vk_memory, + .memoryOffset = dmabuf->planes[3].offset, + .pNext = &(VkBindImagePlaneMemoryInfo) { + .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + .planeAspect = VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT, + }, + } + }); +#endif + + if (is_yuv) + vk_conversion = gsk_vulkan_device_get_vk_conversion (device, vk_format, &self->vk_sampler); + else + vk_conversion = VK_NULL_HANDLE; + + gsk_vulkan_image_create_view (self, + vk_conversion, + &(GskMemoryFormatInfo) { + vk_format, + vk_components, + }); + + GDK_DEBUG (DMABUF, "Vulkan uploaded %zux%zu %.4s::%016llx %sdmabuf", + width, height, + (char *) &dmabuf->fourcc, (unsigned long long) dmabuf->modifier, + is_yuv ? "YUV " : ""); + + return GSK_GPU_IMAGE (self); +} +#endif + static void gsk_vulkan_image_get_projection_matrix (GskGpuImage *image, graphene_matrix_t *out_projection) diff --git a/gsk/gpu/gskvulkanimageprivate.h b/gsk/gpu/gskvulkanimageprivate.h index 678dc02129..4ea0d5efde 100644 --- a/gsk/gpu/gskvulkanimageprivate.h +++ b/gsk/gpu/gskvulkanimageprivate.h @@ -3,6 +3,8 @@ #include "gskgpuimageprivate.h" #include "gskvulkandeviceprivate.h" +#include "gdk/gdkdmabufprivate.h" + G_BEGIN_DECLS /* required postprocessing steps before the image van be used */ @@ -28,11 +30,15 @@ GskGpuImage * gsk_vulkan_image_new_for_offscreen (GskVulk GdkMemoryFormat preferred_format, gsize width, gsize height); - GskGpuImage * gsk_vulkan_image_new_for_upload (GskVulkanDevice *device, GdkMemoryFormat format, gsize width, gsize height); +#ifdef HAVE_DMABUF +GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device, + GdkTexture *texture); +#endif + guchar * gsk_vulkan_image_get_data (GskVulkanImage *self, gsize *out_stride);