forked from AuroraMiddleware/gtk
vulkan: acquire/present images when drawing
Another step towards the final goal of actually showing something.
This commit is contained in:
parent
06657fa23b
commit
8ba2898e08
@ -36,9 +36,12 @@ struct _GdkVulkanContextPrivate {
|
|||||||
|
|
||||||
int swapchain_width, swapchain_height;
|
int swapchain_width, swapchain_height;
|
||||||
VkSwapchainKHR swapchain;
|
VkSwapchainKHR swapchain;
|
||||||
|
VkSemaphore draw_semaphore;
|
||||||
|
|
||||||
guint n_images;
|
guint n_images;
|
||||||
VkImage *images;
|
VkImage *images;
|
||||||
|
|
||||||
|
uint32_t draw_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -121,13 +124,24 @@ gdk_vulkan_context_dispose (GObject *gobject)
|
|||||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (gobject);
|
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (gobject);
|
||||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
|
VkDevice device;
|
||||||
|
|
||||||
g_clear_pointer (&priv->images, g_free);
|
g_clear_pointer (&priv->images, g_free);
|
||||||
priv->n_images = 0;
|
priv->n_images = 0;
|
||||||
|
|
||||||
|
device = gdk_vulkan_context_get_device (context);
|
||||||
|
|
||||||
|
if (priv->draw_semaphore != VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
vkDestroySemaphore (device,
|
||||||
|
priv->draw_semaphore,
|
||||||
|
NULL);
|
||||||
|
priv->draw_semaphore = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->swapchain != VK_NULL_HANDLE)
|
if (priv->swapchain != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
vkDestroySwapchainKHR (gdk_vulkan_context_get_device (context),
|
vkDestroySwapchainKHR (device,
|
||||||
priv->swapchain,
|
priv->swapchain,
|
||||||
NULL);
|
NULL);
|
||||||
priv->swapchain = VK_NULL_HANDLE;
|
priv->swapchain = VK_NULL_HANDLE;
|
||||||
@ -149,36 +163,6 @@ gdk_vulkan_context_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (gdk_vulkan_context_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gdk_vulkan_context_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
gobject_class->dispose = gdk_vulkan_context_dispose;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GdkVulkanContext::images-updated:
|
|
||||||
* @context: the object on which the signal is emitted
|
|
||||||
*
|
|
||||||
* This signal is emitted when the images managed by this context have
|
|
||||||
* changed. Usually this means that the swapchain had to be recreated,
|
|
||||||
* for example in response to a change of the window size.
|
|
||||||
*/
|
|
||||||
signals[IMAGES_UPDATED] =
|
|
||||||
g_signal_new (g_intern_static_string ("images-updated"),
|
|
||||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL, NULL,
|
|
||||||
g_cclosure_marshal_VOID__VOID,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_vulkan_context_init (GdkVulkanContext *self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -259,8 +243,8 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
|||||||
|
|
||||||
if (res == VK_SUCCESS)
|
if (res == VK_SUCCESS)
|
||||||
{
|
{
|
||||||
priv->swapchain_width = gdk_window_get_width (window);
|
priv->swapchain_width = capabilities.currentExtent.width;
|
||||||
priv->swapchain_height = gdk_window_get_height (window);
|
priv->swapchain_height = capabilities.currentExtent.height;
|
||||||
priv->swapchain = new_swapchain;
|
priv->swapchain = new_swapchain;
|
||||||
|
|
||||||
GDK_VK_CHECK (vkGetSwapchainImagesKHR, device,
|
GDK_VK_CHECK (vkGetSwapchainImagesKHR, device,
|
||||||
@ -288,6 +272,84 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
|||||||
return res == VK_SUCCESS;
|
return res == VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
|
||||||
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!gdk_vulkan_context_check_swapchain (context, &error))
|
||||||
|
{
|
||||||
|
g_warning ("%s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
|
||||||
|
priv->swapchain,
|
||||||
|
UINT64_MAX,
|
||||||
|
priv->draw_semaphore,
|
||||||
|
VK_NULL_HANDLE,
|
||||||
|
&priv->draw_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||||
|
cairo_region_t *painted,
|
||||||
|
cairo_region_t *damage)
|
||||||
|
{
|
||||||
|
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
|
||||||
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
|
|
||||||
|
GDK_VK_CHECK (vkQueuePresentKHR, gdk_vulkan_context_get_queue (context),
|
||||||
|
&(VkPresentInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||||
|
.swapchainCount = 1,
|
||||||
|
.pSwapchains = (VkSwapchainKHR[]) {
|
||||||
|
priv->swapchain
|
||||||
|
},
|
||||||
|
.pImageIndices = (uint32_t[]) {
|
||||||
|
priv->draw_index
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->dispose = gdk_vulkan_context_dispose;
|
||||||
|
|
||||||
|
draw_context_class->begin_frame = gdk_vulkan_context_begin_frame;
|
||||||
|
draw_context_class->end_frame = gdk_vulkan_context_end_frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GdkVulkanContext::images-updated:
|
||||||
|
* @context: the object on which the signal is emitted
|
||||||
|
*
|
||||||
|
* This signal is emitted when the images managed by this context have
|
||||||
|
* changed. Usually this means that the swapchain had to be recreated,
|
||||||
|
* for example in response to a change of the window size.
|
||||||
|
*/
|
||||||
|
signals[IMAGES_UPDATED] =
|
||||||
|
g_signal_new (g_intern_static_string ("images-updated"),
|
||||||
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_vulkan_context_init (GdkVulkanContext *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_vulkan_context_real_init (GInitable *initable,
|
gdk_vulkan_context_real_init (GInitable *initable,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@ -350,6 +412,13 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
|||||||
if (!gdk_vulkan_context_check_swapchain (context, error))
|
if (!gdk_vulkan_context_check_swapchain (context, error))
|
||||||
goto out_surface;
|
goto out_surface;
|
||||||
|
|
||||||
|
GDK_VK_CHECK (vkCreateSemaphore, gdk_vulkan_context_get_device (context),
|
||||||
|
&(VkSemaphoreCreateInfo) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
|
},
|
||||||
|
NULL,
|
||||||
|
&priv->draw_semaphore);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +486,7 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context)
|
|||||||
return priv->image_format.format;
|
return priv->image_format.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
uint32_t
|
||||||
gdk_vulkan_context_get_n_images (GdkVulkanContext *context)
|
gdk_vulkan_context_get_n_images (GdkVulkanContext *context)
|
||||||
{
|
{
|
||||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
@ -439,6 +508,28 @@ gdk_vulkan_context_get_image (GdkVulkanContext *context,
|
|||||||
return priv->images[id];
|
return priv->images[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
gdk_vulkan_context_get_draw_index (GdkVulkanContext *context)
|
||||||
|
{
|
||||||
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), 0);
|
||||||
|
g_return_val_if_fail (gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context)), 0);
|
||||||
|
|
||||||
|
return priv->draw_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSemaphore
|
||||||
|
gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context)
|
||||||
|
{
|
||||||
|
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_NULL_HANDLE);
|
||||||
|
g_return_val_if_fail (gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context)), VK_NULL_HANDLE);
|
||||||
|
|
||||||
|
return priv->draw_semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_display_create_vulkan_device (GdkDisplay *display,
|
gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
@ -64,10 +64,14 @@ uint32_t gdk_vulkan_context_get_queue_family_index (GdkVulkanCo
|
|||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context);
|
VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
guint gdk_vulkan_context_get_n_images (GdkVulkanContext *context);
|
uint32_t gdk_vulkan_context_get_n_images (GdkVulkanContext *context);
|
||||||
GDK_AVAILABLE_IN_3_90
|
GDK_AVAILABLE_IN_3_90
|
||||||
VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context,
|
VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context,
|
||||||
guint id);
|
guint id);
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context);
|
||||||
|
GDK_AVAILABLE_IN_3_90
|
||||||
|
VkSemaphore gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context);
|
||||||
|
|
||||||
#endif /* GDK_WINDOWING_VULKAN */
|
#endif /* GDK_WINDOWING_VULKAN */
|
||||||
|
|
||||||
|
@ -285,6 +285,32 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkDrawingContext *
|
||||||
|
gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
|
||||||
|
const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||||
|
cairo_region_t *whole_window;
|
||||||
|
GdkDrawingContext *result;
|
||||||
|
GdkWindow *window;
|
||||||
|
|
||||||
|
window = gsk_renderer_get_window (renderer);
|
||||||
|
|
||||||
|
whole_window = cairo_region_create_rectangle (&(GdkRectangle) {
|
||||||
|
0, 0,
|
||||||
|
gdk_window_get_width (window),
|
||||||
|
gdk_window_get_height (window)
|
||||||
|
});
|
||||||
|
|
||||||
|
result = gdk_window_begin_draw_frame (window,
|
||||||
|
GDK_DRAW_CONTEXT (self->vulkan),
|
||||||
|
region);
|
||||||
|
|
||||||
|
cairo_region_destroy (whole_window);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
|
gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
|
||||||
{
|
{
|
||||||
@ -293,6 +319,7 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
|
|||||||
renderer_class->realize = gsk_vulkan_renderer_realize;
|
renderer_class->realize = gsk_vulkan_renderer_realize;
|
||||||
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
|
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
|
||||||
renderer_class->render = gsk_vulkan_renderer_render;
|
renderer_class->render = gsk_vulkan_renderer_render;
|
||||||
|
renderer_class->begin_draw_frame = gsk_vulkan_renderer_begin_draw_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user