mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vulkan] Get window resize working again
The biggest change was splitting up the job resources into per-render-pass resources, allowing individual render passes to reallocate their resources without affecting any others. After that, it was just getting translucency and capture working after a window resize.
This commit is contained in:
parent
45e09673c7
commit
cd4791c5d3
11 changed files with 439 additions and 290 deletions
|
@ -14,7 +14,7 @@ struct tex_s;
|
|||
typedef void (*capfunc_t) (struct tex_s *screencap, void *data);
|
||||
|
||||
typedef struct qfv_capture_frame_s {
|
||||
VkBuffer buffer;
|
||||
struct qfv_resobj_s *buffer;
|
||||
byte *data;
|
||||
|
||||
bool initiated;
|
||||
|
@ -27,12 +27,10 @@ typedef struct qfv_capture_frame_set_s
|
|||
|
||||
typedef struct qfv_capturectx_s {
|
||||
qfv_capture_frame_set_t frames;
|
||||
struct qfv_device_s *device;
|
||||
VkExtent2D extent;
|
||||
size_t imgsize;
|
||||
size_t memsize;
|
||||
byte *data;
|
||||
VkDeviceMemory memory;
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_capturectx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
|
|
@ -21,9 +21,12 @@ typedef struct qfv_transtate_s {
|
|||
typedef struct translucentframe_s {
|
||||
VkDescriptorSet flat;
|
||||
VkDescriptorSet cube;
|
||||
VkImage heads;
|
||||
VkImage cube_heads;
|
||||
VkBuffer state;
|
||||
struct qfv_resobj_s *heads;
|
||||
struct qfv_resobj_s *cube_heads;
|
||||
struct qfv_resobj_s *heads_view;
|
||||
struct qfv_resobj_s *cube_heads_view;
|
||||
struct qfv_resobj_s *state;
|
||||
struct qfv_resobj_s *frags;
|
||||
} translucentframe_t;
|
||||
|
||||
typedef struct translucentframeset_s
|
||||
|
@ -32,6 +35,7 @@ typedef struct translucentframeset_s
|
|||
typedef struct translucentctx_s {
|
||||
translucentframeset_t frames;
|
||||
struct qfv_resource_s *resources;
|
||||
VkExtent2D extent;
|
||||
|
||||
int maxFragments;
|
||||
} translucentctx_t;
|
||||
|
@ -43,7 +47,5 @@ void Vulkan_Translucent_Setup (struct vulkan_ctx_s *ctx);
|
|||
void Vulkan_Translucent_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
VkDescriptorSet Vulkan_Translucent_Descriptors (struct vulkan_ctx_s *ctx,
|
||||
int frame)__attribute__((pure));
|
||||
void Vulkan_Translucent_CreateBuffers (struct vulkan_ctx_s *ctx,
|
||||
VkExtent2D extent);
|
||||
|
||||
#endif//__QF_Vulkan_qf_translucent_h
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct qfv_imageinfo_s {
|
|||
VkImageTiling tiling;
|
||||
VkImageUsageFlags usage;
|
||||
VkImageLayout initialLayout;
|
||||
struct qfv_resobj_s *object;
|
||||
} qfv_imageinfo_t;
|
||||
|
||||
typedef struct qfv_imageviewinfo_s {
|
||||
|
@ -91,6 +92,7 @@ typedef struct qfv_imageviewinfo_s {
|
|||
VkFormat format;
|
||||
VkComponentMapping components;
|
||||
VkImageSubresourceRange subresourceRange;
|
||||
struct qfv_resobj_s *object;
|
||||
} qfv_imageviewinfo_t;
|
||||
|
||||
typedef struct qfv_bufferinfo_s {
|
||||
|
@ -355,6 +357,8 @@ typedef struct qfv_renderpass_s {
|
|||
qfv_framebufferinfo_t *framebufferinfo;
|
||||
VkImageView output;
|
||||
qfv_reference_t outputref;
|
||||
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_renderpass_t;
|
||||
|
||||
typedef struct qfv_render_s {
|
||||
|
@ -386,9 +390,6 @@ typedef struct qfv_step_s {
|
|||
|
||||
typedef struct qfv_job_s {
|
||||
qfv_label_t label;
|
||||
struct qfv_resource_s *resources;
|
||||
struct qfv_resobj_s *images;
|
||||
struct qfv_resobj_s *image_views;
|
||||
|
||||
uint32_t num_renderpasses;
|
||||
uint32_t num_pipelines;
|
||||
|
@ -440,7 +441,9 @@ void QFV_Render_Init (struct vulkan_ctx_s *ctx);
|
|||
void QFV_Render_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void QFV_Render_AddTasks (struct vulkan_ctx_s *ctx, exprsym_t *task_sys);
|
||||
|
||||
void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp);
|
||||
void QFV_DestroyFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp);
|
||||
void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp,
|
||||
VkExtent2D extent);
|
||||
|
||||
struct qfv_dsmanager_s *
|
||||
QFV_Render_DSManager (struct vulkan_ctx_s *ctx,
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#endif
|
||||
|
||||
#include "QF/cexpr.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/Vulkan/buffer.h"
|
||||
#include "QF/Vulkan/capture.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "QF/Vulkan/resource.h"
|
||||
#include "QF/Vulkan/swapchain.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
@ -66,13 +69,14 @@ capture_initiate (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
|
||||
auto sc = ctx->swapchain;
|
||||
auto scImage = sc->images->a[ctx->swapImageIndex];
|
||||
auto buffer = frame->buffer->buffer.buffer;
|
||||
|
||||
VkBufferMemoryBarrier start_buffer_barriers[] = {
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.buffer = frame->buffer,
|
||||
.buffer = buffer,
|
||||
.offset = 0,
|
||||
.size = VK_WHOLE_SIZE,
|
||||
},
|
||||
|
@ -93,7 +97,7 @@ capture_initiate (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.buffer = frame->buffer,
|
||||
.buffer = buffer,
|
||||
.offset = 0,
|
||||
.size = VK_WHOLE_SIZE,
|
||||
},
|
||||
|
@ -127,7 +131,7 @@ capture_initiate (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
};
|
||||
dfunc->vkCmdCopyImageToBuffer (cmd, scImage,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
frame->buffer, 1, ©);
|
||||
buffer, 1, ©);
|
||||
|
||||
dfunc->vkCmdPipelineBarrier (cmd,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
|
@ -172,7 +176,7 @@ capture_finalize (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
|
||||
VkMappedMemoryRange range = {
|
||||
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.memory = cap->memory,
|
||||
.memory = cap->resources->memory,
|
||||
.offset = frame->data - cap->data,
|
||||
.size = cap->imgsize,
|
||||
};
|
||||
|
@ -233,7 +237,6 @@ QFV_Capture_Init (vulkan_ctx_t *ctx)
|
|||
|
||||
auto device = ctx->device;
|
||||
auto ifunc = device->physDev->instance->funcs;
|
||||
auto dfunc = device->funcs;
|
||||
|
||||
ctx->capture_context = calloc (1, sizeof (qfv_capturectx_t));
|
||||
auto cap = ctx->capture_context;
|
||||
|
@ -248,7 +251,6 @@ QFV_Capture_Init (vulkan_ctx_t *ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
cap->device = device;
|
||||
cap->extent = swapchain->extent;
|
||||
|
||||
auto rctx = ctx->render_context;
|
||||
|
@ -257,44 +259,62 @@ QFV_Capture_Init (vulkan_ctx_t *ctx)
|
|||
DARRAY_RESIZE (&cap->frames, frames);
|
||||
cap->frames.grow = 0;
|
||||
|
||||
//FIXME assumes the swapchain is 32bpp
|
||||
cap->imgsize = swapchain->extent.width * swapchain->extent.height * 4;
|
||||
|
||||
cap->resources = calloc (1, sizeof (qfv_resource_t)
|
||||
+ sizeof (qfv_resobj_t[frames]));
|
||||
auto buffers = (qfv_resobj_t *) &cap->resources[1];
|
||||
cap->resources[0] = (qfv_resource_t) {
|
||||
.name = "capture",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
|
||||
.num_objects = frames,
|
||||
.objects = buffers,
|
||||
};
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
buffers[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "capture:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
auto frame = &cap->frames.a[i];
|
||||
*frame = (qfv_capture_frame_t) {
|
||||
.buffer = QFV_CreateBuffer (device, cap->imgsize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
.buffer = &buffers[i],
|
||||
};
|
||||
}
|
||||
VkMemoryRequirements req;
|
||||
dfunc->vkGetBufferMemoryRequirements (device->dev,
|
||||
cap->frames.a[0].buffer,
|
||||
&req);
|
||||
cap->imgsize = QFV_NextOffset (cap->imgsize, &req);
|
||||
cap->memsize = frames * cap->imgsize;
|
||||
cap->memory = QFV_AllocBufferMemory (device,
|
||||
cap->frames.a[0].buffer,
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
|
||||
cap->memsize, 0);
|
||||
dfunc->vkMapMemory (device->dev, cap->memory, 0, cap->memsize, 0,
|
||||
(void **) &cap->data);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
auto frame = &cap->frames.a[i];
|
||||
frame->data = cap->data + i * cap->imgsize;
|
||||
QFV_BindBufferMemory (device, frame->buffer, cap->memory,
|
||||
i * cap->imgsize);
|
||||
}
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
int shut_up_gcc = 1;
|
||||
void
|
||||
QFV_Capture_Renew (vulkan_ctx_t *ctx)
|
||||
{
|
||||
if (shut_up_gcc) {
|
||||
Sys_Error ("QFV_Capture_Renew not implemented");
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto swapchain = ctx->swapchain;
|
||||
auto cap = ctx->capture_context;
|
||||
|
||||
if (!cap->resources) {
|
||||
return;
|
||||
}
|
||||
if (cap->resources->memory) {
|
||||
dfunc->vkUnmapMemory (device->dev, cap->resources->memory);
|
||||
QFV_DestroyResource (device, cap->resources);
|
||||
}
|
||||
|
||||
cap->extent = swapchain->extent;
|
||||
//FIXME assumes the swapchain is 32bpp
|
||||
cap->imgsize = swapchain->extent.width * swapchain->extent.height * 4;
|
||||
for (uint32_t i = 0; i < cap->resources->num_objects; i++) {
|
||||
auto obj = &cap->resources->objects[i];
|
||||
obj->buffer.size = cap->imgsize;
|
||||
}
|
||||
QFV_CreateResource (device, cap->resources);
|
||||
dfunc->vkMapMemory (device->dev, cap->resources->memory, 0,
|
||||
cap->resources->size, 0, (void **) &cap->data);
|
||||
for (size_t i = 0; i < cap->frames.size; i++) {
|
||||
auto frame = &cap->frames.a[i];
|
||||
frame->data = cap->data + i * cap->imgsize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,12 +325,11 @@ QFV_Capture_Shutdown (vulkan_ctx_t *ctx)
|
|||
auto dfunc = device->funcs;
|
||||
auto cap = ctx->capture_context;
|
||||
|
||||
for (size_t i = 0; i < cap->frames.size; i++) {
|
||||
auto frame = &cap->frames.a[i];
|
||||
dfunc->vkDestroyBuffer (device->dev, frame->buffer, 0);
|
||||
if (cap->resources->memory) {
|
||||
dfunc->vkUnmapMemory (device->dev, cap->resources->memory);
|
||||
QFV_DestroyResource (device, cap->resources);
|
||||
}
|
||||
dfunc->vkUnmapMemory (device->dev, cap->memory);
|
||||
dfunc->vkFreeMemory (device->dev, cap->memory, 0);
|
||||
free (cap->resources);
|
||||
DARRAY_CLEAR (&cap->frames);
|
||||
free (cap);
|
||||
}
|
||||
|
@ -319,11 +338,14 @@ void
|
|||
QFV_Capture_Screen (vulkan_ctx_t *ctx, capfunc_t callback, void *data)
|
||||
{
|
||||
auto cap = ctx->capture_context;
|
||||
if (!cap->data) {
|
||||
if (!cap->resources) {
|
||||
Sys_Printf ("Capture not supported\n");
|
||||
callback (0, data);
|
||||
return;
|
||||
}
|
||||
if (!cap->resources->memory) {
|
||||
QFV_Capture_Renew (ctx);
|
||||
}
|
||||
auto frame = &cap->frames.a[ctx->curFrame];
|
||||
frame->callback = callback;
|
||||
frame->callback_data = data;
|
||||
|
|
|
@ -265,11 +265,11 @@ QFV_RunRenderJob (vulkan_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static VkImageView __attribute__((pure))
|
||||
find_imageview (qfv_reference_t *ref, qfv_renderctx_t *rctx)
|
||||
static qfv_imageviewinfo_t * __attribute__((pure))
|
||||
find_imageview (qfv_reference_t *ref, qfv_renderpass_t *rp,
|
||||
qfv_renderctx_t *rctx)
|
||||
{
|
||||
__auto_type jinfo = rctx->jobinfo;
|
||||
__auto_type job = rctx->job;
|
||||
auto jinfo = rctx->jobinfo;
|
||||
const char *name = ref->name;
|
||||
|
||||
if (strncmp (name, "$imageviews.", 7) == 0) {
|
||||
|
@ -277,19 +277,45 @@ find_imageview (qfv_reference_t *ref, qfv_renderctx_t *rctx)
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < jinfo->num_imageviews; i++) {
|
||||
__auto_type vi = &jinfo->imageviews[i];
|
||||
__auto_type vo = &job->image_views[i];
|
||||
if (strcmp (name, vi->name) == 0) {
|
||||
return vo->image_view.view;
|
||||
auto viewinfo = &jinfo->imageviews[i];
|
||||
if (strcmp (name, viewinfo->name) == 0) {
|
||||
return viewinfo;
|
||||
}
|
||||
}
|
||||
Sys_Error ("%d:invalid imageview: %s", ref->line, ref->name);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_CreateFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
||||
QFV_DestroyFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
||||
{
|
||||
__auto_type rctx = ctx->render_context;
|
||||
if (rp->beginInfo.framebuffer) {
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto bi = &rp->beginInfo;
|
||||
dfunc->vkDestroyFramebuffer (device->dev, bi->framebuffer, 0);
|
||||
bi->framebuffer = 0;
|
||||
}
|
||||
if (rp->resources && rp->resources->memory) {
|
||||
QFV_DestroyResource (ctx->device, rp->resources);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QFV_CreateFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp,
|
||||
VkExtent2D extent)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
|
||||
if (rp->resources && !rp->resources->memory) {
|
||||
for (uint32_t i = 0; i < rp->resources->num_objects; i++) {
|
||||
auto obj = &rp->resources->objects[i];
|
||||
if (obj->type == qfv_res_image) {
|
||||
obj->image.extent.width = extent.width;
|
||||
obj->image.extent.height = extent.height;
|
||||
}
|
||||
}
|
||||
QFV_CreateResource (ctx->device, rp->resources);
|
||||
}
|
||||
|
||||
auto fb = rp->framebufferinfo;
|
||||
auto attachments = rp->framebuffer.views;
|
||||
|
@ -298,8 +324,8 @@ QFV_CreateFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
|||
.attachmentCount = fb->num_attachments,
|
||||
.pAttachments = attachments,
|
||||
.renderPass = rp->beginInfo.renderPass,
|
||||
.width = fb->width,
|
||||
.height = fb->height,
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.layers = fb->layers,
|
||||
};
|
||||
for (uint32_t i = 0; i < fb->num_attachments; i++) {
|
||||
|
@ -312,9 +338,11 @@ QFV_CreateFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
|||
cInfo.height = sc->extent.height;
|
||||
}
|
||||
} else {
|
||||
attachments[i] = find_imageview (&fb->attachments[i].view, rctx);
|
||||
auto viewinfo = find_imageview (&fb->attachments[i].view, rp, rctx);
|
||||
attachments[i] = viewinfo->object->image_view.view;
|
||||
if (rp->outputref.name) {
|
||||
rp->output = find_imageview (&rp->outputref, rctx);
|
||||
viewinfo = find_imageview (&rp->outputref, rp, rctx);
|
||||
rp->output = viewinfo->object->image_view.view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,8 +380,8 @@ wait_on_fence (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
}
|
||||
|
||||
static void
|
||||
renderpass_update_viewper_sissor (qfv_renderpass_t *rp,
|
||||
const qfv_output_t *output)
|
||||
renderpass_update_viewport_sissor (qfv_renderpass_t *rp,
|
||||
const qfv_output_t *output)
|
||||
{
|
||||
rp->beginInfo.renderArea.extent = output->extent;
|
||||
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
||||
|
@ -375,7 +403,7 @@ static void
|
|||
update_viewport_scissor (qfv_render_t *render, const qfv_output_t *output)
|
||||
{
|
||||
for (uint32_t i = 0; i < render->num_renderpasses; i++) {
|
||||
renderpass_update_viewper_sissor (&render->renderpasses[i], output);
|
||||
renderpass_update_viewport_sissor (&render->renderpasses[i], output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,12 +422,13 @@ update_framebuffer (const exprval_t **params, exprval_t *result,
|
|||
Vulkan_ConfigOutput (ctx, &output);
|
||||
if (output.extent.width != render->output.extent.width
|
||||
|| output.extent.height != render->output.extent.height) {
|
||||
//FIXME framebuffer image creation here
|
||||
QFV_DestroyFramebuffer (ctx, rp);
|
||||
update_viewport_scissor (render, &output);
|
||||
render->output.extent = output.extent;
|
||||
}
|
||||
|
||||
if (!rp->beginInfo.framebuffer) {
|
||||
QFV_CreateFramebuffer (ctx, rp);
|
||||
QFV_CreateFramebuffer (ctx, rp, render->output.extent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,15 +498,16 @@ QFV_Render_Shutdown (vulkan_ctx_t *ctx)
|
|||
for (uint32_t i = 0; i < job->num_layouts; i++) {
|
||||
dfunc->vkDestroyPipelineLayout (device->dev, job->layouts[i], 0);
|
||||
}
|
||||
if (job->resources) {
|
||||
QFV_DestroyResource (ctx->device, job->resources);
|
||||
free (job->resources);
|
||||
}
|
||||
for (uint32_t i = 0; i < job->num_steps; i++) {
|
||||
if (job->steps[i].render) {
|
||||
auto render = job->steps[i].render;
|
||||
for (uint32_t j = 0; j < render->num_renderpasses; j++) {
|
||||
auto bi = &render->renderpasses[j].beginInfo;
|
||||
auto rp = &render->renderpasses[j];
|
||||
if (rp->resources && rp->resources->memory) {
|
||||
QFV_DestroyResource (ctx->device, rp->resources);
|
||||
}
|
||||
free (rp->resources);
|
||||
auto bi = &rp->beginInfo;
|
||||
if (bi->framebuffer) {
|
||||
dfunc->vkDestroyFramebuffer (device->dev,
|
||||
bi->framebuffer, 0);
|
||||
|
|
|
@ -220,31 +220,86 @@ count_stuff (qfv_jobinfo_t *jobinfo, objcount_t *counts)
|
|||
}
|
||||
}
|
||||
|
||||
static qfv_imageinfo_t * __attribute__((pure))
|
||||
find_imageinfo (qfv_jobinfo_t *jobinfo, const qfv_reference_t *ref)
|
||||
{
|
||||
if (strcmp (ref->name, "$output.image") == 0) {
|
||||
//auto image = jinfo->output.image;
|
||||
//job->image_views[i].image_view.external_image = image;
|
||||
//job->image_views[i].image_view.image = -1;
|
||||
} else {
|
||||
for (uint32_t i = 0; i <= jobinfo->num_images; i++) {
|
||||
auto img = &jobinfo->images[i];
|
||||
if (strcmp (ref->name, img->name) == 0) {
|
||||
return img;
|
||||
}
|
||||
}
|
||||
}
|
||||
Sys_Printf ("%d: unknown image reference: %s\n", ref->line, ref->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qfv_imageviewinfo_t * __attribute__((pure))
|
||||
find_imageviewinfo (qfv_jobinfo_t *jobinfo, const qfv_reference_t *ref)
|
||||
{
|
||||
for (uint32_t i = 0; i <= jobinfo->num_imageviews; i++) {
|
||||
auto imgview = &jobinfo->imageviews[i];
|
||||
if (strcmp (ref->name, imgview->name) == 0) {
|
||||
return imgview;
|
||||
}
|
||||
}
|
||||
Sys_Printf ("%d: unknown image view reference: %s\n", ref->line, ref->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
create_resources (vulkan_ctx_t *ctx, objcount_t *counts)
|
||||
create_resources (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
||||
{
|
||||
auto rctx = ctx->render_context;
|
||||
auto jinfo = rctx->jobinfo;
|
||||
auto job = rctx->job;
|
||||
|
||||
auto fbi = rp->framebufferinfo;
|
||||
uint32_t num_attachments = 0;
|
||||
for (uint32_t i = 0; i < fbi->num_attachments; i++) {
|
||||
auto attach = &fbi->attachments[i];
|
||||
if (!attach->external) {
|
||||
num_attachments++;
|
||||
}
|
||||
}
|
||||
if (!num_attachments) {
|
||||
rp->resources = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = sizeof (qfv_resource_t);
|
||||
size += sizeof (qfv_resobj_t [counts->num_images]);
|
||||
size += sizeof (qfv_resobj_t [counts->num_imageviews]);
|
||||
size += sizeof (qfv_resobj_t [num_attachments]);
|
||||
size += sizeof (qfv_resobj_t [num_attachments]);
|
||||
|
||||
job->resources = malloc (size);
|
||||
job->images = (qfv_resobj_t *) &job->resources[1];
|
||||
job->image_views = &job->images[counts->num_images];
|
||||
rp->resources = calloc (1, size);
|
||||
auto images = (qfv_resobj_t *) &rp->resources[1];
|
||||
auto image_views = &images[num_attachments];
|
||||
|
||||
job->resources[0] = (qfv_resource_t) {
|
||||
.name = "render",
|
||||
rp->resources[0] = (qfv_resource_t) {
|
||||
.name = rp->label.name,
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = counts->num_images + counts->num_imageviews,
|
||||
.objects = job->images,
|
||||
.num_objects = 2 * num_attachments,
|
||||
.objects = images,
|
||||
};
|
||||
for (uint32_t i = 0; i < counts->num_images; i++) {
|
||||
__auto_type img = &jinfo->images[i];
|
||||
job->images[i] = (qfv_resobj_t) {
|
||||
int error = 0;
|
||||
for (uint32_t i = 0; i < num_attachments; i++) {
|
||||
auto attach = &fbi->attachments[i];
|
||||
auto imgview = find_imageviewinfo (jinfo, &attach->view);
|
||||
if (!imgview) {
|
||||
error = 1;
|
||||
continue;
|
||||
}
|
||||
auto img = find_imageinfo (jinfo, &imgview->image);
|
||||
if (!img) {
|
||||
error = 1;
|
||||
continue;
|
||||
}
|
||||
images[i] = (qfv_resobj_t) {
|
||||
.name = img->name,
|
||||
.type = qfv_res_image,
|
||||
.image = {
|
||||
|
@ -260,52 +315,30 @@ create_resources (vulkan_ctx_t *ctx, objcount_t *counts)
|
|||
.initialLayout = img->initialLayout,
|
||||
},
|
||||
};
|
||||
}
|
||||
int error = 0;
|
||||
for (uint32_t i = 0; i < counts->num_imageviews; i++) {
|
||||
__auto_type view = &jinfo->imageviews[i];
|
||||
job->image_views[i] = (qfv_resobj_t) {
|
||||
.name = view->name,
|
||||
img->object = &images[i];
|
||||
|
||||
image_views[i] = (qfv_resobj_t) {
|
||||
.name = imgview->name,
|
||||
.type = qfv_res_image_view,
|
||||
.image_view = {
|
||||
.flags = view->flags,
|
||||
.type = view->viewType,
|
||||
.format = view->format,
|
||||
.components = view->components,
|
||||
.subresourceRange = view->subresourceRange,
|
||||
.image = img->object - rp->resources->objects,
|
||||
.flags = imgview->flags,
|
||||
.type = imgview->viewType,
|
||||
.format = imgview->format,
|
||||
.components = imgview->components,
|
||||
.subresourceRange = imgview->subresourceRange,
|
||||
},
|
||||
};
|
||||
if (strcmp (view->image.name, "$output.image") == 0) {
|
||||
//__auto_type image = jinfo->output.image;
|
||||
//job->image_views[i].image_view.external_image = image;
|
||||
//job->image_views[i].image_view.image = -1;
|
||||
} else {
|
||||
qfv_resobj_t *img = 0;
|
||||
for (uint32_t j = 0; j < jinfo->num_images; j++) {
|
||||
if (strcmp (view->image.name, jinfo->images[j].name) == 0) {
|
||||
img = &job->images[j];
|
||||
}
|
||||
}
|
||||
if (img) {
|
||||
uint32_t ind = img - job->resources->objects;
|
||||
job->image_views[i].image_view.image = ind;
|
||||
// fall back to the image's format if not overriden
|
||||
if (!job->image_views[i].image_view.format) {
|
||||
job->image_views[i].image_view.format = img->image.format;
|
||||
}
|
||||
} else {
|
||||
Sys_Printf ("%d: unknown image reference: %s\n",
|
||||
view->image.line, view->image.name);
|
||||
error = 1;
|
||||
}
|
||||
if (!image_views[i].image_view.format) {
|
||||
image_views[i].image_view.format = img->object->image.format;
|
||||
}
|
||||
imgview->object = &image_views[i];
|
||||
}
|
||||
if (error) {
|
||||
free (job->resources);
|
||||
job->resources = 0;
|
||||
free (rp->resources);
|
||||
rp->resources = 0;
|
||||
return;
|
||||
}
|
||||
QFV_CreateResource (ctx->device, job->resources);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -831,6 +864,7 @@ init_renderpass (qfv_renderpass_t *rp, qfv_renderpassinfo_t *rpinfo,
|
|||
.framebufferinfo = &rpinfo->framebuffer,
|
||||
.outputref = rpinfo->output,
|
||||
};
|
||||
create_resources (s->ctx, rp);
|
||||
s->inds.num_attachments += rpinfo->framebuffer.num_attachments;
|
||||
for (uint32_t i = 0; i < rpinfo->num_subpasses; i++) {
|
||||
init_subpass (&rp->subpasses[i], &rpinfo->subpasses[i], jp, s);
|
||||
|
@ -1178,5 +1212,4 @@ QFV_BuildRender (vulkan_ctx_t *ctx)
|
|||
count_stuff (rctx->jobinfo, &counts);
|
||||
|
||||
create_objects (ctx, &counts);
|
||||
create_resources (ctx, &counts);
|
||||
}
|
||||
|
|
|
@ -291,12 +291,14 @@ QFV_DestroyResource (qfv_device_t *device, qfv_resource_t *resource)
|
|||
{
|
||||
__auto_type buffview = &obj->buffer_view;
|
||||
dfunc->vkDestroyBufferView (device->dev, buffview->view, 0);
|
||||
buffview->view = 0;
|
||||
}
|
||||
break;
|
||||
case qfv_res_image_view:
|
||||
{
|
||||
__auto_type imgview = &obj->image_view;
|
||||
dfunc->vkDestroyImageView (device->dev, imgview->view, 0);
|
||||
imgview->view = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -308,12 +310,14 @@ QFV_DestroyResource (qfv_device_t *device, qfv_resource_t *resource)
|
|||
{
|
||||
__auto_type buffer = &obj->buffer;
|
||||
dfunc->vkDestroyBuffer (device->dev, buffer->buffer, 0);
|
||||
buffer->buffer = 0;
|
||||
}
|
||||
break;
|
||||
case qfv_res_image:
|
||||
{
|
||||
__auto_type image = &obj->image;
|
||||
dfunc->vkDestroyImage (device->dev, image->image, 0);
|
||||
image->image = 0;
|
||||
}
|
||||
break;
|
||||
case qfv_res_buffer_view:
|
||||
|
@ -322,6 +326,7 @@ QFV_DestroyResource (qfv_device_t *device, qfv_resource_t *resource)
|
|||
}
|
||||
}
|
||||
dfunc->vkFreeMemory (device->dev, resource->memory, 0);
|
||||
resource->memory = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1744,14 +1744,6 @@ steps = {
|
|||
);
|
||||
};
|
||||
};
|
||||
translucent = {
|
||||
dependencies = (wait_on_fence);
|
||||
process = {
|
||||
tasks = (
|
||||
{ func = clear_translucent; },
|
||||
);
|
||||
};
|
||||
};
|
||||
setup_main = {
|
||||
dependencies = (wait_on_fence);
|
||||
process = {
|
||||
|
@ -1760,12 +1752,14 @@ steps = {
|
|||
params = ("\"main\""); },
|
||||
{ func = update_framebuffer;
|
||||
params = ("\"main\""); },
|
||||
{ func = clear_translucent;
|
||||
params = ("\"main\""); },
|
||||
{ func = particle_wait_physics; },
|
||||
);
|
||||
};
|
||||
};
|
||||
main = {
|
||||
dependencies = (setup_main, particles, shadow, world, translucent);
|
||||
dependencies = (setup_main, particles, shadow, world);
|
||||
render = {
|
||||
renderpasses = {
|
||||
deferred = $renderpasses.deferred;
|
||||
|
|
|
@ -486,6 +486,28 @@ parse = {
|
|||
values = bindings;
|
||||
};
|
||||
};
|
||||
qfv_imageinfo_s = {
|
||||
.name = qfv_imageinfo_t;
|
||||
flags = auto;
|
||||
imageType = auto;
|
||||
format = auto;
|
||||
extent = auto;
|
||||
mipLevels = auto;
|
||||
arrayLayers = auto;
|
||||
samples = auto;
|
||||
tiling = auto;
|
||||
usage = auto;
|
||||
initialLayout = auto;
|
||||
};
|
||||
qfv_imageviewinfo_s = {
|
||||
.name = qfv_imageviewinfo_t;
|
||||
flags = auto;
|
||||
image = auto;
|
||||
viewType = auto;
|
||||
format = auto;
|
||||
components = auto;
|
||||
subresourceRange = auto;
|
||||
};
|
||||
qfv_bufferviewinfo_s = {
|
||||
.name = qfv_bufferviewinfo_t;
|
||||
buffer = auto;
|
||||
|
|
|
@ -106,7 +106,7 @@ acquire_output (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
rp->beginInfo.framebuffer = 0;
|
||||
//FIXME come up with a better mechanism
|
||||
ctx->swapImageIndex = i;
|
||||
QFV_CreateFramebuffer (ctx, rp);
|
||||
QFV_CreateFramebuffer (ctx, rp, sc->extent);
|
||||
octx->framebuffers[i] = rp->beginInfo.framebuffer;
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_FRAMEBUFFER,
|
||||
octx->framebuffers[i],
|
||||
|
|
|
@ -61,20 +61,92 @@
|
|||
#include "r_internal.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static const char * __attribute__((used)) translucent_pass_names[] = {
|
||||
"clear",
|
||||
"blend",
|
||||
};
|
||||
static void
|
||||
trans_create_buffers (vulkan_ctx_t *ctx)
|
||||
{
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto tctx = ctx->translucent_context;
|
||||
size_t frames = tctx->frames.size;
|
||||
|
||||
if (tctx->resources->memory) {
|
||||
QFV_DestroyResource (device, tctx->resources);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tctx->resources->num_objects; i++) {
|
||||
auto obj = &tctx->resources->objects[i];
|
||||
if (obj->type == qfv_res_image) {
|
||||
auto img = &obj->image;
|
||||
if (img->num_layers == 6) {
|
||||
auto e = min (tctx->extent.width, tctx->extent.height);
|
||||
img->extent.width = e;
|
||||
img->extent.height = e;
|
||||
} else {
|
||||
img->extent.width = tctx->extent.width;
|
||||
img->extent.height = tctx->extent.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
QFV_CreateResource (device, tctx->resources);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
auto tframe = &tctx->frames.a[i];
|
||||
auto heads_view = tframe->heads_view->image_view.view;
|
||||
auto cube_heads_view = tframe->cube_heads_view->image_view.view;
|
||||
auto state = tframe->state->buffer.buffer;
|
||||
auto frags = tframe->frags->buffer.buffer;
|
||||
|
||||
VkDescriptorImageInfo flat_imageInfo[] = {
|
||||
{ 0, heads_view, VK_IMAGE_LAYOUT_GENERAL },
|
||||
};
|
||||
VkDescriptorImageInfo cube_imageInfo[] = {
|
||||
{ 0, cube_heads_view, VK_IMAGE_LAYOUT_GENERAL },
|
||||
};
|
||||
VkDescriptorBufferInfo bufferInfo[] = {
|
||||
{ state, 0, VK_WHOLE_SIZE },
|
||||
{ frags, 0, VK_WHOLE_SIZE },
|
||||
};
|
||||
VkWriteDescriptorSet write[] = {
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->flat, 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = flat_imageInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->flat, 0, 0, 2,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = bufferInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->cube, 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = cube_imageInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->cube, 0, 0, 2,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = bufferInfo },
|
||||
};
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 4, write, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||
{
|
||||
__auto_type taskctx = (qfv_taskctx_t *) ectx;
|
||||
vulkan_ctx_t *ctx = taskctx->ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
translucentctx_t *tctx = ctx->translucent_context;
|
||||
__auto_type tframe = &tctx->frames.a[ctx->curFrame];
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto tctx = ctx->translucent_context;
|
||||
auto tframe = &tctx->frames.a[ctx->curFrame];
|
||||
auto job = ctx->render_context->job;
|
||||
auto step = QFV_GetStep (params[0], job);
|
||||
auto render = step->render;
|
||||
|
||||
if (tctx->extent.width != render->output.extent.width
|
||||
|| tctx->extent.height != render->output.extent.height) {
|
||||
|
||||
tctx->extent = render->output.extent;
|
||||
trans_create_buffers (ctx);
|
||||
}
|
||||
|
||||
VkCommandBuffer cmd = QFV_GetCmdBuffer (ctx, false);
|
||||
|
||||
|
@ -84,7 +156,8 @@ clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
};
|
||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
auto image = scr_fisheye ? tframe->cube_heads : tframe->heads;
|
||||
auto img = scr_fisheye ? tframe->cube_heads : tframe->heads;
|
||||
auto image = img->image.image;
|
||||
qfv_imagebarrier_t ib = imageBarriers[qfv_LT_Undefined_to_TransferDst];
|
||||
ib.barrier.image = image;
|
||||
ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
@ -113,13 +186,16 @@ clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
|
||||
qfv_transtate_t *state = QFV_PacketExtend (packet, 2 * sizeof (*state));
|
||||
*state = (qfv_transtate_t) { 0, tctx->maxFragments };
|
||||
__auto_type bb = &bufferBarriers[qfv_BB_TransferWrite_to_ShaderRW];
|
||||
QFV_PacketCopyBuffer (packet, tframe->state, 0, bb);
|
||||
auto bb = &bufferBarriers[qfv_BB_TransferWrite_to_ShaderRW];
|
||||
QFV_PacketCopyBuffer (packet, tframe->state->buffer.buffer, 0, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
|
||||
static exprtype_t *clear_translucent_params[] = {
|
||||
&cexpr_string,
|
||||
};
|
||||
static exprfunc_t clear_translucent_func[] = {
|
||||
{ .func = clear_translucent },
|
||||
{ .func = clear_translucent, .num_params = 1, clear_translucent_params },
|
||||
{}
|
||||
};
|
||||
static exprsym_t translucent_task_syms[] = {
|
||||
|
@ -136,6 +212,100 @@ Vulkan_Translucent_Init (vulkan_ctx_t *ctx)
|
|||
ctx->translucent_context = tctx;
|
||||
}
|
||||
|
||||
static void
|
||||
trans_create_resources (vulkan_ctx_t *ctx)
|
||||
{
|
||||
auto tctx = ctx->translucent_context;
|
||||
size_t frames = tctx->frames.size;
|
||||
|
||||
tctx->resources = calloc (1, sizeof (qfv_resource_t)
|
||||
// heads images (flat + cube)
|
||||
+ sizeof (qfv_resobj_t[frames]) * 2
|
||||
// heads image views (flat + cube)
|
||||
+ sizeof (qfv_resobj_t[frames]) * 2
|
||||
// fragment buffer
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// fragment count
|
||||
+ sizeof (qfv_resobj_t[frames]));
|
||||
auto heads_objs = (qfv_resobj_t *) &tctx->resources[1];
|
||||
auto cube_heads_objs = &heads_objs[frames];
|
||||
auto head_views_objs = &cube_heads_objs[frames];
|
||||
auto cube_head_views_objs = &head_views_objs[frames];
|
||||
auto buffer_objs = &cube_head_views_objs[frames];
|
||||
auto count_objs = &buffer_objs[frames];
|
||||
tctx->resources[0] = (qfv_resource_t) {
|
||||
.name = "oit",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = 6 * frames,
|
||||
.objects = heads_objs,
|
||||
};
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
heads_objs[i] = (qfv_resobj_t) {
|
||||
.name = nva ("heads:%zd", i),
|
||||
.type = qfv_res_image,
|
||||
.image = {
|
||||
.type = VK_IMAGE_TYPE_2D,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.extent = { 0, 0, 1 },
|
||||
.num_mipmaps = 1,
|
||||
.num_layers = 1,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.usage = VK_IMAGE_USAGE_STORAGE_BIT
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
cube_heads_objs[i] = heads_objs[i];
|
||||
cube_heads_objs[i].name = nva ("cube_heads:%zd", i);
|
||||
cube_heads_objs[i].image.extent = (VkExtent3D) { 0, 0, 1 };
|
||||
cube_heads_objs[i].image.num_layers = 6;
|
||||
head_views_objs[i] = (qfv_resobj_t) {
|
||||
.name = strdup (heads_objs[i].name),
|
||||
.type = qfv_res_image_view,
|
||||
.image_view = {
|
||||
.image = i,
|
||||
.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
},
|
||||
};
|
||||
cube_head_views_objs[i] = head_views_objs[i];
|
||||
cube_head_views_objs[i].name = strdup (cube_heads_objs[i].name);
|
||||
cube_head_views_objs[i].image_view.image = i + frames;
|
||||
buffer_objs[i] = (qfv_resobj_t) {
|
||||
.name = nva ("frags:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = sizeof (qfv_transfrag_t) * tctx->maxFragments,
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
},
|
||||
};
|
||||
count_objs[i] = (qfv_resobj_t) {
|
||||
.name = nva ("count:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = 2 * sizeof (qfv_transtate_t),
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
auto tframe = &tctx->frames.a[i];
|
||||
tframe->heads = &heads_objs[i];
|
||||
tframe->cube_heads = &cube_heads_objs[i];
|
||||
tframe->heads_view = &head_views_objs[i];
|
||||
tframe->cube_heads_view = &cube_head_views_objs[i];
|
||||
tframe->state = &count_objs[i];
|
||||
tframe->frags = &buffer_objs[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Translucent_Setup (vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -158,7 +328,7 @@ Vulkan_Translucent_Setup (vulkan_ctx_t *ctx)
|
|||
.cube = QFV_DSManager_AllocSet (dsmanager),
|
||||
};
|
||||
}
|
||||
Vulkan_Translucent_CreateBuffers (ctx, ctx->swapchain->extent);//FIXME
|
||||
trans_create_resources (ctx);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
|
@ -169,11 +339,15 @@ Vulkan_Translucent_Shutdown (vulkan_ctx_t *ctx)
|
|||
translucentctx_t *tctx = ctx->translucent_context;
|
||||
|
||||
if (tctx->resources) {
|
||||
QFV_DestroyResource (device, tctx->resources);
|
||||
free (tctx->resources);
|
||||
tctx->resources = 0;
|
||||
if (tctx->resources->memory) {
|
||||
QFV_DestroyResource (device, tctx->resources);
|
||||
}
|
||||
for (uint32_t i = 0; i < tctx->resources->num_objects; i++) {
|
||||
auto obj = &tctx->resources->objects[i];
|
||||
free ((char *) obj->name);
|
||||
}
|
||||
}
|
||||
|
||||
free (tctx->resources);
|
||||
free (tctx->frames.a);
|
||||
free (tctx);
|
||||
}
|
||||
|
@ -185,137 +359,3 @@ Vulkan_Translucent_Descriptors (vulkan_ctx_t *ctx, int frame)
|
|||
auto tframe = &tctx->frames.a[frame];
|
||||
return scr_fisheye ? tframe->cube : tframe->flat;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Translucent_CreateBuffers (vulkan_ctx_t *ctx, VkExtent2D extent)
|
||||
{
|
||||
if (!ctx->translucent_context) {//FIXME
|
||||
Vulkan_Translucent_Init (ctx);
|
||||
}
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
__auto_type tctx = ctx->translucent_context;
|
||||
size_t frames = tctx->frames.size;
|
||||
|
||||
if (tctx->resources) {
|
||||
QFV_DestroyResource (device, tctx->resources);
|
||||
free (tctx->resources);
|
||||
tctx->resources = 0;
|
||||
}
|
||||
tctx->resources = malloc (sizeof (qfv_resource_t)
|
||||
// heads images (flat + cube)
|
||||
+ sizeof (qfv_resobj_t[frames]) * 2
|
||||
// heads image views (flat + cube)
|
||||
+ sizeof (qfv_resobj_t[frames]) * 2
|
||||
// fragment buffer
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// fragment count
|
||||
+ sizeof (qfv_resobj_t[frames]));
|
||||
auto heads_objs = (qfv_resobj_t *) &tctx->resources[1];
|
||||
auto cube_heads_objs = &heads_objs[frames];
|
||||
auto head_views_objs = &cube_heads_objs[frames];
|
||||
auto cube_head_views_objs = &head_views_objs[frames];
|
||||
auto buffer_objs = &cube_head_views_objs[frames];
|
||||
auto count_objs = &buffer_objs[frames];
|
||||
tctx->resources[0] = (qfv_resource_t) {
|
||||
.name = "oit",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = 6 * frames,
|
||||
.objects = heads_objs,
|
||||
};
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
heads_objs[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "heads:%zd", i),
|
||||
.type = qfv_res_image,
|
||||
.image = {
|
||||
.type = VK_IMAGE_TYPE_2D,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.extent = { extent.width, extent.height, 1 },
|
||||
.num_mipmaps = 1,
|
||||
.num_layers = 1,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.usage = VK_IMAGE_USAGE_STORAGE_BIT
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
auto e = min (extent.width, extent.height);
|
||||
cube_heads_objs[i] = heads_objs[i];
|
||||
cube_heads_objs[i].name = va (ctx->va_ctx, "cube_heads:%zd", i);
|
||||
cube_heads_objs[i].image.extent = (VkExtent3D) { e, e, 1 };
|
||||
cube_heads_objs[i].image.num_layers = 6;
|
||||
head_views_objs[i] = (qfv_resobj_t) {
|
||||
.name = heads_objs[i].name,
|
||||
.type = qfv_res_image_view,
|
||||
.image_view = {
|
||||
.image = i,
|
||||
.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
},
|
||||
};
|
||||
cube_head_views_objs[i] = head_views_objs[i];
|
||||
cube_head_views_objs[i].name = cube_heads_objs[i].name;
|
||||
cube_head_views_objs[i].image_view.image = i + frames;
|
||||
buffer_objs[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "frags:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = sizeof (qfv_transfrag_t) * tctx->maxFragments,
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
},
|
||||
};
|
||||
count_objs[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "count:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
.size = 2 * sizeof (qfv_transtate_t),
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
}
|
||||
QFV_CreateResource (device, tctx->resources);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type tframe = &tctx->frames.a[i];
|
||||
tframe->heads = heads_objs[i].image.image;
|
||||
tframe->cube_heads = cube_heads_objs[i].image.image;
|
||||
tframe->state = count_objs[i].buffer.buffer;
|
||||
|
||||
VkDescriptorImageInfo flat_imageInfo[] = {
|
||||
{ 0, head_views_objs[i].image_view.view, VK_IMAGE_LAYOUT_GENERAL },
|
||||
};
|
||||
VkDescriptorImageInfo cube_imageInfo[] = {
|
||||
{ 0, cube_head_views_objs[i].image_view.view,
|
||||
VK_IMAGE_LAYOUT_GENERAL },
|
||||
};
|
||||
VkDescriptorBufferInfo bufferInfo[] = {
|
||||
{ count_objs[i].buffer.buffer, 0, VK_WHOLE_SIZE },
|
||||
{ buffer_objs[i].buffer.buffer, 0, VK_WHOLE_SIZE },
|
||||
};
|
||||
VkWriteDescriptorSet write[] = {
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->flat, 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = flat_imageInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->flat, 0, 0, 2,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = bufferInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->cube, 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = cube_imageInfo },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||
tframe->cube, 0, 0, 2,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = bufferInfo },
|
||||
};
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 4, write, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue