mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-18 09:51:40 +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/darray.h"
|
||||||
#include "QF/simd/types.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 {
|
typedef struct vulkan_frame_s {
|
||||||
VkFramebuffer framebuffer;
|
VkFramebuffer framebuffer;
|
||||||
VkFence fence;
|
VkFence fence;
|
||||||
|
@ -91,6 +98,9 @@ typedef struct vulkan_ctx_s {
|
||||||
VkViewport viewport;
|
VkViewport viewport;
|
||||||
VkRect2D scissor;
|
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 EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname;
|
||||||
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname;
|
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname;
|
||||||
#include "QF/Vulkan/funclist.h"
|
#include "QF/Vulkan/funclist.h"
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
format = x8_d24_unorm_pack32;
|
format = x8_d24_unorm_pack32;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
format = r8g8b8a8_unorm;
|
format = r8g8b8a8_unorm;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
format = r16g16b16a16_sfloat;
|
format = r16g16b16a16_sfloat;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -50,8 +50,8 @@
|
||||||
format = r16g16b16a16_sfloat;
|
format = r16g16b16a16_sfloat;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
format = r32g32b32a32_sfloat;
|
format = r32g32b32a32_sfloat;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -80,8 +80,8 @@
|
||||||
format = r8g8b8a8_unorm;
|
format = r8g8b8a8_unorm;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -95,8 +95,8 @@
|
||||||
format = r8g8b8a8_unorm;
|
format = r8g8b8a8_unorm;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
extent = {
|
extent = {
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
};
|
};
|
||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
|
@ -223,9 +223,9 @@
|
||||||
framebuffer = {
|
framebuffer = {
|
||||||
renderPass = $properties.renderpass;
|
renderPass = $properties.renderpass;
|
||||||
attachments = (depth, color, emission, normal, position, opaque,
|
attachments = (depth, color, emission, normal, position, opaque,
|
||||||
translucent, "$swapchain.views[$swapImageIndex]");
|
translucent, $output.view);
|
||||||
width = $swapchain.extent.width;
|
width = $output.extent.width;
|
||||||
height = $swapchain.extent.height;
|
height = $output.extent.height;
|
||||||
layers = 1;
|
layers = 1;
|
||||||
};
|
};
|
||||||
clearValues = (
|
clearValues = (
|
||||||
|
@ -236,7 +236,7 @@
|
||||||
{ color = "[0, 0, 0, 1]"; }, // position
|
{ color = "[0, 0, 0, 1]"; }, // position
|
||||||
{ color = "[0, 0, 0, 1]"; }, // opaque
|
{ color = "[0, 0, 0, 1]"; }, // opaque
|
||||||
{ color = "[0, 0, 0, 0]"; }, // translucent
|
{ color = "[0, 0, 0, 0]"; }, // translucent
|
||||||
{ color = "[0, 0, 0, 1]"; }, // swapchain
|
{ color = "[0, 0, 0, 1]"; }, // output
|
||||||
);
|
);
|
||||||
renderpass = {
|
renderpass = {
|
||||||
attachments = (
|
attachments = (
|
||||||
|
@ -311,7 +311,7 @@
|
||||||
finalLayout = color_attachment_optimal;
|
finalLayout = color_attachment_optimal;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format = $swapchain.format;
|
format = $output.format;
|
||||||
samples = 1;
|
samples = 1;
|
||||||
loadOp = clear;
|
loadOp = clear;
|
||||||
storeOp = store;
|
storeOp = store;
|
||||||
|
@ -414,7 +414,7 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
colorAttachments = (
|
colorAttachments = (
|
||||||
{ // swapchain
|
{ // output
|
||||||
attachment = 7;
|
attachment = 7;
|
||||||
layout = color_attachment_optimal;
|
layout = color_attachment_optimal;
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
#include "QF/Vulkan/instance.h"
|
#include "QF/Vulkan/instance.h"
|
||||||
#include "QF/Vulkan/image.h"
|
#include "QF/Vulkan/image.h"
|
||||||
#include "QF/Vulkan/pipeline.h"
|
#include "QF/Vulkan/pipeline.h"
|
||||||
|
#include "QF/Vulkan/renderpass.h"
|
||||||
#include "QF/Vulkan/shader.h"
|
#include "QF/Vulkan/shader.h"
|
||||||
#include "QF/Vulkan/swapchain.h"
|
|
||||||
|
|
||||||
#include "vid_vulkan.h"
|
#include "vid_vulkan.h"
|
||||||
|
|
||||||
|
@ -51,6 +51,17 @@
|
||||||
#include "vkparse.h"
|
#include "vkparse.h"
|
||||||
#undef vkparse_internal
|
#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,
|
static void flag_or (const exprval_t *val1, const exprval_t *val2,
|
||||||
exprval_t *result, exprctx_t *ctx)
|
exprval_t *result, exprctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
@ -577,7 +588,7 @@ parse_VkImage (const plitem_t *item, void **data, plitem_t *messages,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static exprtype_t imageview_type = {
|
exprtype_t VkImageView_type = {
|
||||||
"VkImageView",
|
"VkImageView",
|
||||||
sizeof (VkImageView),
|
sizeof (VkImageView),
|
||||||
0, 0, 0
|
0, 0, 0
|
||||||
|
@ -610,7 +621,7 @@ parse_VkImageView (const plfield_t *field, const plitem_t *item, void *data,
|
||||||
plitem_t *imageViewItem = 0;
|
plitem_t *imageViewItem = 0;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
VkImageView imageView;
|
VkImageView imageView;
|
||||||
if (value->type == &imageview_type) {
|
if (value->type == &VkImageView_type) {
|
||||||
imageView = *(VkImageView *) value->value;
|
imageView = *(VkImageView *) value->value;
|
||||||
} else if (value->type == &cexpr_plitem) {
|
} else if (value->type == &cexpr_plitem) {
|
||||||
imageView = QFV_ParseImageView (ctx, imageViewItem,
|
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"
|
#include "libs/video/renderer/vulkan/vkparse.cinc"
|
||||||
|
|
||||||
static void
|
static exprsym_t qfv_output_t_symbols[] = {
|
||||||
imageviewset_index (const exprval_t *a, size_t index, exprval_t *c,
|
{"format", &VkFormat_type, (void *)field_offset (qfv_output_t, format)},
|
||||||
exprctx_t *ctx)
|
{"extent", &VkExtent2D_type, (void *)field_offset (qfv_output_t, extent)},
|
||||||
{
|
{"view", &VkImageView_type, (void *)field_offset (qfv_output_t, view)},
|
||||||
__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 exprtab_t imageviewset_symtab = {
|
static exprtab_t qfv_output_t_symtab = {
|
||||||
imageviewset_symbols,
|
qfv_output_t_symbols,
|
||||||
};
|
};
|
||||||
exprtype_t imageviewset_type = {
|
exprtype_t qfv_output_t_type = {
|
||||||
"imageviewset",
|
"qfv_output_t",
|
||||||
sizeof (qfv_imageviewset_t *),
|
sizeof (qfv_output_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),
|
|
||||||
cexpr_struct_binops,
|
cexpr_struct_binops,
|
||||||
0,
|
0,
|
||||||
&qfv_swapchain_t_symtab,
|
&qfv_output_t_symtab,
|
||||||
};
|
};
|
||||||
|
|
||||||
static exprsym_t vulkan_frameset_t_symbols[] = {
|
static exprsym_t vulkan_frameset_t_symbols[] = {
|
||||||
|
@ -1023,9 +973,8 @@ QFV_InitParse (vulkan_ctx_t *ctx)
|
||||||
&ctx->hashlinks);
|
&ctx->hashlinks);
|
||||||
context.hashlinks = &ctx->hashlinks;
|
context.hashlinks = &ctx->hashlinks;
|
||||||
vkgen_init_symtabs (&context);
|
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 (&vulkan_frameset_t_symtab, &context);
|
||||||
cexpr_init_symtab (&imageviewset_symtab, &context);
|
|
||||||
cexpr_init_symtab (&data_array_symtab, &context);
|
cexpr_init_symtab (&data_array_symtab, &context);
|
||||||
|
|
||||||
if (!ctx->setLayouts) {
|
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 };
|
exprctx_t exprctx = { .symtab = &root_symtab };
|
||||||
parsectx_t parsectx = { &exprctx, ctx, properties };
|
parsectx_t parsectx = { &exprctx, ctx, properties };
|
||||||
exprsym_t var_syms[] = {
|
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},
|
{"frames", &vulkan_frameset_t_type, &ctx->frames},
|
||||||
{"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples},
|
{"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples},
|
||||||
{"swapImageIndex", &cexpr_uint, &ctx->swapImageIndex},
|
|
||||||
{"physDevLimits", &VkPhysicalDeviceLimits_type,
|
{"physDevLimits", &VkPhysicalDeviceLimits_type,
|
||||||
&ctx->device->physDev->properties.limits },
|
&ctx->device->physDev->properties.limits },
|
||||||
{QFV_PROPERTIES, &cexpr_plitem, &parsectx.properties},
|
{QFV_PROPERTIES, &cexpr_plitem, &parsectx.properties},
|
||||||
|
|
|
@ -10,24 +10,12 @@ typedef struct parsectx_s {
|
||||||
|
|
||||||
#include "QF/cexpr.h"
|
#include "QF/cexpr.h"
|
||||||
#include "QF/plist.h"
|
#include "QF/plist.h"
|
||||||
#include "QF/Vulkan/renderpass.h"
|
|
||||||
#ifdef vkparse_internal
|
#ifdef vkparse_internal
|
||||||
#include "libs/video/renderer/vulkan/vkparse.hinc"
|
#include "libs/video/renderer/vulkan/vkparse.hinc"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define QFV_PROPERTIES "properties"
|
#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);
|
void QFV_InitParse (vulkan_ctx_t *ctx);
|
||||||
exprenum_t *QFV_GetEnum (const char *name);
|
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,
|
rp->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages,
|
||||||
malloc);
|
malloc);
|
||||||
for (size_t i = 0; i < rp->framebuffers->size; i++) {
|
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->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item,
|
||||||
rp->renderpassDef);
|
rp->renderpassDef);
|
||||||
}
|
}
|
||||||
|
@ -424,6 +428,11 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
|
||||||
if (renderpass) {
|
if (renderpass) {
|
||||||
rp->renderpass = renderpass;
|
rp->renderpass = renderpass;
|
||||||
} else {
|
} 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);
|
item = qfv_load_renderpass (ctx, rp, name);
|
||||||
rp->renderpass = QFV_ParseRenderPass (ctx, item, rp->renderpassDef);
|
rp->renderpass = QFV_ParseRenderPass (ctx, item, rp->renderpassDef);
|
||||||
QFV_AddHandle (tab, path, (uint64_t) rp->renderpass);
|
QFV_AddHandle (tab, path, (uint64_t) rp->renderpass);
|
||||||
|
|
Loading…
Reference in a new issue