gpu: Completely revamp descriptor set handling
Instead of trying to cram all descriptors into one large array and only binding it at the start, we now keep 1 descriptor set per image+sampler combo and just rebind it every time we switch textures. This is the very dumb solution that essentially maps to what GL does, but the performance impact is negligible compared to the complicated dance we were attempting before.
This commit is contained in:
@@ -50,8 +50,7 @@ gsk_gpu_globals_op_vk_command (GskGpuOp *op,
|
||||
GskGpuGlobalsOp *self = (GskGpuGlobalsOp *) op;
|
||||
|
||||
vkCmdPushConstants (state->vk_command_buffer,
|
||||
NULL, //gsk_vulkan_device_get_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
|
||||
// gsk_vulkan_descriptors_get_pipeline_layout (state->desc)),
|
||||
gsk_vulkan_device_get_default_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame))),
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0,
|
||||
sizeof (self->instance),
|
||||
|
||||
@@ -71,10 +71,8 @@ static void
|
||||
gsk_gpu_render_pass_op_do_barriers (GskGpuRenderPassOp *self,
|
||||
GskVulkanCommandState *state)
|
||||
{
|
||||
#if 0
|
||||
GskGpuShaderOp *shader;
|
||||
GskGpuOp *op;
|
||||
GskGpuDescriptors *desc = NULL;
|
||||
|
||||
for (op = ((GskGpuOp *) self)->next;
|
||||
op->op_class->stage != GSK_GPU_STAGE_END_PASS;
|
||||
@@ -85,21 +83,21 @@ gsk_gpu_render_pass_op_do_barriers (GskGpuRenderPassOp *self,
|
||||
|
||||
shader = (GskGpuShaderOp *) op;
|
||||
|
||||
if (shader->desc == NULL || shader->desc == desc)
|
||||
continue;
|
||||
|
||||
if (desc == NULL)
|
||||
{
|
||||
gsk_vulkan_descriptors_bind (GSK_VULKAN_DESCRIPTORS (shader->desc), state->desc, state->vk_command_buffer);
|
||||
state->desc = GSK_VULKAN_DESCRIPTORS (shader->desc);
|
||||
}
|
||||
desc = shader->desc;
|
||||
gsk_vulkan_descriptors_transition (GSK_VULKAN_DESCRIPTORS (desc), state->semaphores, state->vk_command_buffer);
|
||||
if (shader->images[0])
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (shader->images[0]),
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT);
|
||||
if (shader->images[1])
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (shader->images[1]),
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_SHADER_READ_BIT);
|
||||
}
|
||||
|
||||
if (desc == NULL)
|
||||
gsk_vulkan_descriptors_transition (state->desc, state->semaphores, state->vk_command_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GskGpuOp *
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "gskglimageprivate.h"
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
#include "gskvulkandeviceprivate.h"
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#endif
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
@@ -67,10 +68,10 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
|
||||
GskVulkanCommandState *state,
|
||||
gsize instance_scale)
|
||||
{
|
||||
#if 0
|
||||
GskGpuShaderOp *self = (GskGpuShaderOp *) op;
|
||||
GskGpuShaderOpClass *shader_op_class = (GskGpuShaderOpClass *) op->op_class;
|
||||
GskGpuOp *next;
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
gsize i, n_ops, max_ops_per_draw;
|
||||
|
||||
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MERGE) &&
|
||||
@@ -80,33 +81,43 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
|
||||
else
|
||||
max_ops_per_draw = 1;
|
||||
|
||||
desc = GSK_VULKAN_DESCRIPTORS (self->desc);
|
||||
if (desc && state->desc != desc)
|
||||
{
|
||||
gsk_vulkan_descriptors_bind (desc, state->desc, state->vk_command_buffer);
|
||||
state->desc = desc;
|
||||
}
|
||||
|
||||
n_ops = self->n_ops;
|
||||
for (next = op->next; next; next = next->next)
|
||||
{
|
||||
GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next;
|
||||
|
||||
if (next->op_class != op->op_class ||
|
||||
next_shader->desc != self->desc ||
|
||||
next_shader->flags != self->flags ||
|
||||
next_shader->color_states != self->color_states ||
|
||||
next_shader->variation != self->variation ||
|
||||
next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size)
|
||||
next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size ||
|
||||
(shader_op_class->n_textures > 0 && (next_shader->images[0] != self->images[0] || next_shader->samplers[0] != self->samplers[0])) ||
|
||||
(shader_op_class->n_textures > 1 && (next_shader->images[1] != self->images[1] || next_shader->samplers[1] != self->samplers[1])))
|
||||
break;
|
||||
|
||||
n_ops += next_shader->n_ops;
|
||||
}
|
||||
|
||||
vk_pipeline_layout = gsk_vulkan_device_get_default_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)));
|
||||
|
||||
for (i = 0; i < shader_op_class->n_textures; i++)
|
||||
{
|
||||
vkCmdBindDescriptorSets (state->vk_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
vk_pipeline_layout,
|
||||
i,
|
||||
1,
|
||||
(VkDescriptorSet[1]) {
|
||||
gsk_vulkan_image_get_vk_descriptor_set (GSK_VULKAN_IMAGE (self->images[i]), self->samplers[i]),
|
||||
},
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
vkCmdBindPipeline (state->vk_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
gsk_vulkan_device_get_vk_pipeline (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
|
||||
gsk_vulkan_descriptors_get_pipeline_layout (state->desc),
|
||||
vk_pipeline_layout,
|
||||
shader_op_class,
|
||||
self->flags,
|
||||
self->color_states,
|
||||
@@ -123,8 +134,6 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
|
||||
}
|
||||
|
||||
return next;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GskGpuOp *
|
||||
|
||||
@@ -25,11 +25,13 @@ struct _GskVulkanDevice
|
||||
|
||||
GHashTable *conversion_cache;
|
||||
GHashTable *render_pass_cache;
|
||||
GHashTable *pipeline_layouts;
|
||||
GskVulkanPipelineLayout *pipeline_layout_cache;
|
||||
GHashTable *pipeline_cache;
|
||||
|
||||
VkCommandPool vk_command_pool;
|
||||
VkDescriptorPool vk_descriptor_pool;
|
||||
VkSampler vk_samplers[GSK_GPU_SAMPLER_N_SAMPLERS];
|
||||
VkDescriptorSetLayout vk_image_set_layout;
|
||||
VkPipelineLayout default_vk_pipeline_layout;
|
||||
};
|
||||
|
||||
struct _GskVulkanDeviceClass
|
||||
@@ -42,28 +44,6 @@ G_DEFINE_TYPE (GskVulkanDevice, gsk_vulkan_device, GSK_TYPE_GPU_DEVICE)
|
||||
typedef struct _ConversionCacheEntry ConversionCacheEntry;
|
||||
typedef struct _PipelineCacheKey PipelineCacheKey;
|
||||
typedef struct _RenderPassCacheKey RenderPassCacheKey;
|
||||
typedef struct _GskVulkanPipelineLayoutSetup GskVulkanPipelineLayoutSetup;
|
||||
|
||||
struct _GskVulkanPipelineLayoutSetup
|
||||
{
|
||||
gsize n_buffers;
|
||||
gsize n_samplers;
|
||||
gsize n_immutable_samplers;
|
||||
VkSampler *immutable_samplers;
|
||||
};
|
||||
|
||||
struct _GskVulkanPipelineLayout
|
||||
{
|
||||
gint ref_count;
|
||||
|
||||
VkDescriptorSetLayout vk_buffer_set_layout;
|
||||
VkDescriptorSetLayout vk_image_set_layout;
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
GHashTable *pipeline_cache;
|
||||
|
||||
GskVulkanPipelineLayoutSetup setup;
|
||||
VkSampler samplers[];
|
||||
};
|
||||
|
||||
struct _ConversionCacheEntry
|
||||
{
|
||||
@@ -81,8 +61,9 @@ struct _PipelineCacheKey
|
||||
GskGpuColorStates color_states;
|
||||
guint32 variation;
|
||||
GskGpuBlend blend;
|
||||
VkFormat format;
|
||||
VkPipeline pipeline;
|
||||
VkFormat vk_format;
|
||||
VkPipelineLayout vk_layout;
|
||||
VkPipeline vk_pipeline;
|
||||
};
|
||||
|
||||
struct _RenderPassCacheKey
|
||||
@@ -121,7 +102,8 @@ pipeline_cache_key_hash (gconstpointer data)
|
||||
(key->color_states << 8) ^
|
||||
(key->variation << 16) ^
|
||||
(key->blend << 24) ^
|
||||
(key->format << 21) ^ (key->format >> 11);
|
||||
GPOINTER_TO_UINT (key->vk_layout) ^
|
||||
(key->vk_format << 21) ^ (key->vk_format >> 11);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -136,7 +118,8 @@ pipeline_cache_key_equal (gconstpointer a,
|
||||
keya->color_states == keyb->color_states &&
|
||||
keya->variation == keyb->variation &&
|
||||
keya->blend == keyb->blend &&
|
||||
keya->format == keyb->format;
|
||||
keya->vk_layout == keyb->vk_layout &&
|
||||
keya->vk_format == keyb->vk_format;
|
||||
}
|
||||
|
||||
static guint
|
||||
@@ -161,65 +144,16 @@ render_pass_cache_key_equal (gconstpointer a,
|
||||
keya->format == keyb->format;
|
||||
}
|
||||
|
||||
static GskVulkanPipelineLayout *
|
||||
gsk_vulkan_pipeline_layout_new (GskVulkanDevice *self,
|
||||
const GskVulkanPipelineLayoutSetup *setup)
|
||||
static VkDescriptorSetLayout
|
||||
gsk_vulkan_device_create_vk_image_set_layout (GskVulkanDevice *self,
|
||||
VkSampler immutable_sampler)
|
||||
{
|
||||
GskVulkanPipelineLayout *layout;
|
||||
GdkDisplay *display;
|
||||
gboolean descriptor_indexing;
|
||||
|
||||
descriptor_indexing = gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING);
|
||||
VkDevice vk_device;
|
||||
VkDescriptorSetLayout result;
|
||||
|
||||
layout = g_malloc (sizeof (GskVulkanPipelineLayout) + setup->n_immutable_samplers * sizeof (VkSampler));
|
||||
layout->ref_count = 1;
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self);
|
||||
|
||||
layout->setup = *setup;
|
||||
if (setup->n_immutable_samplers)
|
||||
memcpy (layout->samplers, setup->immutable_samplers, setup->n_immutable_samplers * sizeof (VkSampler));
|
||||
layout->setup.immutable_samplers = layout->samplers;
|
||||
layout->pipeline_cache = g_hash_table_new (pipeline_cache_key_hash, pipeline_cache_key_equal);
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
|
||||
GSK_VK_CHECK (vkCreateDescriptorSetLayout, display->vk_device,
|
||||
&(VkDescriptorSetLayoutCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = 2,
|
||||
.flags = 0,
|
||||
.pBindings = (VkDescriptorSetLayoutBinding[2]) {
|
||||
{
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = MAX (1, layout->setup.n_immutable_samplers),
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = layout->setup.n_immutable_samplers
|
||||
? layout->setup.immutable_samplers
|
||||
: (VkSampler[1]) {
|
||||
gsk_vulkan_device_get_vk_sampler (self, GSK_GPU_SAMPLER_DEFAULT)
|
||||
},
|
||||
},
|
||||
{
|
||||
.binding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = layout->setup.n_samplers,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
}
|
||||
},
|
||||
.pNext = !descriptor_indexing ? NULL : &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
.bindingCount = 2,
|
||||
.pBindingFlags = (VkDescriptorBindingFlags[2]) {
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
|
||||
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
|
||||
},
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&layout->vk_image_set_layout);
|
||||
|
||||
GSK_VK_CHECK (vkCreateDescriptorSetLayout, display->vk_device,
|
||||
GSK_VK_CHECK (vkCreateDescriptorSetLayout, vk_device,
|
||||
&(VkDescriptorSetLayoutCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = 1,
|
||||
@@ -227,30 +161,38 @@ gsk_vulkan_pipeline_layout_new (GskVulkanDevice *self,
|
||||
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
|
||||
{
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = layout->setup.n_buffers,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
},
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = immutable_sampler == VK_NULL_HANDLE ? NULL : (VkSampler[1]) {
|
||||
immutable_sampler,
|
||||
},
|
||||
}
|
||||
},
|
||||
.pNext = !descriptor_indexing ? NULL : &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
.bindingCount = 1,
|
||||
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
|
||||
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
|
||||
},
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&layout->vk_buffer_set_layout);
|
||||
&result);
|
||||
|
||||
GSK_VK_CHECK (vkCreatePipelineLayout, display->vk_device,
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkPipelineLayout
|
||||
gsk_vulkan_device_create_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
VkDescriptorSetLayout image1_layout,
|
||||
VkDescriptorSetLayout image2_layout)
|
||||
{
|
||||
VkDevice vk_device;
|
||||
VkPipelineLayout result;
|
||||
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self);
|
||||
|
||||
GSK_VK_CHECK (vkCreatePipelineLayout, vk_device,
|
||||
&(VkPipelineLayoutCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 2,
|
||||
.pSetLayouts = (VkDescriptorSetLayout[2]) {
|
||||
layout->vk_image_set_layout,
|
||||
layout->vk_buffer_set_layout,
|
||||
image1_layout,
|
||||
image2_layout,
|
||||
},
|
||||
.pushConstantRangeCount = 1,
|
||||
.pPushConstantRanges = (VkPushConstantRange[1]) {
|
||||
@@ -262,106 +204,11 @@ gsk_vulkan_pipeline_layout_new (GskVulkanDevice *self,
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&layout->vk_pipeline_layout);
|
||||
|
||||
g_hash_table_insert (self->pipeline_layouts, &layout->setup, layout);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_pipeline_layout_unref (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
layout->ref_count--;
|
||||
if (layout->ref_count)
|
||||
return;
|
||||
|
||||
if (!g_hash_table_remove (self->pipeline_layouts, &layout->setup))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
|
||||
vkDestroyDescriptorSetLayout (display->vk_device,
|
||||
layout->vk_image_set_layout,
|
||||
NULL);
|
||||
vkDestroyDescriptorSetLayout (display->vk_device,
|
||||
layout->vk_buffer_set_layout,
|
||||
NULL);
|
||||
|
||||
vkDestroyPipelineLayout (display->vk_device,
|
||||
layout->vk_pipeline_layout,
|
||||
NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, layout->pipeline_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
vkDestroyPipeline (display->vk_device,
|
||||
((PipelineCacheKey *)key)->pipeline,
|
||||
NULL);
|
||||
g_free (key);
|
||||
}
|
||||
g_hash_table_unref (layout->pipeline_cache);
|
||||
|
||||
g_free (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_pipeline_layout_ref (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
{
|
||||
layout->ref_count++;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_vulkan_pipeline_layout_setup_hash (gconstpointer data)
|
||||
{
|
||||
const GskVulkanPipelineLayoutSetup *setup = data;
|
||||
guint result;
|
||||
gsize i;
|
||||
|
||||
result = (setup->n_buffers << 23) |
|
||||
(setup->n_samplers << 7) |
|
||||
setup->n_immutable_samplers;
|
||||
|
||||
for (i = 0; i < setup->n_immutable_samplers; i++)
|
||||
{
|
||||
result = (result << 13) ^
|
||||
GPOINTER_TO_SIZE (setup->immutable_samplers[i]) ^
|
||||
(GPOINTER_TO_SIZE (setup->immutable_samplers[i]) >> 32);
|
||||
}
|
||||
&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_vulkan_pipeline_layout_setup_equal (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const GskVulkanPipelineLayoutSetup *setupa = a;
|
||||
const GskVulkanPipelineLayoutSetup *setupb = b;
|
||||
gsize i;
|
||||
|
||||
if (setupa->n_buffers != setupb->n_buffers ||
|
||||
setupa->n_samplers != setupb->n_samplers ||
|
||||
setupa->n_immutable_samplers != setupb->n_immutable_samplers)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < setupa->n_immutable_samplers; i++)
|
||||
{
|
||||
if (setupa->immutable_samplers[i] != setupb->immutable_samplers[i])
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_vulkan_device_create_offscreen_image (GskGpuDevice *device,
|
||||
gboolean with_mipmap,
|
||||
@@ -448,26 +295,33 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
{
|
||||
GskVulkanDevice *self = GSK_VULKAN_DEVICE (object);
|
||||
GskGpuDevice *device = GSK_GPU_DEVICE (self);
|
||||
VkDevice vk_device;
|
||||
GdkDisplay *display;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gsize i;
|
||||
|
||||
g_object_steal_data (G_OBJECT (gsk_gpu_device_get_display (device)), "-gsk-vulkan-device");
|
||||
|
||||
display = gsk_gpu_device_get_display (device);
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self);
|
||||
|
||||
if (self->pipeline_layout_cache)
|
||||
gsk_vulkan_pipeline_layout_unref (self, self->pipeline_layout_cache);
|
||||
g_assert (g_hash_table_size (self->pipeline_layouts) == 0);
|
||||
g_hash_table_unref (self->pipeline_layouts);
|
||||
g_object_steal_data (G_OBJECT (display), "-gsk-vulkan-device");
|
||||
|
||||
g_hash_table_iter_init (&iter, self->pipeline_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
vkDestroyPipeline (vk_device,
|
||||
((PipelineCacheKey *)key)->vk_pipeline,
|
||||
NULL);
|
||||
g_free (key);
|
||||
}
|
||||
g_hash_table_unref (self->pipeline_cache);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->conversion_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
ConversionCacheEntry *entry = key;
|
||||
vkDestroySamplerYcbcrConversion (display->vk_device, entry->vk_conversion, NULL);
|
||||
vkDestroySampler (display->vk_device, entry->vk_sampler, NULL);
|
||||
vkDestroySamplerYcbcrConversion (vk_device, entry->vk_conversion, NULL);
|
||||
vkDestroySampler (vk_device, entry->vk_sampler, NULL);
|
||||
g_free (key);
|
||||
}
|
||||
g_hash_table_unref (self->conversion_cache);
|
||||
@@ -475,7 +329,7 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
g_hash_table_iter_init (&iter, self->render_pass_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
vkDestroyRenderPass (display->vk_device,
|
||||
vkDestroyRenderPass (vk_device,
|
||||
((RenderPassCacheKey *)key)->render_pass,
|
||||
NULL);
|
||||
g_free (key);
|
||||
@@ -485,12 +339,21 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
for (i = 0; i < G_N_ELEMENTS (self->vk_samplers); i++)
|
||||
{
|
||||
if (self->vk_samplers[i] != VK_NULL_HANDLE)
|
||||
vkDestroySampler (display->vk_device,
|
||||
vkDestroySampler (vk_device,
|
||||
self->vk_samplers[i],
|
||||
NULL);
|
||||
}
|
||||
|
||||
vkDestroyCommandPool (display->vk_device,
|
||||
vkDestroyPipelineLayout (vk_device,
|
||||
self->default_vk_pipeline_layout,
|
||||
NULL);
|
||||
vkDestroyDescriptorSetLayout (vk_device,
|
||||
self->vk_image_set_layout,
|
||||
NULL);
|
||||
vkDestroyDescriptorPool (vk_device,
|
||||
self->vk_descriptor_pool,
|
||||
NULL);
|
||||
vkDestroyCommandPool (vk_device,
|
||||
self->vk_command_pool,
|
||||
NULL);
|
||||
|
||||
@@ -523,24 +386,45 @@ gsk_vulkan_device_init (GskVulkanDevice *self)
|
||||
{
|
||||
self->conversion_cache = g_hash_table_new (conversion_cache_entry_hash, conversion_cache_entry_equal);
|
||||
self->render_pass_cache = g_hash_table_new (render_pass_cache_key_hash, render_pass_cache_key_equal);
|
||||
self->pipeline_layouts = g_hash_table_new (gsk_vulkan_pipeline_layout_setup_hash, gsk_vulkan_pipeline_layout_setup_equal);
|
||||
self->pipeline_cache = g_hash_table_new (pipeline_cache_key_hash, pipeline_cache_key_equal);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_device_create_vk_objects (GskVulkanDevice *self)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
VkDevice vk_device;
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self);
|
||||
|
||||
GSK_VK_CHECK (vkCreateCommandPool, display->vk_device,
|
||||
GSK_VK_CHECK (vkCreateCommandPool, vk_device,
|
||||
&(const VkCommandPoolCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
.queueFamilyIndex = display->vk_queue_family_index,
|
||||
.queueFamilyIndex = gsk_vulkan_device_get_vk_queue_family_index (self),
|
||||
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
||||
},
|
||||
NULL,
|
||||
&self->vk_command_pool);
|
||||
GSK_VK_CHECK (vkCreateDescriptorPool, vk_device,
|
||||
&(VkDescriptorPoolCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
.maxSets = 10000,
|
||||
.poolSizeCount = 1,
|
||||
.pPoolSizes = (VkDescriptorPoolSize[1]) {
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 10000,
|
||||
},
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&self->vk_descriptor_pool);
|
||||
|
||||
self->vk_image_set_layout = gsk_vulkan_device_create_vk_image_set_layout (self, NULL);
|
||||
|
||||
self->default_vk_pipeline_layout = gsk_vulkan_device_create_vk_pipeline_layout (self,
|
||||
self->vk_image_set_layout,
|
||||
self->vk_image_set_layout);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -656,24 +540,15 @@ gsk_vulkan_device_get_vk_queue_family_index (GskVulkanDevice *self)
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout
|
||||
gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self)
|
||||
{
|
||||
return layout->vk_image_set_layout;
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout
|
||||
gsk_vulkan_device_get_vk_buffer_set_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
{
|
||||
return layout->vk_buffer_set_layout;
|
||||
return self->vk_image_set_layout;
|
||||
}
|
||||
|
||||
VkPipelineLayout
|
||||
gsk_vulkan_device_get_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
gsk_vulkan_device_get_default_vk_pipeline_layout (GskVulkanDevice *self)
|
||||
{
|
||||
return layout->vk_pipeline_layout;
|
||||
return self->default_vk_pipeline_layout;
|
||||
}
|
||||
|
||||
VkCommandPool
|
||||
@@ -682,6 +557,12 @@ gsk_vulkan_device_get_vk_command_pool (GskVulkanDevice *self)
|
||||
return self->vk_command_pool;
|
||||
}
|
||||
|
||||
VkDescriptorPool
|
||||
gsk_vulkan_device_get_vk_descriptor_pool (GskVulkanDevice *self)
|
||||
{
|
||||
return self->vk_descriptor_pool;
|
||||
}
|
||||
|
||||
static VkSampler
|
||||
gsk_vulkan_device_create_sampler (GskVulkanDevice *self,
|
||||
VkSamplerYcbcrConversion vk_conversion,
|
||||
@@ -906,9 +787,6 @@ typedef struct _GskVulkanShaderSpecialization GskVulkanShaderSpecialization;
|
||||
struct _GskVulkanShaderSpecialization
|
||||
{
|
||||
guint32 flags;
|
||||
guint32 n_immutable_samplers;
|
||||
guint32 n_samplers;
|
||||
guint32 n_buffers;
|
||||
guint32 color_states;
|
||||
guint32 variation;
|
||||
};
|
||||
@@ -964,18 +842,18 @@ static VkPipelineColorBlendAttachmentState blend_attachment_states[4] = {
|
||||
|
||||
VkPipeline
|
||||
gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout,
|
||||
VkPipelineLayout vk_layout,
|
||||
const GskGpuShaderOpClass *op_class,
|
||||
GskGpuShaderFlags flags,
|
||||
GskGpuColorStates color_states,
|
||||
guint32 variation,
|
||||
GskGpuBlend blend,
|
||||
VkFormat format,
|
||||
VkFormat vk_format,
|
||||
VkRenderPass render_pass)
|
||||
{
|
||||
PipelineCacheKey cache_key;
|
||||
PipelineCacheKey *cached_result;
|
||||
VkPipeline pipeline;
|
||||
VkPipeline vk_pipeline;
|
||||
GdkDisplay *display;
|
||||
const char *version_string;
|
||||
char *vertex_shader_name, *fragment_shader_name;
|
||||
@@ -983,16 +861,17 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
const char *blend_name[] = { "NONE", "OVER", "ADD", "CLEAR" };
|
||||
|
||||
cache_key = (PipelineCacheKey) {
|
||||
.vk_layout = vk_layout,
|
||||
.op_class = op_class,
|
||||
.color_states = color_states,
|
||||
.variation = variation,
|
||||
.flags = flags,
|
||||
.blend = blend,
|
||||
.format = format,
|
||||
.vk_format = vk_format,
|
||||
};
|
||||
cached_result = g_hash_table_lookup (layout->pipeline_cache, &cache_key);
|
||||
cached_result = g_hash_table_lookup (self->pipeline_cache, &cache_key);
|
||||
if (cached_result)
|
||||
return cached_result->pipeline;
|
||||
return cached_result->vk_pipeline;
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
if (gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_DYNAMIC_INDEXING) &&
|
||||
@@ -1024,7 +903,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.module = gdk_display_get_vk_shader_module (display, vertex_shader_name),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = &(VkSpecializationInfo) {
|
||||
.mapEntryCount = 6,
|
||||
.mapEntryCount = 3,
|
||||
.pMapEntries = (VkSpecializationMapEntry[6]) {
|
||||
{
|
||||
.constantID = 0,
|
||||
@@ -1033,26 +912,11 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
},
|
||||
{
|
||||
.constantID = 1,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_immutable_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 2,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 3,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_buffers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 4,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, color_states),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 5,
|
||||
.constantID = 2,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, variation),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
@@ -1060,9 +924,6 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.dataSize = sizeof (GskVulkanShaderSpecialization),
|
||||
.pData = &(GskVulkanShaderSpecialization) {
|
||||
.flags = flags,
|
||||
.n_immutable_samplers = MAX (1, layout->setup.n_immutable_samplers),
|
||||
.n_samplers = layout->setup.n_samplers - MAX (3 * layout->setup.n_immutable_samplers, 1),
|
||||
.n_buffers = layout->setup.n_buffers,
|
||||
.color_states = color_states,
|
||||
.variation = variation,
|
||||
},
|
||||
@@ -1074,7 +935,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.module = gdk_display_get_vk_shader_module (display, fragment_shader_name),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = &(VkSpecializationInfo) {
|
||||
.mapEntryCount = 6,
|
||||
.mapEntryCount = 3,
|
||||
.pMapEntries = (VkSpecializationMapEntry[6]) {
|
||||
{
|
||||
.constantID = 0,
|
||||
@@ -1083,26 +944,11 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
},
|
||||
{
|
||||
.constantID = 1,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_immutable_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 2,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 3,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_buffers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 4,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, color_states),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 5,
|
||||
.constantID = 2,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, variation),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
@@ -1110,9 +956,6 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.dataSize = sizeof (GskVulkanShaderSpecialization),
|
||||
.pData = &(GskVulkanShaderSpecialization) {
|
||||
.flags = flags,
|
||||
.n_immutable_samplers = MAX (1, layout->setup.n_immutable_samplers),
|
||||
.n_samplers = layout->setup.n_samplers - MAX (3 * layout->setup.n_immutable_samplers, 1),
|
||||
.n_buffers = layout->setup.n_buffers,
|
||||
.color_states = color_states,
|
||||
.variation = variation,
|
||||
},
|
||||
@@ -1161,14 +1004,14 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
},
|
||||
},
|
||||
.layout = layout->vk_pipeline_layout,
|
||||
.layout = vk_layout,
|
||||
.renderPass = render_pass,
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = -1,
|
||||
},
|
||||
NULL,
|
||||
&pipeline);
|
||||
&vk_pipeline);
|
||||
|
||||
gdk_profiler_end_markf (begin_time,
|
||||
"Create Vulkan pipeline", "%s version=%s color states=%u variation=%u clip=%u blend=%s format=%u",
|
||||
@@ -1178,83 +1021,27 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
color_states,
|
||||
variation,
|
||||
blend_name[blend],
|
||||
format);
|
||||
vk_format);
|
||||
|
||||
GSK_DEBUG (SHADERS,
|
||||
"Create Vulkan pipeline (%s %s, %u/%u/%u/%s/%u) for layout (%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT ")",
|
||||
"Create Vulkan pipeline (%s %s, %u/%u/%u/%s/%u)",
|
||||
op_class->shader_name,
|
||||
version_string + 1,
|
||||
flags,
|
||||
color_states,
|
||||
variation,
|
||||
blend_name[blend],
|
||||
format,
|
||||
layout->setup.n_buffers,
|
||||
layout->setup.n_samplers,
|
||||
layout->setup.n_immutable_samplers);
|
||||
vk_format);
|
||||
|
||||
g_free (fragment_shader_name);
|
||||
g_free (vertex_shader_name);
|
||||
|
||||
cached_result = g_memdup (&cache_key, sizeof (PipelineCacheKey));
|
||||
cached_result->pipeline = pipeline;
|
||||
g_hash_table_insert (layout->pipeline_cache, cached_result, cached_result);
|
||||
cached_result->vk_pipeline = vk_pipeline;
|
||||
g_hash_table_add (self->pipeline_cache, cached_result);
|
||||
gdk_display_vulkan_pipeline_cache_updated (display);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
GskVulkanPipelineLayout *
|
||||
gsk_vulkan_device_acquire_pipeline_layout (GskVulkanDevice *self,
|
||||
VkSampler *immutable_samplers,
|
||||
gsize n_immutable_samplers,
|
||||
gsize n_samplers,
|
||||
gsize n_buffers)
|
||||
{
|
||||
GskVulkanPipelineLayoutSetup setup;
|
||||
GskVulkanPipelineLayout *layout;
|
||||
|
||||
/* round the number of samplers/buffer up a bit, so we don't (re)create
|
||||
* excessive amounts of layouts */
|
||||
n_samplers = MAX (n_samplers, 8);
|
||||
g_assert (n_samplers <= self->max_samplers);
|
||||
n_buffers = MAX (n_buffers, 8);
|
||||
g_assert (n_buffers <= self->max_buffers);
|
||||
setup.n_samplers = MIN (2 << g_bit_nth_msf (n_samplers - 1, -1), self->max_samplers);
|
||||
setup.n_buffers = MIN (2 << g_bit_nth_msf (n_buffers - 1, -1), self->max_buffers);
|
||||
setup.n_immutable_samplers = n_immutable_samplers;
|
||||
setup.immutable_samplers = immutable_samplers;
|
||||
|
||||
layout = g_hash_table_lookup (self->pipeline_layouts, &setup);
|
||||
if (layout)
|
||||
{
|
||||
gsk_vulkan_pipeline_layout_ref (self, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
return gsk_vulkan_pipeline_layout_new (self, &setup);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_device_release_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout *layout)
|
||||
{
|
||||
if (self->pipeline_layout_cache)
|
||||
gsk_vulkan_pipeline_layout_unref (self, self->pipeline_layout_cache);
|
||||
|
||||
self->pipeline_layout_cache = layout;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_device_get_pipeline_sizes (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout,
|
||||
gsize *n_immutable_samplers,
|
||||
gsize *n_samplers,
|
||||
gsize *n_buffers)
|
||||
{
|
||||
*n_immutable_samplers = layout->setup.n_immutable_samplers;
|
||||
*n_samplers = layout->setup.n_samplers;
|
||||
*n_buffers = layout->setup.n_buffers;
|
||||
return vk_pipeline;
|
||||
}
|
||||
|
||||
static GskVulkanAllocator *
|
||||
|
||||
@@ -11,20 +11,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* also used by gskvulkanframe.c */
|
||||
enum {
|
||||
GSK_VULKAN_IMAGE_SET_LAYOUT,
|
||||
GSK_VULKAN_BUFFER_SET_LAYOUT,
|
||||
|
||||
GSK_VULKAN_N_DESCRIPTOR_SETS
|
||||
};
|
||||
|
||||
#define GSK_TYPE_VULKAN_DEVICE (gsk_vulkan_device_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(GskVulkanDevice, gsk_vulkan_device, GSK, VULKAN_DEVICE, GskGpuDevice)
|
||||
|
||||
typedef struct _GskVulkanPipelineLayout GskVulkanPipelineLayout;
|
||||
|
||||
GskGpuDevice * gsk_vulkan_device_get_for_display (GdkDisplay *display,
|
||||
GError **error);
|
||||
|
||||
@@ -39,29 +29,12 @@ VkPhysicalDevice gsk_vulkan_device_get_vk_physical_device (GskVulk
|
||||
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;
|
||||
VkCommandPool gsk_vulkan_device_get_vk_command_pool (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkDescriptorPool gsk_vulkan_device_get_vk_descriptor_pool (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkDescriptorSetLayout gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkPipelineLayout gsk_vulkan_device_get_default_vk_pipeline_layout (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkSampler gsk_vulkan_device_get_vk_sampler (GskVulkanDevice *self,
|
||||
GskGpuSampler sampler) G_GNUC_PURE;
|
||||
|
||||
GskVulkanPipelineLayout *
|
||||
gsk_vulkan_device_acquire_pipeline_layout (GskVulkanDevice *self,
|
||||
VkSampler *immutable_samplers,
|
||||
gsize n_immutable_samplers,
|
||||
gsize n_samplers,
|
||||
gsize n_buffers);
|
||||
void gsk_vulkan_device_release_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout);
|
||||
void gsk_vulkan_device_get_pipeline_sizes (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout,
|
||||
gsize *n_immutable_samplers,
|
||||
gsize *n_samplers,
|
||||
gsize *n_buffers);
|
||||
VkDescriptorSetLayout gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout) G_GNUC_PURE;
|
||||
VkDescriptorSetLayout gsk_vulkan_device_get_vk_buffer_set_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout) G_GNUC_PURE;
|
||||
VkPipelineLayout gsk_vulkan_device_get_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout) G_GNUC_PURE;
|
||||
|
||||
VkSamplerYcbcrConversion
|
||||
gsk_vulkan_device_get_vk_conversion (GskVulkanDevice *self,
|
||||
VkFormat vk_format,
|
||||
@@ -71,13 +44,13 @@ VkRenderPass gsk_vulkan_device_get_vk_render_pass (GskVulk
|
||||
VkImageLayout from_layout,
|
||||
VkImageLayout to_layout);
|
||||
VkPipeline gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
GskVulkanPipelineLayout*layout,
|
||||
VkPipelineLayout layout,
|
||||
const GskGpuShaderOpClass *op_class,
|
||||
GskGpuShaderFlags flags,
|
||||
GskGpuColorStates color_states,
|
||||
guint32 variation,
|
||||
GskGpuBlend blend,
|
||||
VkFormat format,
|
||||
VkFormat vk_format,
|
||||
VkRenderPass render_pass);
|
||||
|
||||
GskVulkanAllocator * gsk_vulkan_device_get_external_allocator (GskVulkanDevice *self);
|
||||
|
||||
@@ -39,7 +39,6 @@ struct _GskVulkanFrame
|
||||
VkSemaphore vk_acquire_semaphore;
|
||||
VkFence vk_fence;
|
||||
VkCommandBuffer vk_command_buffer;
|
||||
VkDescriptorPool vk_descriptor_pool;
|
||||
|
||||
gsize pool_n_sets;
|
||||
gsize pool_n_images;
|
||||
@@ -139,13 +138,6 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame)
|
||||
GSK_VK_CHECK (vkResetCommandBuffer, self->vk_command_buffer,
|
||||
0);
|
||||
|
||||
if (self->vk_descriptor_pool != VK_NULL_HANDLE)
|
||||
{
|
||||
GSK_VK_CHECK (vkResetDescriptorPool, vk_device,
|
||||
self->vk_descriptor_pool,
|
||||
0);
|
||||
}
|
||||
|
||||
GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->cleanup (frame);
|
||||
}
|
||||
|
||||
@@ -223,75 +215,6 @@ gsk_vulkan_frame_upload_texture (GskGpuFrame *frame,
|
||||
return GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->upload_texture (frame, with_mipmap, texture);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_frame_prepare_descriptors (GskVulkanFrame *self)
|
||||
{
|
||||
#if 0
|
||||
GskVulkanDevice *device;
|
||||
VkDevice vk_device;
|
||||
gsize i, n_images, n_sets;
|
||||
|
||||
device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self)));
|
||||
vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
|
||||
n_images = 0;
|
||||
n_sets = 2 * gsk_descriptors_get_size (&self->descriptors);
|
||||
for (i = 0; i < gsk_descriptors_get_size (&self->descriptors); i++)
|
||||
{
|
||||
gsize n_desc_images;
|
||||
GskVulkanRealDescriptors *desc = gsk_descriptors_get (&self->descriptors, i);
|
||||
gsk_vulkan_real_descriptors_prepare (desc, &n_desc_images);
|
||||
n_images += n_desc_images;
|
||||
}
|
||||
|
||||
if (n_sets > self->pool_n_sets ||
|
||||
n_images > self->pool_n_images)
|
||||
{
|
||||
if (self->vk_descriptor_pool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyDescriptorPool (vk_device,
|
||||
self->vk_descriptor_pool,
|
||||
NULL);
|
||||
self->vk_descriptor_pool = VK_NULL_HANDLE;
|
||||
}
|
||||
if (n_sets > self->pool_n_sets)
|
||||
self->pool_n_sets = 4 << g_bit_nth_msf (n_sets - 1, -1);
|
||||
if (n_images > self->pool_n_images)
|
||||
self->pool_n_images = 2 << g_bit_nth_msf (n_images - 1, -1);
|
||||
}
|
||||
|
||||
if (self->vk_descriptor_pool == VK_NULL_HANDLE)
|
||||
{
|
||||
GSK_VK_CHECK (vkCreateDescriptorPool, vk_device,
|
||||
&(VkDescriptorPoolCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.maxSets = self->pool_n_sets,
|
||||
.poolSizeCount = 2,
|
||||
.pPoolSizes = (VkDescriptorPoolSize[2]) {
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = self->pool_n_images,
|
||||
},
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = self->pool_n_buffers,
|
||||
}
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&self->vk_descriptor_pool);
|
||||
}
|
||||
|
||||
for (i = 0; i < gsk_descriptors_get_size (&self->descriptors); i++)
|
||||
{
|
||||
GskVulkanRealDescriptors *desc = gsk_descriptors_get (&self->descriptors, i);
|
||||
|
||||
gsk_vulkan_real_descriptors_update_sets (desc, self->vk_descriptor_pool);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static GskGpuBuffer *
|
||||
gsk_vulkan_frame_create_vertex_buffer (GskGpuFrame *frame,
|
||||
gsize size)
|
||||
@@ -323,14 +246,7 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
{
|
||||
GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
|
||||
GskVulkanSemaphores semaphores;
|
||||
GskVulkanCommandState state;
|
||||
|
||||
#if 0
|
||||
if (gsk_descriptors_get_size (&self->descriptors) == 0)
|
||||
gsk_descriptors_append (&self->descriptors, gsk_vulkan_real_descriptors_new (self));
|
||||
#endif
|
||||
|
||||
gsk_vulkan_frame_prepare_descriptors (self);
|
||||
GskVulkanCommandState state = { 0, };
|
||||
|
||||
GSK_VK_CHECK (vkBeginCommandBuffer, self->vk_command_buffer,
|
||||
&(VkCommandBufferBeginInfo) {
|
||||
@@ -402,13 +318,6 @@ gsk_vulkan_frame_finalize (GObject *object)
|
||||
vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
vk_command_pool = gsk_vulkan_device_get_vk_command_pool (device);
|
||||
|
||||
if (self->vk_descriptor_pool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyDescriptorPool (vk_device,
|
||||
self->vk_descriptor_pool,
|
||||
NULL);
|
||||
}
|
||||
|
||||
vkFreeCommandBuffers (vk_device,
|
||||
vk_command_pool,
|
||||
1, &self->vk_command_buffer);
|
||||
|
||||
@@ -33,6 +33,7 @@ struct _GskVulkanImage
|
||||
VkImageView vk_framebuffer_image_view;
|
||||
VkSampler vk_sampler;
|
||||
VkSemaphore vk_semaphore;
|
||||
VkDescriptorSet vk_descriptor_sets[GSK_GPU_SAMPLER_N_SAMPLERS];
|
||||
|
||||
VkPipelineStageFlags vk_pipeline_stage;
|
||||
VkImageLayout vk_image_layout;
|
||||
@@ -1282,9 +1283,21 @@ static void
|
||||
gsk_vulkan_image_finalize (GObject *object)
|
||||
{
|
||||
GskVulkanImage *self = GSK_VULKAN_IMAGE (object);
|
||||
VkDescriptorPool vk_descriptor_pool;
|
||||
VkDevice vk_device;
|
||||
gsize i;
|
||||
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self->device);
|
||||
vk_descriptor_pool = gsk_vulkan_device_get_vk_descriptor_pool (self->device);
|
||||
|
||||
for (i = 0; i < GSK_GPU_SAMPLER_N_SAMPLERS; i++)
|
||||
{
|
||||
if (self->vk_descriptor_sets[i])
|
||||
vkFreeDescriptorSets (vk_device,
|
||||
vk_descriptor_pool,
|
||||
1,
|
||||
&self->vk_descriptor_sets[i]);
|
||||
}
|
||||
|
||||
if (self->vk_framebuffer != VK_NULL_HANDLE)
|
||||
vkDestroyFramebuffer (vk_device, self->vk_framebuffer, NULL);
|
||||
@@ -1388,6 +1401,47 @@ gsk_vulkan_image_get_vk_sampler (GskVulkanImage *self)
|
||||
return self->vk_sampler;
|
||||
}
|
||||
|
||||
VkDescriptorSet
|
||||
gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
GskGpuSampler sampler)
|
||||
{
|
||||
if (self->vk_descriptor_sets[sampler] == NULL)
|
||||
{
|
||||
VkDevice vk_device = gsk_vulkan_device_get_vk_device (self->device);
|
||||
|
||||
GSK_VK_CHECK (vkAllocateDescriptorSets, vk_device,
|
||||
&(VkDescriptorSetAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorPool = gsk_vulkan_device_get_vk_descriptor_pool (self->device),
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = (VkDescriptorSetLayout[1]) {
|
||||
gsk_vulkan_device_get_vk_image_set_layout (self->device),
|
||||
},
|
||||
},
|
||||
&self->vk_descriptor_sets[sampler]);
|
||||
g_assert (self->vk_descriptor_sets[sampler]);
|
||||
vkUpdateDescriptorSets (vk_device,
|
||||
1,
|
||||
&(VkWriteDescriptorSet) {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->vk_descriptor_sets[sampler],
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &(VkDescriptorImageInfo) {
|
||||
.sampler = gsk_vulkan_device_get_vk_sampler (self->device, sampler),
|
||||
.imageView = self->vk_image_view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
},
|
||||
},
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return self->vk_descriptor_sets[sampler];
|
||||
}
|
||||
|
||||
VkImage
|
||||
gsk_vulkan_image_get_vk_image (GskVulkanImage *self)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,8 @@ guchar * gsk_vulkan_image_get_data (GskVulk
|
||||
gsize *out_stride);
|
||||
|
||||
VkSampler gsk_vulkan_image_get_vk_sampler (GskVulkanImage *self);
|
||||
VkDescriptorSet gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
GskGpuSampler sampler);
|
||||
VkPipelineStageFlags gsk_vulkan_image_get_vk_pipeline_stage (GskVulkanImage *self);
|
||||
VkImageLayout gsk_vulkan_image_get_vk_image_layout (GskVulkanImage *self);
|
||||
VkAccessFlags gsk_vulkan_image_get_vk_access (GskVulkanImage *self);
|
||||
|
||||
@@ -11,11 +11,8 @@ layout(push_constant) uniform PushConstants {
|
||||
} push;
|
||||
|
||||
layout(constant_id=0) const uint GSK_FLAGS = 0;
|
||||
layout(constant_id=1) const uint GSK_N_IMMUTABLE_SAMPLERS = 32;
|
||||
layout(constant_id=2) const uint GSK_N_SAMPLERS = 32;
|
||||
layout(constant_id=3) const uint GSK_N_BUFFERS = 32;
|
||||
layout(constant_id=4) const uint GSK_COLOR_STATES = 0;
|
||||
layout(constant_id=5) const uint GSK_VARIATION = 0;
|
||||
layout(constant_id=1) const uint GSK_COLOR_STATES = 0;
|
||||
layout(constant_id=2) const uint GSK_VARIATION = 0;
|
||||
|
||||
#define GSK_GLOBAL_MVP push.mvp
|
||||
#define GSK_GLOBAL_CLIP push.clip
|
||||
@@ -35,14 +32,11 @@ layout(constant_id=5) const uint GSK_VARIATION = 0;
|
||||
#define PASS(_loc) layout(location = _loc) in
|
||||
#define PASS_FLAT(_loc) layout(location = _loc) flat in
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D immutable_textures[GSK_N_IMMUTABLE_SAMPLERS];
|
||||
layout(set = 0, binding = 1) uniform sampler2D textures[GSK_N_SAMPLERS];
|
||||
layout(set = 0, binding = 0) uniform sampler2D GSK_TEXTURE0;
|
||||
layout(set = 1, binding = 0) uniform sampler2D GSK_TEXTURE1;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
#define GSK_TEXTURE0 textures[0]
|
||||
#define GSK_TEXTURE1 textures[1]
|
||||
|
||||
void
|
||||
gsk_set_output_color (vec4 color)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user