mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 18:01:30 +00:00
[vulkan] Get brush models rendering again
The new system seems to work quite nicely with brush models, which was the intent, but it's nice to see. Hopefully, it works well when it comes to shadows. There's still water warp and screen shots to fix, and fisheye to get working, as well.
This commit is contained in:
parent
65a63e7423
commit
eb176c37e2
3 changed files with 160 additions and 323 deletions
|
@ -316,13 +316,13 @@ typedef struct bsp_pass_s {
|
|||
/// \ingroup vulkan_bsp
|
||||
///@{
|
||||
typedef enum {
|
||||
QFV_bspDepth,
|
||||
QFV_bspGBuffer,
|
||||
QFV_bspSolid,
|
||||
QFV_bspSky,
|
||||
QFV_bspTurb,
|
||||
QFV_bspTrans, // texture translucency
|
||||
QFV_bspTurb, // also translucent via r_wateralpha
|
||||
|
||||
QFV_bspNumPasses
|
||||
} QFV_BspSubpass;
|
||||
} QFV_BspQueue;
|
||||
|
||||
typedef struct bspframe_s {
|
||||
uint32_t *index_data; // pointer into mega-buffer for this frame (c)
|
||||
|
@ -380,7 +380,6 @@ typedef struct bspctx_s {
|
|||
} bspctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
void Vulkan_Bsp_Flush (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_LoadSkys (const char *sky, struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_RegisterTextures (model_t **models, int num_models,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
|
|
|
@ -1449,6 +1449,15 @@ steps = {
|
|||
dependencies = (wait_on_fence);
|
||||
//currently empty
|
||||
};
|
||||
world = {
|
||||
dependencies = (wait_on_fence);
|
||||
process = {
|
||||
tasks = (
|
||||
{ func = bsp_visit_world;
|
||||
params = (main); },
|
||||
);
|
||||
};
|
||||
};
|
||||
translucent = {
|
||||
dependencies = (wait_on_fence);
|
||||
process = {
|
||||
|
@ -1468,7 +1477,7 @@ steps = {
|
|||
};
|
||||
};
|
||||
main = {
|
||||
dependencies = (setup_main, particles, shadow, translucent);
|
||||
dependencies = (setup_main, particles, shadow, world, translucent);
|
||||
render = {
|
||||
renderpasses = {
|
||||
deferred = $renderpasses.deferred;
|
||||
|
|
|
@ -33,12 +33,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "qfalloca.h"
|
||||
|
@ -578,7 +573,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
}
|
||||
|
||||
}
|
||||
#if 0
|
||||
|
||||
static int
|
||||
R_DrawBrushModel (entity_t ent, bsp_pass_t *pass, vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -607,7 +602,7 @@ R_DrawBrushModel (entity_t ent, bsp_pass_t *pass, vulkan_ctx_t *ctx)
|
|||
renderer->render_id);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
visit_leaf (mleaf_t *leaf)
|
||||
{
|
||||
|
@ -729,7 +724,7 @@ R_VisitWorldNodes (bsp_pass_t *pass, vulkan_ctx_t *ctx)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
|
||||
static void
|
||||
bind_texture (vulktex_t *tex, uint32_t setnum, VkPipelineLayout layout,
|
||||
qfv_devfuncs_t *dfunc, VkCommandBuffer cmd)
|
||||
|
@ -763,152 +758,6 @@ push_fragconst (bsp_push_constants_t *constants, VkPipelineLayout layout,
|
|||
QFV_PushConstants (device, cmd, layout, 4, push_constants);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline,
|
||||
VkPipelineLayout layout, qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = bframe->cmdSet.a[subpass];
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
rFrame->renderpass->renderpass, subpass_map[subpass],
|
||||
rFrame->framebuffer,
|
||||
0, 0, 0,
|
||||
};
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||
| VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inherit,
|
||||
};
|
||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
QFV_duCmdBeginLabel (device, cmd, va (ctx->va_ctx, "bsp:%s",
|
||||
bsp_pass_names[subpass]),
|
||||
{0, 0.5, 0.6, 1});
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline);
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
|
||||
VkBuffer buffers[] = { bctx->vertex_buffer, bctx->entid_buffer };
|
||||
VkDeviceSize offsets[] = { 0, bframe->entid_offset };
|
||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 2, buffers, offsets);
|
||||
dfunc->vkCmdBindIndexBuffer (cmd, bctx->index_buffer, bframe->index_offset,
|
||||
VK_INDEX_TYPE_UINT32);
|
||||
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
Vulkan_Scene_Descriptors (ctx),
|
||||
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, 3, sets, 0, 0);
|
||||
|
||||
//XXX glsl_Fog_GetColor (fog);
|
||||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
QFV_duCmdEndLabel (device, cmd);
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_begin (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
//XXX quat_t fog;
|
||||
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth],
|
||||
bframe->cmdSet.a[QFV_bspDepth]);
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
bsp_begin_subpass (QFV_bspDepth, bctx->depth, bctx->layout, rFrame);
|
||||
bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, bctx->layout, rFrame);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_end (vulkan_ctx_t *ctx)
|
||||
{
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspDepth], ctx);
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspGBuffer], ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
turb_begin (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFrag],
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
bsp_begin_subpass (QFV_bspTurb, bctx->turb, bctx->layout, rFrame);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
turb_end (vulkan_ctx_t *ctx)
|
||||
{
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspTurb], ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
sky_begin (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucentFrag],
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
if (bctx->skybox_tex) {
|
||||
bsp_begin_subpass (QFV_bspSky, bctx->skybox, bctx->layout, rFrame);
|
||||
} else {
|
||||
bsp_begin_subpass (QFV_bspSky, bctx->skysheet, bctx->layout, rFrame);
|
||||
}
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
sky_end (vulkan_ctx_t *ctx)
|
||||
{
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspSky], ctx);
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
|
||||
{
|
||||
|
@ -924,19 +773,19 @@ clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
|
|||
}
|
||||
pass->index_count = 0;
|
||||
}
|
||||
#if 0
|
||||
|
||||
static void
|
||||
queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
|
||||
{
|
||||
pass->indices = bframe->index_data + bframe->index_count;
|
||||
for (size_t i = 0; i < bctx->registered_textures.size; i++) {
|
||||
__auto_type queue = &pass->face_queue[i];
|
||||
auto queue = &pass->face_queue[i];
|
||||
if (!queue->size) {
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < queue->size; j++) {
|
||||
__auto_type is = queue->a[j];
|
||||
__auto_type f = bctx->faces[is.face];
|
||||
auto is = queue->a[j];
|
||||
auto f = bctx->faces[is.face];
|
||||
|
||||
f.flags |= ((is.inst_id & INST_ALPHA)
|
||||
>> (BITOP_LOG2(INST_ALPHA)
|
||||
|
@ -990,13 +839,13 @@ queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
|
|||
}
|
||||
|
||||
static void
|
||||
draw_queue (bsp_pass_t *pass, int queue, VkPipelineLayout layout,
|
||||
draw_queue (bsp_pass_t *pass, QFV_BspQueue queue, VkPipelineLayout layout,
|
||||
qfv_device_t *device, VkCommandBuffer cmd)
|
||||
{
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
for (size_t i = 0; i < pass->draw_queues[queue].size; i++) {
|
||||
__auto_type d = pass->draw_queues[queue].a[i];
|
||||
auto d = pass->draw_queues[queue].a[i];
|
||||
if (pass->textures) {
|
||||
vulktex_t *tex = pass->textures->a[d.tex_id];
|
||||
bind_texture (tex, TEX_SET, layout, dfunc, cmd);
|
||||
|
@ -1016,77 +865,8 @@ ent_model_cmp (const void *_a, const void *_b)
|
|||
return ra->model->render_id - rb->model->render_id;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DrawWorld (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
//qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bctx->main_pass.bsp_context = bctx;
|
||||
bctx->main_pass.position = r_refdef.frame.position;
|
||||
bctx->main_pass.vis_frame = r_visframecount;
|
||||
bctx->main_pass.face_frames = r_face_visframes;
|
||||
bctx->main_pass.leaf_frames = r_leaf_visframes;
|
||||
bctx->main_pass.node_frames = r_node_visframes;
|
||||
bctx->main_pass.entid_data = bframe->entid_data;
|
||||
bctx->main_pass.entid_count = 0;
|
||||
|
||||
bctx->anim_index = r_data->realtime * 5;
|
||||
|
||||
clear_queues (bctx, &bctx->main_pass); // do this first for water and skys
|
||||
bframe->index_count = 0;
|
||||
|
||||
entity_t worldent = nullentity;
|
||||
|
||||
int world_id = Vulkan_Scene_AddEntity (ctx, worldent);
|
||||
|
||||
bctx->main_pass.ent_frame = 0; // world is always frame 0
|
||||
bctx->main_pass.inst_id = world_id;
|
||||
bctx->main_pass.brush = &r_refdef.worldmodel->brush;
|
||||
if (bctx->main_pass.instances) {
|
||||
DARRAY_APPEND (&bctx->main_pass.instances[world_id].entities, world_id);
|
||||
}
|
||||
R_VisitWorldNodes (&bctx->main_pass, ctx);
|
||||
if (!bctx->vertex_buffer) {
|
||||
return;
|
||||
}
|
||||
if (r_drawentities) {
|
||||
heapsort (r_ent_queue->ent_queues[mod_brush].a,
|
||||
r_ent_queue->ent_queues[mod_brush].size,
|
||||
sizeof (entity_t), ent_model_cmp);
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
if (!R_DrawBrushModel (ent, &bctx->main_pass, ctx)) {
|
||||
Sys_Printf ("Too many entities!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bframe->entid_count = bctx->main_pass.entid_count;
|
||||
|
||||
queue_faces (&bctx->main_pass, bctx, bframe);
|
||||
|
||||
bsp_begin (rFrame);
|
||||
|
||||
bsp_push_constants_t frag_constants = { .time = vr_data.realtime };
|
||||
push_fragconst (&frag_constants, bctx->layout, device,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
VkPipelineLayout layout = bctx->layout;
|
||||
|
||||
__auto_type pass = &bctx->main_pass;
|
||||
pass->textures = 0;
|
||||
draw_queue (pass, 0, layout, device, bframe->cmdSet.a[QFV_bspDepth]);
|
||||
draw_queue (pass, 1, layout, device, bframe->cmdSet.a[QFV_bspDepth]);
|
||||
pass->textures = &bctx->registered_textures;
|
||||
draw_queue (pass, 0, layout, device, bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
bsp_end (ctx);
|
||||
}
|
||||
#endif
|
||||
void
|
||||
Vulkan_Bsp_Flush (vulkan_ctx_t *ctx)
|
||||
static void
|
||||
bsp_flush (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
@ -1117,71 +897,7 @@ Vulkan_Bsp_Flush (vulkan_ctx_t *ctx)
|
|||
};
|
||||
dfunc->vkFlushMappedMemoryRanges (device->dev, 2, ranges);
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
Vulkan_DrawWaterSurfaces (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
//qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!bctx->main_pass.draw_queues[3].size)
|
||||
return;
|
||||
|
||||
turb_begin (rFrame);
|
||||
|
||||
VkPipelineLayout layout = bctx->layout;
|
||||
bsp_push_constants_t frag_constants = {
|
||||
.time = vr_data.realtime,
|
||||
.alpha = 1,
|
||||
.turb_scale = 0,
|
||||
};
|
||||
push_fragconst (&frag_constants, layout, device,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
||||
__auto_type pass = &bctx->main_pass;
|
||||
pass->textures = &bctx->registered_textures;
|
||||
draw_queue (pass, 2, layout, device, bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
||||
frag_constants.alpha = r_wateralpha;
|
||||
frag_constants.turb_scale = 1;
|
||||
push_fragconst (&frag_constants, bctx->layout, device,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
draw_queue (pass, 3, layout, device, bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
||||
turb_end (ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DrawSky (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
if (!bctx->main_pass.draw_queues[1].size)
|
||||
return;
|
||||
|
||||
sky_begin (rFrame);
|
||||
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
|
||||
bind_texture (&skybox, SKYBOX_SET, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
bsp_push_constants_t frag_constants = { .time = vr_data.realtime };
|
||||
push_fragconst (&frag_constants, bctx->layout, device,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
||||
VkPipelineLayout layout = bctx->layout;
|
||||
__auto_type pass = &bctx->main_pass;
|
||||
pass->textures = &bctx->registered_textures;
|
||||
draw_queue (pass, 1, layout, device, bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
||||
sky_end (ctx);
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
create_default_skys (vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -1359,27 +1075,126 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
|||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto bctx = ctx->bsp_context;
|
||||
int pass = *(int *) params[2]->value;
|
||||
if (!pass && r_refdef.worldmodel) {
|
||||
bctx->main_pass.bsp_context = bctx;
|
||||
bctx->main_pass.position = r_refdef.frame.position;
|
||||
bctx->main_pass.vis_frame = r_visframecount;
|
||||
bctx->main_pass.face_frames = r_face_visframes;
|
||||
bctx->main_pass.leaf_frames = r_leaf_visframes;
|
||||
bctx->main_pass.node_frames = r_node_visframes;
|
||||
//bctx->main_pass.entid_data = bframe->entid_data;
|
||||
//bctx->main_pass.entid_count = 0;
|
||||
auto layout = taskctx->pipeline->layout;
|
||||
auto cmd = taskctx->cmd;
|
||||
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
clear_queues (bctx, &bctx->main_pass); // do this first for water and skys
|
||||
entity_t worldent = nullentity;
|
||||
int world_id = Vulkan_Scene_AddEntity (ctx, worldent);
|
||||
bctx->main_pass.ent_frame = 0; // world is always frame 0
|
||||
bctx->main_pass.inst_id = world_id;
|
||||
bctx->main_pass.brush = &r_refdef.worldmodel->brush;
|
||||
R_VisitWorldNodes (&bctx->main_pass, ctx);
|
||||
if (!bctx->vertex_buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// params are in reverse order
|
||||
auto stage = *(int *) params[2]->value;
|
||||
auto queue = *(QFV_BspQueue *) params[1]->value;
|
||||
auto pass = *(int *) params[0]->value;
|
||||
|
||||
if (stage) {
|
||||
Sys_Error ("bps stages not implemented");
|
||||
}
|
||||
auto mpass = &bctx->main_pass;
|
||||
if (!mpass->draw_queues[queue].size) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto bframe = &bctx->frames.a[ctx->curFrame];
|
||||
VkBuffer buffers[] = { bctx->vertex_buffer, bctx->entid_buffer };
|
||||
VkDeviceSize offsets[] = { 0, bframe->entid_offset };
|
||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 2, buffers, offsets);
|
||||
dfunc->vkCmdBindIndexBuffer (cmd, bctx->index_buffer, bframe->index_offset,
|
||||
VK_INDEX_TYPE_UINT32);
|
||||
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
Vulkan_Scene_Descriptors (ctx),
|
||||
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, 3, sets, 0, 0);
|
||||
|
||||
//XXX glsl_Fog_GetColor (fog);
|
||||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||
bsp_push_constants_t frag_constants = {
|
||||
.time = vr_data.realtime,
|
||||
.alpha = queue == QFV_bspTurb ? r_wateralpha : 1,
|
||||
.turb_scale = queue == QFV_bspTurb ? 1 : 0,
|
||||
};
|
||||
push_fragconst (&frag_constants, layout, device, cmd);
|
||||
if (queue == QFV_bspSky) {
|
||||
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
|
||||
bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd);
|
||||
}
|
||||
|
||||
mpass->textures = pass ? &bctx->registered_textures : 0;
|
||||
draw_queue (mpass, queue, layout, device, cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto stage = *(int *) params[0]->value;
|
||||
|
||||
if (stage) {
|
||||
Sys_Error ("bps stages not implemented");
|
||||
}
|
||||
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
Vulkan_Scene_Flush (ctx);
|
||||
|
||||
auto bctx = ctx->bsp_context;
|
||||
clear_queues (bctx, &bctx->main_pass); // do this first for water and skys
|
||||
|
||||
if (!r_refdef.worldmodel) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bctx->main_pass.bsp_context = bctx;
|
||||
bctx->main_pass.position = r_refdef.frame.position;
|
||||
bctx->main_pass.vis_frame = r_visframecount;
|
||||
bctx->main_pass.face_frames = r_face_visframes;
|
||||
bctx->main_pass.leaf_frames = r_leaf_visframes;
|
||||
bctx->main_pass.node_frames = r_node_visframes;
|
||||
bctx->main_pass.entid_data = bframe->entid_data;
|
||||
bctx->main_pass.entid_count = 0;
|
||||
|
||||
bctx->anim_index = r_data->realtime * 5;
|
||||
|
||||
bframe->index_count = 0;
|
||||
|
||||
entity_t worldent = nullentity;
|
||||
|
||||
int world_id = Vulkan_Scene_AddEntity (ctx, worldent);
|
||||
|
||||
bctx->main_pass.ent_frame = 0; // world is always frame 0
|
||||
bctx->main_pass.inst_id = world_id;
|
||||
bctx->main_pass.brush = &r_refdef.worldmodel->brush;
|
||||
if (bctx->main_pass.instances) {
|
||||
DARRAY_APPEND (&bctx->main_pass.instances[world_id].entities, world_id);
|
||||
}
|
||||
R_VisitWorldNodes (&bctx->main_pass, ctx);
|
||||
|
||||
if (r_drawentities) {
|
||||
heapsort (r_ent_queue->ent_queues[mod_brush].a,
|
||||
r_ent_queue->ent_queues[mod_brush].size,
|
||||
sizeof (entity_t), ent_model_cmp);
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
if (!R_DrawBrushModel (ent, &bctx->main_pass, ctx)) {
|
||||
Sys_Printf ("Too many entities!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bframe->entid_count = bctx->main_pass.entid_count;
|
||||
|
||||
queue_faces (&bctx->main_pass, bctx, bframe);
|
||||
|
||||
bsp_flush (ctx);
|
||||
}
|
||||
|
||||
static exprenum_t bsp_stage_enum;
|
||||
|
@ -1407,7 +1222,12 @@ static exprtype_t bsp_queue_type = {
|
|||
.get_string = cexpr_enum_get_string,
|
||||
.data = &bsp_queue_enum,
|
||||
};
|
||||
static int bsp_queue_values[] = { 0, 1, 2, 3, };
|
||||
static int bsp_queue_values[] = {
|
||||
QFV_bspSolid,
|
||||
QFV_bspSky,
|
||||
QFV_bspTrans,
|
||||
QFV_bspTurb,
|
||||
};
|
||||
static exprsym_t bsp_queue_symbols[] = {
|
||||
{"solid", &bsp_queue_type, bsp_queue_values + 0},
|
||||
{"sky", &bsp_queue_type, bsp_queue_values + 1},
|
||||
|
@ -1421,17 +1241,26 @@ static exprenum_t bsp_queue_enum = {
|
|||
&bsp_queue_symtab,
|
||||
};
|
||||
|
||||
static exprtype_t *bsp_visit_world_params[] = {
|
||||
&bsp_stage_type,
|
||||
};
|
||||
|
||||
static exprtype_t *bsp_draw_queue_params[] = {
|
||||
&cexpr_int,
|
||||
&bsp_queue_type,
|
||||
&bsp_stage_type,
|
||||
};
|
||||
|
||||
static exprfunc_t bsp_visit_world_func[] = {
|
||||
{ 0, 1, bsp_visit_world_params, bsp_visit_world },
|
||||
{}
|
||||
};
|
||||
static exprfunc_t bsp_draw_queue_func[] = {
|
||||
{ 0, 3, bsp_draw_queue_params, bsp_draw_queue },
|
||||
{}
|
||||
};
|
||||
static exprsym_t bsp_task_syms[] = {
|
||||
{ "bsp_visit_world", &cexpr_function, bsp_visit_world_func },
|
||||
{ "bsp_draw_queue", &cexpr_function, bsp_draw_queue_func },
|
||||
{}
|
||||
};
|
||||
|
@ -1505,7 +1334,7 @@ Vulkan_Bsp_Setup (vulkan_ctx_t *ctx)
|
|||
frames * entid_size, 0, (void **) &entid_data);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type bframe = &bctx->frames.a[i];
|
||||
auto bframe = &bctx->frames.a[i];
|
||||
|
||||
DARRAY_INIT (&bframe->cmdSet, QFV_bspNumPasses);
|
||||
DARRAY_RESIZE (&bframe->cmdSet, QFV_bspNumPasses);
|
||||
|
@ -1543,7 +1372,7 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx)
|
|||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
for (size_t i = 0; i < bctx->frames.size; i++) {
|
||||
__auto_type bframe = &bctx->frames.a[i];
|
||||
auto bframe = &bctx->frames.a[i];
|
||||
free (bframe->cmdSet.a);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue