mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vulkan] Run the shadow render passes
The shadow maps are rendered incorrectly because the matrices aren't set correctly yet, but the dual-pass bsp rendering is working.
This commit is contained in:
parent
3d4cca4393
commit
931175b21d
5 changed files with 153 additions and 16 deletions
|
@ -61,6 +61,9 @@ typedef struct qfv_light_buffer_s {
|
|||
#define LIGHTING_SHADOW_INFOS 32
|
||||
#define LIGHTING_DESCRIPTORS (LIGHTING_BUFFER_INFOS + LIGHTING_ATTACH_INFOS + 1)
|
||||
|
||||
typedef struct qfv_framebufferset_s
|
||||
DARRAY_TYPE (VkFramebuffer) qfv_framebufferset_t;
|
||||
|
||||
typedef struct lightingframe_s {
|
||||
VkBuffer data_buffer;
|
||||
VkBuffer id_buffer;
|
||||
|
@ -79,6 +82,9 @@ typedef struct lightingframe_s {
|
|||
VkWriteDescriptorSet shadowWrite;
|
||||
};
|
||||
};
|
||||
|
||||
qfv_imageviewset_t views;
|
||||
qfv_framebufferset_t framebuffers;
|
||||
} lightingframe_t;
|
||||
|
||||
typedef struct lightingframeset_s
|
||||
|
|
|
@ -1920,6 +1920,7 @@ steps = {
|
|||
dependencies = (wait_on_fence);
|
||||
process = {
|
||||
tasks = (
|
||||
{ func = bsp_reset_queues; },
|
||||
{ func = bsp_visit_world;
|
||||
params = (main); },
|
||||
{ func = scene_draw_viewmodel; },
|
||||
|
|
|
@ -838,6 +838,7 @@ clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
|
|||
static void
|
||||
queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
|
||||
{
|
||||
uint32_t base = bframe->index_count;
|
||||
pass->indices = bframe->index_data + bframe->index_count;
|
||||
for (size_t i = 0; i < bctx->registered_textures.size; i++) {
|
||||
auto queue = &pass->face_queue[i];
|
||||
|
@ -882,7 +883,7 @@ queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
|
|||
.tex_id = i,
|
||||
.inst_id = is.inst_id,
|
||||
.instance_count = instance->entities.size,
|
||||
.first_index = pass->index_count,
|
||||
.first_index = pass->index_count + base,
|
||||
.first_instance = instance->first_instance,
|
||||
}));
|
||||
dq_size = pass->draw_queues[dq].size;
|
||||
|
@ -1121,6 +1122,20 @@ create_notexture (vulkan_ctx_t *ctx)
|
|||
bctx->notexture.tex = Vulkan_LoadTexArray (ctx, tex, 2, 1, "notexture");
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_reset_queues (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto bctx = ctx->bsp_context;
|
||||
auto bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bframe->index_count = 0;
|
||||
bframe->entid_count = 0;
|
||||
|
||||
Vulkan_Scene_Flush (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||
{
|
||||
|
@ -1137,15 +1152,12 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
}
|
||||
|
||||
// params are in reverse order
|
||||
auto pass = *(int *) params[2]->value;
|
||||
auto pass_ind = *(int *) params[2]->value;
|
||||
auto queue = *(QFV_BspQueue *) params[1]->value;
|
||||
auto stage = *(int *) params[0]->value;
|
||||
|
||||
if (pass) {
|
||||
Sys_Error ("bsp passes not implemented");
|
||||
}
|
||||
auto mpass = &bctx->main_pass;
|
||||
if (!mpass->draw_queues[queue].size) {
|
||||
auto pass = pass_ind ? &bctx->aux_pass : &bctx->main_pass;
|
||||
if (!pass->draw_queues[queue].size) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1177,8 +1189,8 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd);
|
||||
}
|
||||
|
||||
mpass->textures = stage ? &bctx->registered_textures : 0;
|
||||
draw_queue (mpass, queue, layout, device, cmd);
|
||||
pass->textures = stage ? &bctx->registered_textures : 0;
|
||||
draw_queue (pass, queue, layout, device, cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1188,6 +1200,7 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
auto ctx = taskctx->ctx;
|
||||
auto bctx = ctx->bsp_context;
|
||||
auto pass_ind = *(int *) params[0]->value;
|
||||
|
||||
auto pass = pass_ind ? &bctx->aux_pass : &bctx->main_pass;
|
||||
|
||||
if (!pass_ind) {
|
||||
|
@ -1198,7 +1211,6 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
}
|
||||
|
||||
EntQueue_Clear (pass->entqueue);
|
||||
Vulkan_Scene_Flush (ctx);
|
||||
|
||||
clear_queues (bctx, pass); // do this first for water and skys
|
||||
|
||||
|
@ -1209,12 +1221,10 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
auto bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
pass->entid_data = bframe->entid_data;
|
||||
pass->entid_count = 0;
|
||||
pass->entid_count = bframe->entid_count;
|
||||
|
||||
bctx->anim_index = r_data->realtime * 5;
|
||||
|
||||
bframe->index_count = 0;
|
||||
|
||||
entity_t worldent = nullentity;
|
||||
|
||||
int world_id = Vulkan_Scene_AddEntity (ctx, worldent);
|
||||
|
@ -1236,9 +1246,10 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
}
|
||||
}
|
||||
}
|
||||
bframe->entid_count = bctx->main_pass.entid_count;
|
||||
|
||||
queue_faces (&bctx->main_pass, bctx, bframe);
|
||||
queue_faces (pass, bctx, bframe);
|
||||
|
||||
bframe->entid_count = pass->entid_count;
|
||||
|
||||
bsp_flush (ctx);
|
||||
}
|
||||
|
@ -1298,6 +1309,10 @@ static exprtype_t *bsp_draw_queue_params[] = {
|
|||
&bsp_stage_type,
|
||||
};
|
||||
|
||||
static exprfunc_t bsp_reset_queues_func[] = {
|
||||
{ .func = bsp_reset_queues },
|
||||
{}
|
||||
};
|
||||
static exprfunc_t bsp_visit_world_func[] = {
|
||||
{ 0, 1, bsp_visit_world_params, bsp_visit_world },
|
||||
{}
|
||||
|
@ -1307,6 +1322,7 @@ static exprfunc_t bsp_draw_queue_func[] = {
|
|||
{}
|
||||
};
|
||||
static exprsym_t bsp_task_syms[] = {
|
||||
{ "bsp_reset_queues", &cexpr_function, bsp_reset_queues_func },
|
||||
{ "bsp_visit_world", &cexpr_function, bsp_visit_world_func },
|
||||
{ "bsp_draw_queue", &cexpr_function, bsp_draw_queue_func },
|
||||
{}
|
||||
|
|
|
@ -179,10 +179,106 @@ lighting_setup_aux (const exprval_t **params, exprval_t *result,
|
|||
pass->vis_frame = visstate.visframecount;
|
||||
}
|
||||
|
||||
static VkImageView
|
||||
create_view (vulkan_ctx_t *ctx, light_renderer_t *renderer)
|
||||
{
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto lctx = ctx->lighting_context;
|
||||
|
||||
VkImageViewCreateInfo cInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.image = lctx->light_images.a[renderer->image_index],
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.format = VK_FORMAT_X8_D24_UNORM_PACK32,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = renderer->layer,
|
||||
.layerCount = renderer->numLayers,
|
||||
},
|
||||
};
|
||||
VkImageView view;
|
||||
dfunc->vkCreateImageView (device->dev, &cInfo, 0, &view);
|
||||
return view;
|
||||
}
|
||||
|
||||
static VkFramebuffer
|
||||
create_framebuffer (vulkan_ctx_t *ctx, light_renderer_t *renderer,
|
||||
VkImageView view, VkRenderPass renderpass)
|
||||
{
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
|
||||
VkFramebuffer framebuffer;
|
||||
dfunc->vkCreateFramebuffer (device->dev,
|
||||
&(VkFramebufferCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.renderPass = renderpass,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &view,
|
||||
.width = renderer->size,
|
||||
.height = renderer->size,
|
||||
.layers = 1,
|
||||
}, 0, &framebuffer);
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_frame_buffers_views (vulkan_ctx_t *ctx, lightingframe_t *lframe)
|
||||
{
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
for (size_t i = 0; i < lframe->framebuffers.size; i++) {
|
||||
auto framebuffer = lframe->framebuffers.a[i];
|
||||
dfunc->vkDestroyFramebuffer (device->dev, framebuffer, 0);
|
||||
}
|
||||
lframe->framebuffers.size = 0;
|
||||
for (size_t i = 0; i < lframe->views.size; i++) {
|
||||
auto view = lframe->views.a[i];
|
||||
dfunc->vkDestroyImageView (device->dev, view, 0);
|
||||
}
|
||||
lframe->views.size = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result,
|
||||
exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto lctx = ctx->lighting_context;
|
||||
auto shadow = QFV_GetStep (params[0], ctx->render_context->job);
|
||||
auto render = shadow->render;
|
||||
auto lframe = &lctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!lctx->ldata) {
|
||||
return;
|
||||
}
|
||||
//auto pass = Vulkan_Bsp_GetAuxPass (ctx);
|
||||
|
||||
clear_frame_buffers_views (ctx, lframe);
|
||||
|
||||
auto queue = r_ent_queue; //FIXME fetch from scene
|
||||
for (size_t i = 0; i < queue->ent_queues[mod_light].size; i++) {
|
||||
entity_t ent = queue->ent_queues[mod_light].a[i];
|
||||
auto ls = get_lightstyle (ent);
|
||||
if (!d_lightstylevalue[ls]) {
|
||||
continue;
|
||||
}
|
||||
uint32_t id = get_lightid (ent);
|
||||
auto r = &lctx->light_renderers.a[id];
|
||||
//auto l = get_light (ent);
|
||||
auto renderpass = &render->renderpasses[r->renderpass_index];
|
||||
auto view = create_view (ctx, r);
|
||||
auto bi = &renderpass->beginInfo;
|
||||
auto fbuffer = create_framebuffer (ctx, r, view, bi->renderPass);
|
||||
bi->framebuffer = fbuffer;
|
||||
QFV_RunRenderPass (ctx, renderpass, r->size, r->size);
|
||||
DARRAY_APPEND (&lframe->views, view);
|
||||
DARRAY_APPEND (&lframe->framebuffers, fbuffer);
|
||||
bi->framebuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -692,6 +788,9 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
lframe->shadowWrite.dstBinding = 0;
|
||||
lframe->shadowWrite.descriptorCount = LIGHTING_SHADOW_INFOS;
|
||||
lframe->shadowWrite.pImageInfo = lframe->shadowInfo;
|
||||
|
||||
lframe->views = (qfv_imageviewset_t) DARRAY_STATIC_INIT (16);
|
||||
lframe->framebuffers = (qfv_framebufferset_t) DARRAY_STATIC_INIT (16);
|
||||
}
|
||||
|
||||
auto packet = QFV_PacketAcquire (ctx->staging);
|
||||
|
@ -735,6 +834,13 @@ Vulkan_Lighting_Shutdown (vulkan_ctx_t *ctx)
|
|||
QFV_DestroyResource (device, lctx->light_resources);
|
||||
free (lctx->light_resources);
|
||||
|
||||
for (size_t i = 0; i < lctx->frames.size; i++) {
|
||||
auto lframe = &lctx->frames.a[i];
|
||||
clear_frame_buffers_views (ctx, lframe);
|
||||
DARRAY_CLEAR (&lframe->views);
|
||||
DARRAY_CLEAR (&lframe->framebuffers);
|
||||
}
|
||||
|
||||
DARRAY_CLEAR (&lctx->light_mats);
|
||||
DARRAY_CLEAR (&lctx->light_images);
|
||||
DARRAY_CLEAR (&lctx->light_renderers);
|
||||
|
@ -956,7 +1062,7 @@ build_shadow_maps (lightingctx_t *lctx, vulkan_ctx_t *ctx)
|
|||
for (int i = 0; i < numMaps; i++) {
|
||||
int cube = maps[i].layers < 6 ? 0 : maps[i].cube;
|
||||
shad->objects[i] = (qfv_resobj_t) {
|
||||
.name = "map",
|
||||
.name = va (ctx->va_ctx, "map:%d", maps[i].size),
|
||||
.type = qfv_res_image,
|
||||
.image = {
|
||||
.flags = cube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0,
|
||||
|
|
|
@ -84,6 +84,14 @@ Vulkan_Scene_AddEntity (vulkan_ctx_t *ctx, entity_t entity)
|
|||
render_id = sframe->entity_pool.size++;
|
||||
entdata = sframe->entity_pool.a + render_id;
|
||||
}
|
||||
} else {
|
||||
if (!Entity_Valid (entity)) {
|
||||
return 0; //FIXME see below
|
||||
} else {
|
||||
renderer_t *renderer = Ent_GetComponent (entity.id, scene_renderer,
|
||||
entity.reg);
|
||||
return renderer->render_id;
|
||||
}
|
||||
}
|
||||
if (Entity_Valid (entity)) {
|
||||
renderer_t *renderer = Ent_GetComponent (entity.id, scene_renderer,
|
||||
|
|
Loading…
Reference in a new issue