mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
vulkan: Put the vertex buffer into the render object
Renderpasses get recreated every frame, but we keep render objects around. So if we keep the vertex buffer in the render object, we can also keep it around and just reuse it. Also, we only need one buffer for all the render passes, which is another bonus. The initial buffer size is chosen at 128kB. Maximized Nautilus, gnome-text-editor with an open file and widget-factory take ~100kB when doing a full redraw. Other apps are between 30-50kB usually. So I chose a value that is not too big, but catches ~90% of cases.
This commit is contained in:
parent
1abcf3d48a
commit
70c9521cae
@ -103,6 +103,12 @@ gsk_vulkan_buffer_get_buffer (GskVulkanBuffer *self)
|
||||
return self->vk_buffer;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_vulkan_buffer_get_size (GskVulkanBuffer *self)
|
||||
{
|
||||
return self->size;
|
||||
}
|
||||
|
||||
guchar *
|
||||
gsk_vulkan_buffer_map (GskVulkanBuffer *self)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@ GskVulkanBuffer * gsk_vulkan_buffer_new_map (GdkVulk
|
||||
void gsk_vulkan_buffer_free (GskVulkanBuffer *buffer);
|
||||
|
||||
VkBuffer gsk_vulkan_buffer_get_buffer (GskVulkanBuffer *self);
|
||||
gsize gsk_vulkan_buffer_get_size (GskVulkanBuffer *self);
|
||||
|
||||
guchar * gsk_vulkan_buffer_map (GskVulkanBuffer *self);
|
||||
void gsk_vulkan_buffer_unmap (GskVulkanBuffer *self);
|
||||
|
@ -57,7 +57,9 @@ static gsize
|
||||
gsk_vulkan_offscreen_op_count_vertex_data (GskVulkanOp *op,
|
||||
gsize n_bytes)
|
||||
{
|
||||
return n_bytes;
|
||||
GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
|
||||
|
||||
return gsk_vulkan_render_pass_count_vertex_data (self->render_pass, n_bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -66,6 +68,9 @@ gsk_vulkan_offscreen_op_collect_vertex_data (GskVulkanOp *op,
|
||||
GskVulkanRender *render,
|
||||
guchar *data)
|
||||
{
|
||||
GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
|
||||
|
||||
gsk_vulkan_render_pass_collect_vertex_data (self->render_pass, render, data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "gdk/gdkvulkancontextprivate.h"
|
||||
|
||||
#define DESCRIPTOR_POOL_MAXITEMS 50000
|
||||
#define VERTEX_BUFFER_SIZE_STEP 128 * 1024 /* 128kB */
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_descriptor_image_infos
|
||||
#define GDK_ARRAY_TYPE_NAME GskDescriptorImageInfos
|
||||
@ -60,6 +61,7 @@ struct _GskVulkanRender
|
||||
|
||||
GskVulkanImage *target;
|
||||
|
||||
GskVulkanBuffer *vertex_buffer;
|
||||
VkSampler samplers[3];
|
||||
GskVulkanBuffer *storage_buffer;
|
||||
guchar *storage_buffer_memory;
|
||||
@ -642,6 +644,27 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_render_collect_vertex_buffer (GskVulkanRender *self)
|
||||
{
|
||||
gsize n_bytes;
|
||||
guchar *data;
|
||||
|
||||
n_bytes = gsk_vulkan_render_pass_count_vertex_data (self->render_pass, 0);
|
||||
if (n_bytes == 0)
|
||||
return;
|
||||
|
||||
if (self->vertex_buffer && gsk_vulkan_buffer_get_size (self->vertex_buffer) < n_bytes)
|
||||
g_clear_pointer (&self->vertex_buffer, gsk_vulkan_buffer_free);
|
||||
|
||||
if (self->vertex_buffer == NULL)
|
||||
self->vertex_buffer = gsk_vulkan_buffer_new (self->vulkan, round_up (n_bytes, VERTEX_BUFFER_SIZE_STEP));
|
||||
|
||||
data = gsk_vulkan_buffer_map (self->vertex_buffer);
|
||||
gsk_vulkan_render_pass_collect_vertex_data (self->render_pass, self, data);
|
||||
gsk_vulkan_buffer_unmap (self->vertex_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_draw_pass (GskVulkanRender *self,
|
||||
GskVulkanRenderPass *pass,
|
||||
@ -651,6 +674,15 @@ gsk_vulkan_render_draw_pass (GskVulkanRender *self,
|
||||
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
|
||||
|
||||
if (self->vertex_buffer)
|
||||
vkCmdBindVertexBuffers (command_buffer,
|
||||
0,
|
||||
1,
|
||||
(VkBuffer[1]) {
|
||||
gsk_vulkan_buffer_get_buffer (self->vertex_buffer)
|
||||
},
|
||||
(VkDeviceSize[1]) { 0 });
|
||||
|
||||
gsk_vulkan_render_pass_draw (pass, self, self->pipeline_layout, command_buffer);
|
||||
|
||||
gsk_vulkan_command_pool_submit_buffer (self->command_pool,
|
||||
@ -672,6 +704,8 @@ gsk_vulkan_render_draw (GskVulkanRender *self)
|
||||
|
||||
gsk_vulkan_render_prepare_descriptor_sets (self);
|
||||
|
||||
gsk_vulkan_render_collect_vertex_buffer (self);
|
||||
|
||||
gsk_vulkan_render_draw_pass (self,
|
||||
self->render_pass,
|
||||
self->fence);
|
||||
@ -747,6 +781,8 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
|
||||
gsk_vulkan_render_cleanup (self);
|
||||
|
||||
g_clear_pointer (&self->vertex_buffer, gsk_vulkan_buffer_free);
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->pipeline_cache);
|
||||
|
@ -60,7 +60,6 @@ struct _GskVulkanRenderPass
|
||||
|
||||
VkRenderPass render_pass;
|
||||
VkFramebuffer framebuffer;
|
||||
GskVulkanBuffer *vertex_data;
|
||||
};
|
||||
|
||||
struct _GskVulkanParseState
|
||||
@ -181,8 +180,6 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context,
|
||||
NULL,
|
||||
&self->framebuffer);
|
||||
|
||||
self->vertex_data = NULL;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (fallback_pixels_quark == 0)
|
||||
{
|
||||
@ -219,9 +216,6 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
|
||||
vkDestroyFramebuffer (device, self->framebuffer, NULL);
|
||||
vkDestroyRenderPass (device, self->render_pass, NULL);
|
||||
|
||||
if (self->vertex_data)
|
||||
gsk_vulkan_buffer_free (self->vertex_data);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
@ -241,12 +235,6 @@ gsk_vulkan_render_pass_print (GskVulkanRenderPass *self,
|
||||
}
|
||||
}
|
||||
|
||||
static inline gsize
|
||||
round_up (gsize number, gsize divisor)
|
||||
{
|
||||
return (number + divisor - 1) / divisor * divisor;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gsk_vulkan_render_pass_alloc_op (GskVulkanRenderPass *self,
|
||||
gsize size)
|
||||
@ -1422,13 +1410,12 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
}
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
||||
gsize
|
||||
gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self,
|
||||
gsize n_bytes)
|
||||
{
|
||||
GskVulkanOp *op;
|
||||
gsize n_bytes;
|
||||
|
||||
n_bytes = 0;
|
||||
for (op = gsk_vulkan_render_pass_get_first_op (self); op; op = op->next)
|
||||
{
|
||||
n_bytes = gsk_vulkan_op_count_vertex_data (op, n_bytes);
|
||||
@ -1437,7 +1424,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
guchar *data)
|
||||
@ -1450,28 +1437,6 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
}
|
||||
}
|
||||
|
||||
static GskVulkanBuffer *
|
||||
gsk_vulkan_render_pass_get_vertex_data (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render)
|
||||
{
|
||||
if (self->vertex_data == NULL)
|
||||
{
|
||||
gsize n_bytes;
|
||||
guchar *data;
|
||||
|
||||
n_bytes = gsk_vulkan_render_pass_count_vertex_data (self);
|
||||
if (n_bytes == 0)
|
||||
return NULL;
|
||||
|
||||
self->vertex_data = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
|
||||
data = gsk_vulkan_buffer_map (self->vertex_data);
|
||||
gsk_vulkan_render_pass_collect_vertex_data (self, render, data);
|
||||
gsk_vulkan_buffer_unmap (self->vertex_data);
|
||||
}
|
||||
|
||||
return self->vertex_data;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render)
|
||||
@ -1493,20 +1458,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self,
|
||||
VkPipeline current_pipeline = VK_NULL_HANDLE;
|
||||
const GskVulkanOpClass *current_pipeline_class = NULL;
|
||||
const char *current_pipeline_clip_type = NULL;
|
||||
GskVulkanBuffer *vertex_buffer;
|
||||
GskVulkanOp *op;
|
||||
|
||||
vertex_buffer = gsk_vulkan_render_pass_get_vertex_data (self, render);
|
||||
|
||||
if (vertex_buffer)
|
||||
vkCmdBindVertexBuffers (command_buffer,
|
||||
0,
|
||||
1,
|
||||
(VkBuffer[1]) {
|
||||
gsk_vulkan_buffer_get_buffer (vertex_buffer)
|
||||
},
|
||||
(VkDeviceSize[1]) { 0 });
|
||||
|
||||
for (op = gsk_vulkan_render_pass_get_first_op (self); op; op = op->next)
|
||||
{
|
||||
if (op->op_class->shader_name &&
|
||||
|
@ -33,6 +33,11 @@ void gsk_vulkan_render_pass_upload (GskVulk
|
||||
GskVulkanUploader *uploader);
|
||||
void gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render);
|
||||
gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self,
|
||||
gsize n_bytes);
|
||||
void gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
guchar *data);
|
||||
void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
VkPipelineLayout pipeline_layout,
|
||||
|
Loading…
Reference in New Issue
Block a user