vulkan: Turn swapchain image targets into GskVulkanImages

This gives us proper refcounting here, too. And there's no longer a
difference between the different types of images.
This commit is contained in:
Benjamin Otte 2016-12-08 21:14:41 +01:00
parent 17c11dd97b
commit 8756deec58
3 changed files with 65 additions and 44 deletions

View File

@ -109,14 +109,15 @@ gsk_vulkan_image_upload_data (GskVulkanImage *self,
}
static void
gsk_vulkan_image_ensure_view (GskVulkanImage *self)
gsk_vulkan_image_ensure_view (GskVulkanImage *self,
VkFormat format)
{
GSK_VK_CHECK (vkCreateImageView, gdk_vulkan_context_get_device (self->vulkan),
&(VkImageViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = self->vk_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = VK_FORMAT_B8G8R8A8_SRGB,
.format = format,
.components = {
.r = VK_COMPONENT_SWIZZLE_R,
.g = VK_COMPONENT_SWIZZLE_G,
@ -261,7 +262,7 @@ gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
/* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
g_object_unref (staging);
gsk_vulkan_image_ensure_view (self);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
return self;
}
@ -311,7 +312,7 @@ gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
}
});
gsk_vulkan_image_ensure_view (self);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
return self;
}
@ -330,6 +331,27 @@ gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
return gsk_vulkan_image_new_from_data_directly (context, command_buffer, data, width, height, stride);
}
GskVulkanImage *
gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
VkImage image,
VkFormat format,
gsize width,
gsize height)
{
GskVulkanImage *self;
self = g_object_new (GSK_TYPE_VULKAN_IMAGE, NULL);
self->vulkan = g_object_ref (context);
self->width = width;
self->height = height;
self->vk_image = image;
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
return self;
}
void
gsk_vulkan_image_finalize (GObject *object)
{
@ -342,11 +364,16 @@ gsk_vulkan_image_finalize (GObject *object)
NULL);
}
gsk_vulkan_memory_free (self->memory);
/* memory is NULL for for_swapchain() images, where we don't own
* the VkImage */
if (self->memory)
{
gsk_vulkan_memory_free (self->memory);
vkDestroyImage (gdk_vulkan_context_get_device (self->vulkan),
self->vk_image,
NULL);
vkDestroyImage (gdk_vulkan_context_get_device (self->vulkan),
self->vk_image,
NULL);
}
g_object_unref (self->vulkan);

View File

@ -9,6 +9,11 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GskVulkanImage, gsk_vulkan_image, GSK, VULKAN_IMAGE, GObject)
GskVulkanImage * gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
VkImage image,
VkFormat format,
gsize width,
gsize height);
GskVulkanImage * gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
VkCommandBuffer command_buffer,
guchar *data,

View File

@ -57,56 +57,37 @@ struct _GskVulkanRendererClass
G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_RENDERER)
struct _GskVulkanTarget {
VkImage image;
VkImageView image_view;
GskVulkanImage *image;
VkFramebuffer framebuffer;
};
static GskVulkanTarget *
gsk_vulkan_target_new_for_image (GskVulkanRenderer *self,
VkImage image)
VkImage image,
gsize width,
gsize height)
{
GskVulkanTarget *target;
GdkWindow *window;
VkDevice device;
device = gdk_vulkan_context_get_device (self->vulkan);
window = gdk_draw_context_get_window (GDK_DRAW_CONTEXT (self->vulkan));
target = g_slice_new0 (GskVulkanTarget);
target->image = image;
GSK_VK_CHECK (vkCreateImageView, device,
&(VkImageViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = target->image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = gdk_vulkan_context_get_image_format (self->vulkan),
.components = {
.r = VK_COMPONENT_SWIZZLE_R,
.g = VK_COMPONENT_SWIZZLE_G,
.b = VK_COMPONENT_SWIZZLE_B,
.a = VK_COMPONENT_SWIZZLE_A,
},
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
},
NULL,
&target->image_view);
target->image = gsk_vulkan_image_new_for_swapchain (self->vulkan,
image,
gdk_vulkan_context_get_image_format (self->vulkan),
width, height);
GSK_VK_CHECK (vkCreateFramebuffer, device,
&(VkFramebufferCreateInfo) {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = self->render_pass,
.attachmentCount = 1,
.pAttachments = &target->image_view,
.width = gdk_window_get_width (window),
.height = gdk_window_get_height (window),
.pAttachments = (VkImageView[1]) {
gsk_vulkan_image_get_image_view (target->image)
},
.width = width,
.height = height,
.layers = 1
},
NULL,
@ -126,9 +107,8 @@ gsk_vulkan_target_free (GskVulkanRenderer *self,
vkDestroyFramebuffer (device,
target->framebuffer,
NULL);
vkDestroyImageView (device,
target->image_view,
NULL);
g_object_unref (target->image);
g_slice_free (GskVulkanTarget, target);
}
@ -151,6 +131,9 @@ static void
gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context,
GskVulkanRenderer *self)
{
GdkWindow *window;
gint scale_factor;
gsize width, height;
guint i;
gsk_vulkan_renderer_free_targets (self);
@ -158,10 +141,16 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context,
self->n_targets = gdk_vulkan_context_get_n_images (context);
self->targets = g_new (GskVulkanTarget *, self->n_targets);
window = gsk_renderer_get_window (GSK_RENDERER (self));
scale_factor = gdk_window_get_scale_factor (window);
width = gdk_window_get_width (window) * scale_factor;
height = gdk_window_get_height (window) * scale_factor;
for (i = 0; i < self->n_targets; i++)
{
self->targets[i] = gsk_vulkan_target_new_for_image (self,
gdk_vulkan_context_get_image (context, i));
gdk_vulkan_context_get_image (context, i),
width, height);
}
}