[vulkan] Make frame-buffers independent of swapchain

This is more correct as the environment (X11 etc) might provide more
swapchain images than we want: 3 frames in flight is generally
considered a good balance between saturating the hardware and latency.
This commit is contained in:
Bill Currie 2021-01-16 21:24:42 +09:00
parent fd8521da76
commit 8078e10ea1
3 changed files with 22 additions and 17 deletions

View file

@ -45,6 +45,7 @@
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/image.h"
#include "QF/Vulkan/instance.h"
#include "QF/Vulkan/renderpass.h"
#include "QF/Vulkan/swapchain.h"
#include "mod_internal.h"
@ -62,8 +63,8 @@ vulkan_R_Init (void)
Vulkan_CreateStagingBuffers (vulkan_ctx);
Vulkan_CreateMatrices (vulkan_ctx);
Vulkan_CreateSwapchain (vulkan_ctx);
Vulkan_CreateRenderPass (vulkan_ctx);
Vulkan_CreateFramebuffers (vulkan_ctx);
Vulkan_CreateRenderPass (vulkan_ctx);
// FIXME this should be staged so screen updates can begin while pipelines
// are being built
vulkan_ctx->pipeline = Vulkan_CreatePipeline (vulkan_ctx, "pipeline");
@ -100,13 +101,27 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs)
= &vulkan_ctx->framebuffers.a[vulkan_ctx->curFrame];
dfunc->vkWaitForFences (dev, 1, &framebuffer->fence, VK_TRUE, 2000000000);
if (framebuffer->framebuffer) {
dfunc->vkDestroyFramebuffer (dev, framebuffer->framebuffer, 0);
}
QFV_AcquireNextImage (vulkan_ctx->swapchain,
framebuffer->imageAvailableSemaphore,
0, &imageIndex);
__auto_type attachments = DARRAY_ALLOCFIXED (qfv_imageviewset_t, 3,
alloca);
qfv_swapchain_t *sc = vulkan_ctx->swapchain;
attachments->a[0] = vulkan_ctx->renderpass.colorImage->view;
attachments->a[1] = vulkan_ctx->renderpass.depthImage->view;
attachments->a[2] = sc->imageViews->a[imageIndex];
VkRenderPass renderpass = vulkan_ctx->renderpass.renderpass;
framebuffer->framebuffer = QFV_CreateFramebuffer (device, renderpass,
attachments,
sc->extent, 1);
Vulkan_FlushText (vulkan_ctx);
qfv_swapchain_t *sc = vulkan_ctx->swapchain;
VkCommandBufferBeginInfo beginInfo
= { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
VkClearValue clearValues[2] = {

View file

@ -32,15 +32,15 @@
descriptorPools = {
twod = {
flags = 0;
maxSets = $swapchain.images.size;
maxSets = $framebuffers.size;
bindings = (
{
type = uniform_buffer;
descriptorCount = $swapchain.images.size;
descriptorCount = $framebuffers.size;
},
{
type = combined_image_sampler;
descriptorCount = $swapchain.images.size;
descriptorCount = $framebuffers.size;
},
);
};

View file

@ -387,30 +387,20 @@ Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx)
{
qfv_device_t *device = ctx->device;
VkCommandPool cmdpool = ctx->cmdpool;
qfv_swapchain_t *sc = ctx->swapchain;
VkRenderPass renderpass = ctx->renderpass.renderpass;
if (!ctx->framebuffers.grow) {
DARRAY_INIT (&ctx->framebuffers, 4);
}
DARRAY_RESIZE (&ctx->framebuffers, sc->numImages);
__auto_type attachments = DARRAY_ALLOCFIXED (qfv_imageviewset_t, 3,
alloca);
attachments->a[0] = ctx->renderpass.colorImage->view;
attachments->a[1] = ctx->renderpass.depthImage->view;
DARRAY_RESIZE (&ctx->framebuffers, 3);//FIXME cvar
__auto_type cmdBuffers = QFV_AllocCommandBufferSet (ctx->framebuffers.size,
alloca);
QFV_AllocateCommandBuffers (device, cmdpool, 0, cmdBuffers);
for (size_t i = 0; i < ctx->framebuffers.size; i++) {
attachments->a[2] = sc->imageViews->a[i];
__auto_type frame = &ctx->framebuffers.a[i];
frame->framebuffer = QFV_CreateFramebuffer (device, renderpass,
attachments,
sc->extent, 1);
frame->framebuffer = 0;
frame->fence = QFV_CreateFence (device, 1);
frame->imageAvailableSemaphore = QFV_CreateSemaphore (device);
frame->renderDoneSemaphore = QFV_CreateSemaphore (device);