mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[vulkan] Break render pass parsing away from swapchain
This allows a single render pass description to be used for both on-screen and off-screen targets. While Vulkan does allow a VkRenderPass to be used with any compatible frame buffer, and vkparse caches a VkRenderPass created from the same description, this allows the same description to be used for a compatible off-screen target without any dependence on the swapchain. However, there is a problem in the caching when it comes to targeting outputs with different formats.
This commit is contained in:
parent
88343d73ea
commit
b2d4fa0ccf
5 changed files with 66 additions and 111 deletions
|
@ -9,6 +9,13 @@
|
|||
#include "QF/darray.h"
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
//FIXME name
|
||||
typedef struct qfv_output_s {
|
||||
VkExtent2D extent;
|
||||
VkImageView view;
|
||||
VkFormat format;
|
||||
} qfv_output_t;
|
||||
|
||||
typedef struct vulkan_frame_s {
|
||||
VkFramebuffer framebuffer;
|
||||
VkFence fence;
|
||||
|
@ -91,6 +98,9 @@ typedef struct vulkan_ctx_s {
|
|||
VkViewport viewport;
|
||||
VkRect2D scissor;
|
||||
|
||||
//FIXME not sure I like it being here (also, type name)
|
||||
qfv_output_t output;
|
||||
|
||||
#define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname;
|
||||
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname;
|
||||
#include "QF/Vulkan/funclist.h"
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
format = x8_d24_unorm_pack32;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -20,8 +20,8 @@
|
|||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -35,8 +35,8 @@
|
|||
format = r16g16b16a16_sfloat;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -50,8 +50,8 @@
|
|||
format = r16g16b16a16_sfloat;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -65,8 +65,8 @@
|
|||
format = r32g32b32a32_sfloat;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -80,8 +80,8 @@
|
|||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -95,8 +95,8 @@
|
|||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
|
@ -223,9 +223,9 @@
|
|||
framebuffer = {
|
||||
renderPass = $properties.renderpass;
|
||||
attachments = (depth, color, emission, normal, position, opaque,
|
||||
translucent, "$swapchain.views[$swapImageIndex]");
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
translucent, $output.view);
|
||||
width = $output.extent.width;
|
||||
height = $output.extent.height;
|
||||
layers = 1;
|
||||
};
|
||||
clearValues = (
|
||||
|
@ -236,7 +236,7 @@
|
|||
{ color = "[0, 0, 0, 1]"; }, // position
|
||||
{ color = "[0, 0, 0, 1]"; }, // opaque
|
||||
{ color = "[0, 0, 0, 0]"; }, // translucent
|
||||
{ color = "[0, 0, 0, 1]"; }, // swapchain
|
||||
{ color = "[0, 0, 0, 1]"; }, // output
|
||||
);
|
||||
renderpass = {
|
||||
attachments = (
|
||||
|
@ -311,7 +311,7 @@
|
|||
finalLayout = color_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $swapchain.format;
|
||||
format = $output.format;
|
||||
samples = 1;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
|
@ -414,7 +414,7 @@
|
|||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // swapchain
|
||||
{ // output
|
||||
attachment = 7;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
#include "QF/Vulkan/instance.h"
|
||||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/pipeline.h"
|
||||
#include "QF/Vulkan/renderpass.h"
|
||||
#include "QF/Vulkan/shader.h"
|
||||
#include "QF/Vulkan/swapchain.h"
|
||||
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
|
@ -51,6 +51,17 @@
|
|||
#include "vkparse.h"
|
||||
#undef vkparse_internal
|
||||
|
||||
typedef struct parseres_s {
|
||||
const char *name;
|
||||
plfield_t *field;
|
||||
size_t offset;
|
||||
} parseres_t;
|
||||
|
||||
typedef struct handleref_s {
|
||||
char *name;
|
||||
uint64_t handle;
|
||||
} handleref_t;
|
||||
|
||||
static void flag_or (const exprval_t *val1, const exprval_t *val2,
|
||||
exprval_t *result, exprctx_t *ctx)
|
||||
{
|
||||
|
@ -577,7 +588,7 @@ parse_VkImage (const plitem_t *item, void **data, plitem_t *messages,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static exprtype_t imageview_type = {
|
||||
exprtype_t VkImageView_type = {
|
||||
"VkImageView",
|
||||
sizeof (VkImageView),
|
||||
0, 0, 0
|
||||
|
@ -610,7 +621,7 @@ parse_VkImageView (const plfield_t *field, const plitem_t *item, void *data,
|
|||
plitem_t *imageViewItem = 0;
|
||||
if (ret) {
|
||||
VkImageView imageView;
|
||||
if (value->type == &imageview_type) {
|
||||
if (value->type == &VkImageView_type) {
|
||||
imageView = *(VkImageView *) value->value;
|
||||
} else if (value->type == &cexpr_plitem) {
|
||||
imageView = QFV_ParseImageView (ctx, imageViewItem,
|
||||
|
@ -856,82 +867,21 @@ parse_specialization_data (const plitem_t *item, void **data,
|
|||
|
||||
#include "libs/video/renderer/vulkan/vkparse.cinc"
|
||||
|
||||
static void
|
||||
imageviewset_index (const exprval_t *a, size_t index, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
__auto_type set = *(qfv_imageviewset_t **) a->value;
|
||||
exprval_t *val = 0;
|
||||
if (index >= set->size) {
|
||||
cexpr_error (ctx, "invalid index: %zd", index);
|
||||
} else {
|
||||
val = cexpr_value (&imageview_type, ctx);
|
||||
*(VkImageView *) val->value = set->a[index];
|
||||
}
|
||||
*(exprval_t **) c->value = val;
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_int (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(int *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_uint (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(unsigned *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_size_t (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(size_t *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
binop_t imageviewset_binops[] = {
|
||||
{ '.', &cexpr_field, &cexpr_exprval, cexpr_struct_pointer_getfield },
|
||||
{ '[', &cexpr_int, &imageview_type, imageviewset_int },
|
||||
{ '[', &cexpr_uint, &imageview_type, imageviewset_uint },
|
||||
{ '[', &cexpr_size_t, &imageview_type, imageviewset_size_t },
|
||||
{}
|
||||
};
|
||||
|
||||
static exprsym_t imageviewset_symbols[] = {
|
||||
{"size", &cexpr_size_t, (void *)field_offset (qfv_imageviewset_t, size)},
|
||||
static exprsym_t qfv_output_t_symbols[] = {
|
||||
{"format", &VkFormat_type, (void *)field_offset (qfv_output_t, format)},
|
||||
{"extent", &VkExtent2D_type, (void *)field_offset (qfv_output_t, extent)},
|
||||
{"view", &VkImageView_type, (void *)field_offset (qfv_output_t, view)},
|
||||
{ }
|
||||
};
|
||||
static exprtab_t imageviewset_symtab = {
|
||||
imageviewset_symbols,
|
||||
static exprtab_t qfv_output_t_symtab = {
|
||||
qfv_output_t_symbols,
|
||||
};
|
||||
exprtype_t imageviewset_type = {
|
||||
"imageviewset",
|
||||
sizeof (qfv_imageviewset_t *),
|
||||
imageviewset_binops,
|
||||
0,
|
||||
&imageviewset_symtab,
|
||||
};
|
||||
static exprsym_t qfv_swapchain_t_symbols[] = {
|
||||
{"format", &VkFormat_type, (void *)field_offset (qfv_swapchain_t, format)},
|
||||
{"extent", &VkExtent2D_type, (void *)field_offset (qfv_swapchain_t, extent)},
|
||||
{"views", &imageviewset_type, (void *)field_offset (qfv_swapchain_t, imageViews)},
|
||||
{ }
|
||||
};
|
||||
static exprtab_t qfv_swapchain_t_symtab = {
|
||||
qfv_swapchain_t_symbols,
|
||||
};
|
||||
exprtype_t qfv_swapchain_t_type = {
|
||||
"qfv_swapchain_t",
|
||||
sizeof (qfv_swapchain_t),
|
||||
exprtype_t qfv_output_t_type = {
|
||||
"qfv_output_t",
|
||||
sizeof (qfv_output_t),
|
||||
cexpr_struct_binops,
|
||||
0,
|
||||
&qfv_swapchain_t_symtab,
|
||||
&qfv_output_t_symtab,
|
||||
};
|
||||
|
||||
static exprsym_t vulkan_frameset_t_symbols[] = {
|
||||
|
@ -1023,9 +973,8 @@ QFV_InitParse (vulkan_ctx_t *ctx)
|
|||
&ctx->hashlinks);
|
||||
context.hashlinks = &ctx->hashlinks;
|
||||
vkgen_init_symtabs (&context);
|
||||
cexpr_init_symtab (&qfv_swapchain_t_symtab, &context);
|
||||
cexpr_init_symtab (&qfv_output_t_symtab, &context);
|
||||
cexpr_init_symtab (&vulkan_frameset_t_symtab, &context);
|
||||
cexpr_init_symtab (&imageviewset_symtab, &context);
|
||||
cexpr_init_symtab (&data_array_symtab, &context);
|
||||
|
||||
if (!ctx->setLayouts) {
|
||||
|
@ -1054,10 +1003,9 @@ parse_object (vulkan_ctx_t *ctx, memsuper_t *memsuper, plitem_t *plist,
|
|||
exprctx_t exprctx = { .symtab = &root_symtab };
|
||||
parsectx_t parsectx = { &exprctx, ctx, properties };
|
||||
exprsym_t var_syms[] = {
|
||||
{"swapchain", &qfv_swapchain_t_type, ctx->swapchain},
|
||||
{"output", &qfv_output_t_type, &ctx->output},
|
||||
{"frames", &vulkan_frameset_t_type, &ctx->frames},
|
||||
{"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples},
|
||||
{"swapImageIndex", &cexpr_uint, &ctx->swapImageIndex},
|
||||
{"physDevLimits", &VkPhysicalDeviceLimits_type,
|
||||
&ctx->device->physDev->properties.limits },
|
||||
{QFV_PROPERTIES, &cexpr_plitem, &parsectx.properties},
|
||||
|
|
|
@ -10,24 +10,12 @@ typedef struct parsectx_s {
|
|||
|
||||
#include "QF/cexpr.h"
|
||||
#include "QF/plist.h"
|
||||
#include "QF/Vulkan/renderpass.h"
|
||||
#ifdef vkparse_internal
|
||||
#include "libs/video/renderer/vulkan/vkparse.hinc"
|
||||
#endif
|
||||
|
||||
#define QFV_PROPERTIES "properties"
|
||||
|
||||
typedef struct parseres_s {
|
||||
const char *name;
|
||||
plfield_t *field;
|
||||
size_t offset;
|
||||
} parseres_t;
|
||||
|
||||
typedef struct handleref_s {
|
||||
char *name;
|
||||
uint64_t handle;
|
||||
} handleref_t;
|
||||
|
||||
void QFV_InitParse (vulkan_ctx_t *ctx);
|
||||
exprenum_t *QFV_GetEnum (const char *name);
|
||||
|
||||
|
|
|
@ -388,7 +388,11 @@ create_attachements (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
|||
rp->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages,
|
||||
malloc);
|
||||
for (size_t i = 0; i < rp->framebuffers->size; i++) {
|
||||
ctx->swapImageIndex = i; // for $swapImageIndex in the config
|
||||
ctx->output = (qfv_output_t) {
|
||||
.extent = ctx->swapchain->extent,
|
||||
.view = ctx->swapchain->imageViews->a[i],
|
||||
.format = ctx->swapchain->format,
|
||||
};
|
||||
rp->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item,
|
||||
rp->renderpassDef);
|
||||
}
|
||||
|
@ -424,6 +428,11 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
|
|||
if (renderpass) {
|
||||
rp->renderpass = renderpass;
|
||||
} else {
|
||||
ctx->output = (qfv_output_t) {
|
||||
.extent = ctx->swapchain->extent,
|
||||
.view = ctx->swapchain->imageViews->a[0],
|
||||
.format = ctx->swapchain->format,
|
||||
};
|
||||
item = qfv_load_renderpass (ctx, rp, name);
|
||||
rp->renderpass = QFV_ParseRenderPass (ctx, item, rp->renderpassDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) rp->renderpass);
|
||||
|
|
Loading…
Reference in a new issue