mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vulkan] Create the render images and views
And tear them down again on shutdown. The images and views are in a qfv_resource_t block, making their management much easier.
This commit is contained in:
parent
1ef658a260
commit
421467529f
5 changed files with 243 additions and 14 deletions
|
@ -41,8 +41,7 @@ typedef struct qfv_imageinfo_s {
|
|||
typedef struct qfv_imageviewinfo_s {
|
||||
const char *name;
|
||||
VkImageViewCreateFlags flags;
|
||||
//VkImage image;
|
||||
const char *image;
|
||||
qfv_reference_t image;
|
||||
VkImageViewType viewType;
|
||||
VkFormat format;
|
||||
VkComponentMapping components;
|
||||
|
@ -102,7 +101,6 @@ typedef struct qfv_attachmentsetinfo_s {
|
|||
typedef struct qfv_pipelineinfo_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
qfv_reference_t pipeline;
|
||||
uint32_t num_tasks;
|
||||
qfv_taskinfo_t *tasks;
|
||||
|
||||
|
@ -118,7 +116,7 @@ typedef struct qfv_pipelineinfo_s {
|
|||
const VkPipelineDepthStencilStateCreateInfo *depthStencil;
|
||||
const VkPipelineColorBlendStateCreateInfo *colorBlend;
|
||||
const VkPipelineDynamicStateCreateInfo *dynamic;
|
||||
qfv_reference_t *layout;
|
||||
qfv_reference_t layout;
|
||||
} qfv_pipelineinfo_t;
|
||||
|
||||
typedef struct qfv_subpassinfo_s {
|
||||
|
@ -157,14 +155,9 @@ typedef struct qfv_renderinfo_s {
|
|||
qfv_imageviewinfo_t *views;
|
||||
uint32_t num_renderpasses;
|
||||
qfv_renderpassinfo_t *renderpasses;
|
||||
qfv_output_t output;
|
||||
} qfv_renderinfo_t;
|
||||
|
||||
typedef struct qfv_renderctx_s {
|
||||
struct hashctx_s *hashctx;
|
||||
exprtab_t task_functions;
|
||||
qfv_renderinfo_t *renderinfo;
|
||||
} qfv_renderctx_t;
|
||||
|
||||
typedef struct qfv_label_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
@ -217,9 +210,24 @@ typedef struct qfv_renderpass_s_ {
|
|||
qfv_subpass_t_ *subpasses;
|
||||
} qfv_renderpass_t_;
|
||||
|
||||
typedef struct qfv_render_s {
|
||||
struct qfv_resource_s *resources;
|
||||
struct qfv_resobj_s *images;
|
||||
struct qfv_resobj_s *image_views;
|
||||
} qfv_render_t;
|
||||
|
||||
typedef struct qfv_renderctx_s {
|
||||
struct hashctx_s *hashctx;
|
||||
exprtab_t task_functions;
|
||||
qfv_renderinfo_t *renderinfo;
|
||||
qfv_render_t *render;
|
||||
} qfv_renderctx_t;
|
||||
|
||||
void QFV_RunRenderPass (qfv_renderpass_t_ *rp, struct vulkan_ctx_s *ctx);
|
||||
void QFV_LoadRenderPass (struct vulkan_ctx_s *ctx);
|
||||
void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx);
|
||||
void QFV_BuildRender (struct vulkan_ctx_s *ctx);
|
||||
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);
|
||||
|
||||
#endif//__QF_Vulkan_render_h
|
||||
|
|
|
@ -116,7 +116,8 @@ vulkan_R_Init (void)
|
|||
Vulkan_Translucent_Init (vulkan_ctx);
|
||||
Vulkan_Compose_Init (vulkan_ctx);
|
||||
|
||||
QFV_LoadRenderPass (vulkan_ctx);
|
||||
QFV_LoadRenderInfo (vulkan_ctx);
|
||||
QFV_BuildRender (vulkan_ctx);
|
||||
|
||||
Skin_Init ();
|
||||
|
||||
|
@ -742,6 +743,8 @@ vulkan_vid_render_shutdown (void)
|
|||
Vulkan_Palette_Shutdown (vulkan_ctx);
|
||||
Vulkan_Texture_Shutdown (vulkan_ctx);
|
||||
|
||||
QFV_Render_Shutdown (vulkan_ctx);
|
||||
|
||||
QFV_DestroyStagingBuffer (vulkan_ctx->staging);
|
||||
df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0);
|
||||
|
||||
|
|
|
@ -38,11 +38,13 @@
|
|||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/cmem.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/debug.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "QF/Vulkan/resource.h"
|
||||
#include "QF/Vulkan/pipeline.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
|
@ -124,15 +126,201 @@ QFV_RunRenderPass (qfv_renderpass_t_ *rp, vulkan_ctx_t *ctx)
|
|||
QFV_CmdEndLabel (device, cmd);
|
||||
}
|
||||
|
||||
static qfv_output_t
|
||||
get_output (vulkan_ctx_t *ctx, plitem_t *item)
|
||||
{
|
||||
qfv_output_t output = {};
|
||||
Vulkan_ConfigOutput (ctx, &output);
|
||||
|
||||
plitem_t *output_def = PL_ObjectForKey (item, "output");
|
||||
if (output_def) {
|
||||
// QFV_ParseOutput clears the structure, but extent and frames need to
|
||||
// be preserved
|
||||
qfv_output_t o = output;
|
||||
QFV_ParseOutput (ctx, &o, output_def, item);
|
||||
output.format = o.format;
|
||||
output.finalLayout = o.finalLayout;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
void
|
||||
QFV_LoadRenderPass (vulkan_ctx_t *ctx)
|
||||
QFV_LoadRenderInfo (vulkan_ctx_t *ctx)
|
||||
{
|
||||
__auto_type rctx = ctx->render_context;
|
||||
|
||||
plitem_t *item = Vulkan_GetConfig (ctx, "main_def");
|
||||
__auto_type output = get_output (ctx, item);
|
||||
Vulkan_Script_SetOutput (ctx, &output);
|
||||
rctx->renderinfo = QFV_ParseRenderInfo (ctx, item, rctx);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t num_images;
|
||||
uint32_t num_views;
|
||||
|
||||
uint32_t num_renderpasses;
|
||||
uint32_t num_attachments;
|
||||
uint32_t num_subpasses;
|
||||
uint32_t num_dependencies;
|
||||
uint32_t num_attachmentrefs;
|
||||
uint32_t num_colorblend;
|
||||
uint32_t num_preserve;
|
||||
uint32_t num_pipelines;
|
||||
uint32_t num_tasks;
|
||||
uint32_t num_stages;
|
||||
} objcount_t;
|
||||
|
||||
static void
|
||||
count_pl_stuff (qfv_pipelineinfo_t *pli, objcount_t *counts)
|
||||
{
|
||||
counts->num_tasks += pli->num_tasks;
|
||||
counts->num_stages += pli->num_graph_stages;
|
||||
}
|
||||
|
||||
static void
|
||||
count_as_stuff (qfv_attachmentsetinfo_t *as, objcount_t *counts)
|
||||
{
|
||||
counts->num_attachmentrefs += as->num_input;
|
||||
counts->num_attachmentrefs += as->num_color;
|
||||
counts->num_colorblend += as->num_color;
|
||||
if (as->resolve) {
|
||||
counts->num_attachmentrefs += as->num_color;
|
||||
}
|
||||
if (as->depth) {
|
||||
counts->num_attachmentrefs += 1;
|
||||
}
|
||||
counts->num_preserve += as->num_preserve;
|
||||
}
|
||||
|
||||
static void
|
||||
count_sp_stuff (qfv_subpassinfo_t *spi, objcount_t *counts)
|
||||
{
|
||||
counts->num_dependencies += spi->num_dependencies;
|
||||
if (spi->attachments) {
|
||||
count_as_stuff (spi->attachments, counts);
|
||||
}
|
||||
counts->num_pipelines += spi->num_pipelines;
|
||||
for (uint32_t i = 0; i < spi->num_pipelines; i++) {
|
||||
count_pl_stuff (spi->pipelines, counts);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
count_rp_stuff (qfv_renderpassinfo_t *rpi, objcount_t *counts)
|
||||
{
|
||||
counts->num_attachments += rpi->num_attachments;
|
||||
counts->num_subpasses += rpi->num_subpasses;
|
||||
for (uint32_t i = 0; i < rpi->num_subpasses; i++) {
|
||||
count_sp_stuff (&rpi->subpasses[i], counts);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
count_stuff (qfv_renderinfo_t *renderinfo, objcount_t *counts)
|
||||
{
|
||||
counts->num_images += renderinfo->num_images;
|
||||
counts->num_views += renderinfo->num_views;
|
||||
counts->num_renderpasses += renderinfo->num_renderpasses;
|
||||
for (uint32_t i = 0; i < renderinfo->num_renderpasses; i++) {
|
||||
count_rp_stuff (&renderinfo->renderpasses[i], counts);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_resources (vulkan_ctx_t *ctx, objcount_t *counts)
|
||||
{
|
||||
__auto_type rctx = ctx->render_context;
|
||||
__auto_type rinfo = rctx->renderinfo;
|
||||
__auto_type render = rctx->render;
|
||||
|
||||
render->resources = malloc (sizeof(qfv_resource_t)
|
||||
+ counts->num_images * sizeof (qfv_resobj_t)
|
||||
+ counts->num_views * sizeof (qfv_resobj_t));
|
||||
render->images = (qfv_resobj_t *) &render->resources[1];
|
||||
render->image_views = &render->images[counts->num_images];
|
||||
|
||||
render->resources[0] = (qfv_resource_t) {
|
||||
.name = "render",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = counts->num_images + counts->num_views,
|
||||
.objects = render->images,
|
||||
};
|
||||
for (uint32_t i = 0; i < counts->num_images; i++) {
|
||||
__auto_type img = &rinfo->images[i];
|
||||
render->images[i] = (qfv_resobj_t) {
|
||||
.name = img->name,
|
||||
.type = qfv_res_image,
|
||||
.image = {
|
||||
.flags = img->flags,
|
||||
.type = img->imageType,
|
||||
.format = img->format,
|
||||
.extent = img->extent,
|
||||
.num_mipmaps = img->mipLevels,
|
||||
.num_layers = img->arrayLayers,
|
||||
.samples = img->samples,
|
||||
.tiling = img->tiling,
|
||||
.usage = img->usage,
|
||||
.initialLayout = img->initialLayout,
|
||||
},
|
||||
};
|
||||
}
|
||||
int error = 0;
|
||||
for (uint32_t i = 0; i < counts->num_views; i++) {
|
||||
__auto_type view = &rinfo->views[i];
|
||||
render->image_views[i] = (qfv_resobj_t) {
|
||||
.name = view->name,
|
||||
.type = qfv_res_image_view,
|
||||
.image_view = {
|
||||
.flags = view->flags,
|
||||
.type = view->viewType,
|
||||
.format = view->format,
|
||||
.components = view->components,
|
||||
.subresourceRange = view->subresourceRange,
|
||||
},
|
||||
};
|
||||
if (strcmp (view->image.name, "$output.image") == 0) {
|
||||
__auto_type image = rinfo->output.image;
|
||||
render->image_views[i].image_view.external_image = image;
|
||||
render->image_views[i].image_view.image = -1;
|
||||
} else {
|
||||
qfv_resobj_t *img = 0;
|
||||
for (uint32_t j = 0; j < rinfo->num_images; j++) {
|
||||
if (strcmp (view->image.name, rinfo->images[j].name) == 0) {
|
||||
img = &render->images[j];
|
||||
}
|
||||
}
|
||||
if (img) {
|
||||
uint32_t ind = img - render->resources->objects;
|
||||
render->image_views[i].image_view.image = ind;
|
||||
} else {
|
||||
Sys_Printf ("%d: unknown image reference: %s\n",
|
||||
view->image.line, view->image.name);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
free (render->resources);
|
||||
render->resources = 0;
|
||||
return;
|
||||
}
|
||||
QFV_CreateResource (ctx->device, render->resources);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_BuildRender (vulkan_ctx_t *ctx)
|
||||
{
|
||||
__auto_type rctx = ctx->render_context;
|
||||
|
||||
rctx->render = calloc (1, sizeof (qfv_render_t));
|
||||
|
||||
objcount_t counts = {};
|
||||
count_stuff (rctx->renderinfo, &counts);
|
||||
create_resources (ctx, &counts);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_Render_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -146,6 +334,25 @@ QFV_Render_Init (vulkan_ctx_t *ctx)
|
|||
rctx->task_functions.symbols = 0;
|
||||
}
|
||||
|
||||
void
|
||||
QFV_Render_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
__auto_type rctx = ctx->render_context;
|
||||
if (rctx->render) {
|
||||
if (rctx->render->resources) {
|
||||
QFV_DestroyResource (ctx->device, rctx->render->resources);
|
||||
free (rctx->render->resources);
|
||||
}
|
||||
free (rctx->render);
|
||||
}
|
||||
if (rctx->renderinfo) {
|
||||
delete_memsuper (rctx->renderinfo->memsuper);
|
||||
}
|
||||
if (rctx->task_functions.tab) {
|
||||
Hash_DelTable (rctx->task_functions.tab);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QFV_Render_AddTasks (vulkan_ctx_t *ctx, exprsym_t *task_syms)
|
||||
{
|
||||
|
|
|
@ -521,6 +521,11 @@ images = {
|
|||
@inherit = $image_base;
|
||||
format = r16g16b16a16_sfloat;
|
||||
};
|
||||
output = {
|
||||
@inherit = $image_base;
|
||||
usage = color_attachment|input_attachment|sampled;
|
||||
format = $output.format;
|
||||
};
|
||||
};
|
||||
views = {
|
||||
depth = {
|
||||
|
@ -558,10 +563,15 @@ views = {
|
|||
};
|
||||
output = {
|
||||
@inherit = $view_base;
|
||||
image = $output.image;
|
||||
image = output;
|
||||
format = $output.format;
|
||||
}
|
||||
};
|
||||
output = {
|
||||
view = $output;
|
||||
format = r16g16b16a16_sfloat;
|
||||
finalLayout = shader_read_only_optimal;
|
||||
};
|
||||
renderpasses = {
|
||||
deferred = {
|
||||
attachments = {
|
||||
|
|
|
@ -604,6 +604,7 @@
|
|||
qfv_renderinfo_s = {
|
||||
.name = qfv_renderinfo_t;
|
||||
properties = ignore;
|
||||
output = ignore;
|
||||
images = {
|
||||
type = (labeledarray, qfv_imageinfo_t, name);
|
||||
size = num_images;
|
||||
|
|
Loading…
Reference in a new issue