Port hakuX Vulkan descriptor pool and framebuffer cache

This commit is contained in:
izzy2lost
2026-04-08 02:34:51 -04:00
parent 4f8d079d29
commit ddb6060091
3 changed files with 76 additions and 22 deletions
+40 -9
View File
@@ -471,6 +471,26 @@ static void create_frame_buffer(PGRAPHState *pg)
assert(r->color_binding || r->zeta_binding);
SurfaceBinding *binding = r->color_binding ? : r->zeta_binding;
VkImageView color_view = r->color_binding ? r->color_binding->image_view
: VK_NULL_HANDLE;
VkImageView zeta_view = r->zeta_binding ? r->zeta_binding->image_view
: VK_NULL_HANDLE;
uint32_t width = binding->width;
uint32_t height = binding->height;
pgraph_apply_scaling_factor(pg, &width, &height);
for (int i = 0; i < r->fb_cache_count; i++) {
if (r->fb_cache[i].render_pass == r->render_pass &&
r->fb_cache[i].color_view == color_view &&
r->fb_cache[i].zeta_view == zeta_view &&
r->fb_cache[i].width == width &&
r->fb_cache[i].height == height) {
r->current_framebuffer = r->fb_cache[i].framebuffer;
return;
}
}
if (r->framebuffer_index >= ARRAY_SIZE(r->framebuffers)) {
pgraph_vk_finish(pg, VK_FINISH_REASON_NEED_BUFFER_SPACE);
}
@@ -479,26 +499,35 @@ static void create_frame_buffer(PGRAPHState *pg)
int attachment_count = 0;
if (r->color_binding) {
attachments[attachment_count++] = r->color_binding->image_view;
attachments[attachment_count++] = color_view;
}
if (r->zeta_binding) {
attachments[attachment_count++] = r->zeta_binding->image_view;
attachments[attachment_count++] = zeta_view;
}
SurfaceBinding *binding = r->color_binding ? : r->zeta_binding;
VkFramebufferCreateInfo create_info = {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = r->render_pass,
.attachmentCount = attachment_count,
.pAttachments = attachments,
.width = binding->width,
.height = binding->height,
.width = width,
.height = height,
.layers = 1,
};
pgraph_apply_scaling_factor(pg, &create_info.width, &create_info.height);
VK_CHECK(vkCreateFramebuffer(r->device, &create_info, NULL,
&r->framebuffers[r->framebuffer_index++]));
r->current_framebuffer = r->framebuffers[r->framebuffer_index - 1];
if (r->fb_cache_count < FB_CACHE_MAX) {
r->fb_cache[r->fb_cache_count++] = (typeof(r->fb_cache[0])) {
.render_pass = r->render_pass,
.color_view = color_view,
.zeta_view = zeta_view,
.width = width,
.height = height,
.framebuffer = r->current_framebuffer,
};
}
}
static void destroy_framebuffers(PGRAPHState *pg)
@@ -511,6 +540,8 @@ static void destroy_framebuffers(PGRAPHState *pg)
r->framebuffers[i] = VK_NULL_HANDLE;
}
r->framebuffer_index = 0;
r->fb_cache_count = 0;
r->current_framebuffer = VK_NULL_HANDLE;
}
static void create_clear_pipeline(PGRAPHState *pg)
@@ -1282,12 +1313,12 @@ static void begin_render_pass(PGRAPHState *pg)
vp_height = pg->surface_binding_dim.height;
pgraph_apply_scaling_factor(pg, &vp_width, &vp_height);
assert(r->framebuffer_index > 0);
assert(r->current_framebuffer != VK_NULL_HANDLE);
VkRenderPassBeginInfo render_pass_begin_info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = r->render_pass,
.framebuffer = r->framebuffers[r->framebuffer_index - 1],
.framebuffer = r->current_framebuffer,
.renderArea.extent.width = vp_width,
.renderArea.extent.height = vp_height,
.clearValueCount = 0,
+16 -2
View File
@@ -43,6 +43,9 @@
#include "glsl.h"
#define HAVE_EXTERNAL_MEMORY 0
#define NUM_GFX_DESCRIPTOR_SETS 8192
#define MAX_FRAMEBUFFERS 256
#define FB_CACHE_MAX 32
typedef struct QueueFamilyIndices {
int queue_family;
@@ -369,9 +372,19 @@ typedef struct PGRAPHVkState {
VkCommandBuffer aux_command_buffer;
bool in_aux_command_buffer;
VkFramebuffer framebuffers[50];
VkFramebuffer framebuffers[MAX_FRAMEBUFFERS];
int framebuffer_index;
bool framebuffer_dirty;
struct {
VkRenderPass render_pass;
VkImageView color_view;
VkImageView zeta_view;
uint32_t width;
uint32_t height;
VkFramebuffer framebuffer;
} fb_cache[FB_CACHE_MAX];
int fb_cache_count;
VkFramebuffer current_framebuffer;
VkRenderPass render_pass;
GArray *render_passes; // RenderPass
@@ -387,7 +400,8 @@ typedef struct PGRAPHVkState {
VkDescriptorPool descriptor_pool;
VkDescriptorSetLayout descriptor_set_layout;
VkDescriptorSet descriptor_sets[1024];
VkDescriptorSet *descriptor_sets;
int descriptor_set_count;
int descriptor_set_index;
StorageBuffer storage_buffers[BUFFER_COUNT];
+20 -11
View File
@@ -32,7 +32,7 @@ static void create_descriptor_pool(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
size_t num_sets = ARRAY_SIZE(r->descriptor_sets);
size_t num_sets = r->descriptor_set_count;
VkDescriptorPoolSize pool_sizes[] = {
{
@@ -49,7 +49,7 @@ static void create_descriptor_pool(PGRAPHState *pg)
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.poolSizeCount = ARRAY_SIZE(pool_sizes),
.pPoolSizes = pool_sizes,
.maxSets = ARRAY_SIZE(r->descriptor_sets),
.maxSets = num_sets,
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
};
VK_CHECK(vkCreateDescriptorPool(r->device, &pool_info, NULL,
@@ -110,31 +110,39 @@ static void destroy_descriptor_set_layout(PGRAPHState *pg)
static void create_descriptor_sets(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
int count = r->descriptor_set_count;
VkDescriptorSetLayout layouts[ARRAY_SIZE(r->descriptor_sets)];
for (int i = 0; i < ARRAY_SIZE(layouts); i++) {
r->descriptor_sets = g_malloc_n(count, sizeof(VkDescriptorSet));
VkDescriptorSetLayout *layouts =
g_malloc_n(count, sizeof(VkDescriptorSetLayout));
for (int i = 0; i < count; i++) {
layouts[i] = r->descriptor_set_layout;
}
VkDescriptorSetAllocateInfo alloc_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = r->descriptor_pool,
.descriptorSetCount = ARRAY_SIZE(r->descriptor_sets),
.descriptorSetCount = count,
.pSetLayouts = layouts,
};
VK_CHECK(
vkAllocateDescriptorSets(r->device, &alloc_info, r->descriptor_sets));
g_free(layouts);
}
static void destroy_descriptor_sets(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
vkFreeDescriptorSets(r->device, r->descriptor_pool,
ARRAY_SIZE(r->descriptor_sets), r->descriptor_sets);
for (int i = 0; i < ARRAY_SIZE(r->descriptor_sets); i++) {
r->descriptor_sets[i] = VK_NULL_HANDLE;
if (r->descriptor_sets == NULL) {
return;
}
vkFreeDescriptorSets(r->device, r->descriptor_pool,
r->descriptor_set_count, r->descriptor_sets);
g_free(r->descriptor_sets);
r->descriptor_sets = NULL;
}
void pgraph_vk_update_descriptor_sets(PGRAPHState *pg)
@@ -164,7 +172,7 @@ void pgraph_vk_update_descriptor_sets(PGRAPHState *pg)
r->device_props.limits.minUniformBufferOffsetAlignment);
bool need_descriptor_write_reset =
(r->descriptor_set_index >= ARRAY_SIZE(r->descriptor_sets));
(r->descriptor_set_index >= r->descriptor_set_count);
if (need_descriptor_write_reset || need_ubo_staging_buffer_reset) {
pgraph_vk_finish(pg, VK_FINISH_REASON_NEED_BUFFER_SPACE);
@@ -173,7 +181,7 @@ void pgraph_vk_update_descriptor_sets(PGRAPHState *pg)
VkWriteDescriptorSet descriptor_writes[2 + NV2A_MAX_TEXTURES];
assert(r->descriptor_set_index < ARRAY_SIZE(r->descriptor_sets));
assert(r->descriptor_set_index < r->descriptor_set_count);
if (need_uniform_write) {
for (int i = 0; i < ARRAY_SIZE(layouts); i++) {
@@ -531,6 +539,7 @@ void pgraph_vk_init_shaders(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
r->descriptor_set_count = NUM_GFX_DESCRIPTOR_SETS;
pgraph_vk_init_glsl_compiler();
create_descriptor_pool(pg);
create_descriptor_set_layout(pg);