mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vulkan] Implement window resize support
There's a problem with screenshot capture in that the image is sheared after window resize, but the screen view looks good, and vulkan is happy with the state changes.
This commit is contained in:
parent
22276ad356
commit
1d50940c2a
7 changed files with 87 additions and 22 deletions
|
@ -44,6 +44,7 @@ typedef struct qfv_renderpass_s {
|
||||||
struct qfv_imageset_s *attachment_images;
|
struct qfv_imageset_s *attachment_images;
|
||||||
struct qfv_imageviewset_s *attachment_views;
|
struct qfv_imageviewset_s *attachment_views;
|
||||||
VkDeviceMemory attachmentMemory;
|
VkDeviceMemory attachmentMemory;
|
||||||
|
size_t attachmentMemory_size;
|
||||||
|
|
||||||
qfv_framebufferset_t *framebuffers;
|
qfv_framebufferset_t *framebuffers;
|
||||||
VkViewport viewport;
|
VkViewport viewport;
|
||||||
|
|
|
@ -81,6 +81,8 @@ typedef struct vulkan_ctx_s {
|
||||||
size_t curFrame;
|
size_t curFrame;
|
||||||
vulkan_frameset_t frames;
|
vulkan_frameset_t frames;
|
||||||
qfv_renderpassset_t renderPasses;
|
qfv_renderpassset_t renderPasses;
|
||||||
|
//FIXME for resize, but should be a set
|
||||||
|
struct qfv_renderpass_s *main_renderpass;
|
||||||
|
|
||||||
struct qfv_capture_s *capture;
|
struct qfv_capture_s *capture;
|
||||||
void (*capture_callback) (const byte *data, int width, int height);
|
void (*capture_callback) (const byte *data, int width, int height);
|
||||||
|
|
|
@ -293,9 +293,32 @@ vulkan_begin_frame (void)
|
||||||
__auto_type frame = &vulkan_ctx->frames.a[vulkan_ctx->curFrame];
|
__auto_type frame = &vulkan_ctx->frames.a[vulkan_ctx->curFrame];
|
||||||
|
|
||||||
dfunc->vkWaitForFences (dev, 1, &frame->fence, VK_TRUE, 2000000000);
|
dfunc->vkWaitForFences (dev, 1, &frame->fence, VK_TRUE, 2000000000);
|
||||||
QFV_AcquireNextImage (vulkan_ctx->swapchain,
|
if (!QFV_AcquireNextImage (vulkan_ctx->swapchain,
|
||||||
frame->imageAvailableSemaphore,
|
frame->imageAvailableSemaphore,
|
||||||
0, &imageIndex);
|
0, &imageIndex)) {
|
||||||
|
QFV_DeviceWaitIdle (device);
|
||||||
|
if (vulkan_ctx->capture) {
|
||||||
|
QFV_DestroyCapture (vulkan_ctx->capture);
|
||||||
|
}
|
||||||
|
Vulkan_CreateSwapchain (vulkan_ctx);
|
||||||
|
Vulkan_CreateCapture (vulkan_ctx);
|
||||||
|
|
||||||
|
//FIXME
|
||||||
|
qfv_output_t output = {
|
||||||
|
.extent = vulkan_ctx->swapchain->extent,
|
||||||
|
.view = vulkan_ctx->swapchain->imageViews->a[0],
|
||||||
|
.format = vulkan_ctx->swapchain->format,
|
||||||
|
.view_list = vulkan_ctx->swapchain->imageViews->a,
|
||||||
|
};
|
||||||
|
vulkan_ctx->main_renderpass->viewport.width = output.extent.width;
|
||||||
|
vulkan_ctx->main_renderpass->viewport.height = output.extent.height;
|
||||||
|
vulkan_ctx->main_renderpass->scissor.extent = output.extent;
|
||||||
|
vulkan_ctx->output = output;
|
||||||
|
Vulkan_CreateAttachments (vulkan_ctx, vulkan_ctx->main_renderpass);
|
||||||
|
QFV_AcquireNextImage (vulkan_ctx->swapchain,
|
||||||
|
frame->imageAvailableSemaphore,
|
||||||
|
0, &imageIndex);
|
||||||
|
}
|
||||||
vulkan_ctx->swapImageIndex = imageIndex;
|
vulkan_ctx->swapImageIndex = imageIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
|
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/mathlib.h"
|
#include "QF/mathlib.h"
|
||||||
|
#include "QF/va.h"
|
||||||
|
|
||||||
|
#include "QF/Vulkan/debug.h"
|
||||||
#include "QF/Vulkan/device.h"
|
#include "QF/Vulkan/device.h"
|
||||||
#include "QF/Vulkan/image.h"
|
#include "QF/Vulkan/image.h"
|
||||||
#include "QF/Vulkan/instance.h"
|
#include "QF/Vulkan/instance.h"
|
||||||
|
|
|
@ -180,4 +180,5 @@ Vulkan_Main_CreateRenderPasses (vulkan_ctx_t *ctx)
|
||||||
&output, main_draw);
|
&output, main_draw);
|
||||||
rp->order = QFV_rp_main;
|
rp->order = QFV_rp_main;
|
||||||
DARRAY_APPEND (&ctx->renderPasses, rp);
|
DARRAY_APPEND (&ctx->renderPasses, rp);
|
||||||
|
ctx->main_renderpass = rp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,24 @@ get_image_size (VkImage image, qfv_device_t *device)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_framebuffers (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
||||||
|
{
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rp->framebuffers->size; i++) {
|
||||||
|
dfunc->vkDestroyFramebuffer (device->dev, rp->framebuffers->a[i], 0);
|
||||||
|
}
|
||||||
|
free (rp->framebuffers);
|
||||||
|
rp->framebuffers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Vulkan_CreateAttachments (vulkan_ctx_t *ctx, qfv_renderpass_t *renderpass)
|
Vulkan_CreateAttachments (vulkan_ctx_t *ctx, qfv_renderpass_t *renderpass)
|
||||||
{
|
{
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
__auto_type rp = renderpass;
|
__auto_type rp = renderpass;
|
||||||
|
|
||||||
plitem_t *item = get_rp_item (ctx, rp, "images");
|
plitem_t *item = get_rp_item (ctx, rp, "images");
|
||||||
|
@ -85,19 +99,44 @@ Vulkan_CreateAttachments (vulkan_ctx_t *ctx, qfv_renderpass_t *renderpass)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (renderpass->framebuffers) {
|
||||||
|
destroy_framebuffers (ctx, renderpass);
|
||||||
|
}
|
||||||
|
if (rp->attachment_views) {
|
||||||
|
for (size_t i = 0; i < rp->attachment_views->size; i++) {
|
||||||
|
dfunc->vkDestroyImageView (device->dev,
|
||||||
|
rp->attachment_views->a[i], 0);
|
||||||
|
}
|
||||||
|
free (rp->attachment_views);
|
||||||
|
rp->attachment_views = 0;
|
||||||
|
}
|
||||||
|
if (rp->attachment_images) {
|
||||||
|
for (size_t i = 0; i < rp->attachment_images->size; i++) {
|
||||||
|
dfunc->vkDestroyImage (device->dev, rp->attachment_images->a[i], 0);
|
||||||
|
}
|
||||||
|
free (rp->attachment_images);
|
||||||
|
rp->attachment_images = 0;
|
||||||
|
}
|
||||||
|
|
||||||
__auto_type images = QFV_ParseImageSet (ctx, item, rp->renderpassDef);
|
__auto_type images = QFV_ParseImageSet (ctx, item, rp->renderpassDef);
|
||||||
rp->attachment_images = images;
|
rp->attachment_images = images;
|
||||||
size_t memSize = 0;
|
size_t memSize = 0;
|
||||||
for (size_t i = 0; i < images->size; i++) {
|
for (size_t i = 0; i < images->size; i++) {
|
||||||
memSize += get_image_size (images->a[i], device);
|
memSize += get_image_size (images->a[i], device);
|
||||||
}
|
}
|
||||||
VkDeviceMemory mem;
|
VkDeviceMemory mem = rp->attachmentMemory;
|
||||||
mem = QFV_AllocImageMemory (device, images->a[0],
|
if (memSize > rp->attachmentMemory_size) {
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
if (rp->attachmentMemory) {
|
||||||
memSize, 0);
|
dfunc->vkFreeMemory (device->dev, rp->attachmentMemory, 0);
|
||||||
rp->attachmentMemory = mem;
|
}
|
||||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
|
rp->attachmentMemory_size = memSize;
|
||||||
mem, "memory:framebuffers");
|
mem = QFV_AllocImageMemory (device, images->a[0],
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
memSize, 0);
|
||||||
|
rp->attachmentMemory = mem;
|
||||||
|
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
|
||||||
|
mem, "memory:framebuffers");
|
||||||
|
}
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (size_t i = 0; i < images->size; i++) {
|
for (size_t i = 0; i < images->size; i++) {
|
||||||
QFV_BindImageMemory (device, images->a[i], mem, offset);
|
QFV_BindImageMemory (device, images->a[i], mem, offset);
|
||||||
|
@ -179,18 +218,6 @@ destroy_renderframes (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_framebuffers (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
|
||||||
{
|
|
||||||
qfv_device_t *device = ctx->device;
|
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < rp->framebuffers->size; i++) {
|
|
||||||
dfunc->vkDestroyFramebuffer (device->dev, rp->framebuffers->a[i], 0);
|
|
||||||
}
|
|
||||||
free (rp->framebuffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
qfv_renderpass_t *
|
qfv_renderpass_t *
|
||||||
Vulkan_CreateRenderPass (vulkan_ctx_t *ctx, const char *name,
|
Vulkan_CreateRenderPass (vulkan_ctx_t *ctx, const char *name,
|
||||||
qfv_output_t *output, qfv_draw_t draw)
|
qfv_output_t *output, qfv_draw_t draw)
|
||||||
|
|
|
@ -280,7 +280,16 @@ Vulkan_CreateSwapchain (vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
VkSwapchainKHR old_swapchain = 0;
|
VkSwapchainKHR old_swapchain = 0;
|
||||||
if (ctx->swapchain) {
|
if (ctx->swapchain) {
|
||||||
|
//FIXME this shouldn't be here
|
||||||
|
qfv_device_t *device = ctx->swapchain->device;
|
||||||
|
VkDevice dev = device->dev;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
old_swapchain = ctx->swapchain->swapchain;
|
old_swapchain = ctx->swapchain->swapchain;
|
||||||
|
for (size_t i = 0; i < ctx->swapchain->imageViews->size; i++) {
|
||||||
|
dfunc->vkDestroyImageView(dev, ctx->swapchain->imageViews->a[i], 0);
|
||||||
|
}
|
||||||
|
free (ctx->swapchain->images);
|
||||||
|
free (ctx->swapchain->imageViews);
|
||||||
free (ctx->swapchain);
|
free (ctx->swapchain);
|
||||||
}
|
}
|
||||||
ctx->swapchain = QFV_CreateSwapchain (ctx, old_swapchain);
|
ctx->swapchain = QFV_CreateSwapchain (ctx, old_swapchain);
|
||||||
|
|
Loading…
Reference in a new issue