[vulkan] Get alias model rendering mostly working

Mostly because no lighting or compositing to the output buffer is done,
but the model is there in renderdoc's image viewer.
This commit is contained in:
Bill Currie 2023-06-22 20:27:55 +09:00
parent 854b612597
commit d2e85f775d
9 changed files with 108 additions and 202 deletions

View file

@ -106,13 +106,7 @@ void Vulkan_Mod_MakeAliasModelDisplayLists (struct mod_alias_ctx_s *alias_ctx,
void Vulkan_AliasAddSkin (struct vulkan_ctx_s *ctx, qfv_alias_skin_t *skin);
void Vulkan_AliasRemoveSkin (struct vulkan_ctx_s *ctx, qfv_alias_skin_t *skin);
void Vulkan_AliasBegin (struct qfv_orenderframe_s *rFrame);
void Vulkan_DrawAlias (struct entity_s ent, struct qfv_orenderframe_s *rFrame);
void Vulkan_AliasEnd (struct qfv_orenderframe_s *rFrame);
void Vulkan_Alias_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_AliasDepthRange (struct qfv_orenderframe_s *rFrame, float n, float f);
#endif//__QF_Vulkan_qf_alias_h

View file

@ -127,7 +127,9 @@ static void
vulkan_R_ClearState (void)
{
QFV_DeviceWaitIdle (vulkan_ctx->device);
//FIXME clear scene correctly
r_refdef.worldmodel = 0;
EntQueue_Clear (r_ent_queue);
R_ClearDlights ();
R_ClearParticles ();
Vulkan_LoadLights (0, vulkan_ctx);

View file

@ -280,7 +280,7 @@ properties = {
bindings = (
{ binding = 0; stride = "2 * 4 * 4"; inputRate = vertex; },
{ binding = 1; stride = "2 * 4 * 4"; inputRate = vertex; },
{ binding = 2; stride = "2 * 4"; inputRate = instance; },
{ binding = 2; stride = "2 * 4"; inputRate = vertex; },
);
attributes = (
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
@ -983,9 +983,9 @@ renderpasses = {
color = $color.bsp;
tasks = (
{ func = bsp_draw_queue;
params = (main, solid); },
params = (main, solid, 0); },
{ func = bsp_draw_queue;
params = (main, sky); },
params = (main, sky, 0); },
);
stages = (
@ -1007,7 +1007,8 @@ renderpasses = {
alias:depth = {
color = $color.alias;
tasks = (
{ func = alias_draw; },
{ func = alias_draw;
params = (0); },
);
stages = (
@ -1076,7 +1077,7 @@ renderpasses = {
tasks = (
// FIXME sky should not use OIT
{ func = bsp_draw_queue;
params = (main, sky); },
params = (main, sky, 1); },
);
stages = (
@ -1092,7 +1093,7 @@ renderpasses = {
tasks = (
// FIXME sky should not use OIT
{ func = bsp_draw_queue;
params = (main, sky); },
params = (main, sky, 1); },
);
stages = (
@ -1107,9 +1108,9 @@ renderpasses = {
color = $color.bsp;
tasks = (
{ func = bsp_draw_queue;
params = (main, translucent); },
params = (main, translucent, 2); },
{ func = bsp_draw_queue;
params = (main, turbulent); },
params = (main, turbulent, 2); },
);
stages = (
@ -1172,9 +1173,9 @@ renderpasses = {
color = $color.bsp;
tasks = (
{ func = bsp_draw_queue;
params = (main, solid); },
params = (main, solid, 1); },
{ func = bsp_draw_queue;
params = (main, sky); },
params = (main, sky, 1); },
);
stages = (
@ -1189,7 +1190,8 @@ renderpasses = {
alias:gbuffer = {
color = $color.alias;
tasks = (
{ func = alias_draw; },
{ func = alias_draw;
params = (1); },
);
stages = (
@ -1385,7 +1387,6 @@ steps = {
);
};
};
/*
particles = {
dependencies = (wait_on_fence);
compute = {
@ -1444,7 +1445,6 @@ steps = {
};
};
};
*/
preoutput = {
dependencies = (wait_on_fence);
process = {

View file

@ -43,7 +43,6 @@
#include "QF/Vulkan/qf_alias.h"
#include "QF/Vulkan/qf_matrices.h"
#include "QF/Vulkan/qf_palette.h"
#include "QF/Vulkan/qf_renderpass.h"
#include "QF/Vulkan/qf_texture.h"
#include "QF/Vulkan/debug.h"
#include "QF/Vulkan/device.h"
@ -61,25 +60,12 @@ typedef struct {
vec4f_t fog;
} alias_push_constants_t;
static const char * __attribute__((used)) alias_pass_names[] = {
"depth",
"g-buffer",
"translucent",
};
static QFV_Subpass subpass_map[] = {
QFV_passDepth, // QFV_aliasDepth
QFV_passGBuffer, // QFV_aliasGBuffer
QFV_passTranslucentFrag,// QFV_aliasTranslucent
};
static void
emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
qfv_alias_skin_t *skin,
uint32_t numPC, qfv_push_constants_t *constants,
aliashdr_t *hdr, qfv_orenderframe_t *rFrame, entity_t ent)
aliashdr_t *hdr, vulkan_ctx_t *ctx, entity_t ent)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
@ -116,14 +102,41 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
QFV_CmdEndLabel (device, cmd);
}
void
Vulkan_DrawAlias (entity_t ent, qfv_orenderframe_t *rFrame)
static void
alias_depth_range (qfv_taskctx_t *taskctx, float minDepth, float maxDepth)
{
auto ctx = taskctx->ctx;
auto device = ctx->device;
auto dfunc = device->funcs;
auto viewport = taskctx->pipeline->viewport;
viewport.minDepth = minDepth;
viewport.maxDepth = maxDepth;
dfunc->vkCmdSetViewport (taskctx->cmd, 0, 1, &viewport);
}
void
Vulkan_AliasAddSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
skin->descriptor = Vulkan_CreateCombinedImageSampler (ctx, skin->view,
actx->sampler);
}
void
Vulkan_AliasRemoveSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
{
Vulkan_FreeTexture (ctx, skin->descriptor);
skin->descriptor = 0;
}
static void
alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
{
auto ctx = taskctx->ctx;
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg);
model_t *model = renderer->model;
auto model = renderer->model;
aliashdr_t *hdr;
qfv_alias_skin_t *skin;
alias_push_constants_t constants = {};
@ -171,138 +184,52 @@ Vulkan_DrawAlias (entity_t ent, qfv_orenderframe_t *rFrame)
}
QuatZero (constants.fog);
emit_commands (aframe->cmdSet.a[QFV_aliasDepth],
animation->pose1, animation->pose2,
0, 2, push_constants, hdr, rFrame, ent);
emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer],
animation->pose1, animation->pose2,
skin, 5, push_constants, hdr, rFrame, ent);
emit_commands (taskctx->cmd, animation->pose1, animation->pose2,
pass ? skin : 0,
pass ? 5 : 2, push_constants,
hdr, ctx, ent);
}
static void
alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline,
qfv_orenderframe_t *rFrame)
alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
uint32_t curFrame = ctx->curFrame;
aliasframe_t *aframe = &actx->frames.a[curFrame];
VkCommandBuffer cmd = aframe->cmdSet.a[subpass];
auto taskctx = (qfv_taskctx_t *) ectx;
bool vmod = Entity_Valid (vr_data.view_model);
int pass = *(int *) params[0]->value;
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, "alias:%s",
alias_pass_names[subpass]),
{ 0.6, 0.5, 0, 1});
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
auto ctx = taskctx->ctx;
auto device = ctx->device;
auto dfunc = device->funcs;
auto actx = ctx->alias_context;
auto cmd = taskctx->cmd;
VkDescriptorSet sets[] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Palette_Descriptor (ctx),
};
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
actx->layout, 0, 2, sets, 0, 0);
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
//XXX glsl_Fog_GetColor (fog);
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
}
static void
alias_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);
}
void
Vulkan_AliasBegin (qfv_orenderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
//XXX quat_t fog;
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth],
aframe->cmdSet.a[QFV_aliasDepth]);
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
aframe->cmdSet.a[QFV_aliasGBuffer]);
alias_begin_subpass (QFV_aliasDepth, actx->depth, rFrame);
alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, rFrame);
}
void
Vulkan_AliasEnd (qfv_orenderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
alias_end_subpass (aframe->cmdSet.a[QFV_aliasDepth], ctx);
alias_end_subpass (aframe->cmdSet.a[QFV_aliasGBuffer], ctx);
}
void
Vulkan_AliasDepthRange (qfv_orenderframe_t *rFrame,
float minDepth, float maxDepth)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
VkViewport viewport = rFrame->renderpass->viewport;
viewport.minDepth = minDepth;
viewport.maxDepth = maxDepth;
dfunc->vkCmdSetViewport (aframe->cmdSet.a[QFV_aliasDepth], 0, 1,
&viewport);
dfunc->vkCmdSetViewport (aframe->cmdSet.a[QFV_aliasGBuffer], 0, 1,
&viewport);
}
void
Vulkan_AliasAddSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
{
aliasctx_t *actx = ctx->alias_context;
skin->descriptor = Vulkan_CreateCombinedImageSampler (ctx, skin->view,
actx->sampler);
}
void
Vulkan_AliasRemoveSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
{
Vulkan_FreeTexture (ctx, skin->descriptor);
skin->descriptor = 0;
}
static void
alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
{
auto queue = r_ent_queue; //FIXME fetch from scene
for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) {
entity_t ent = queue->ent_queues[mod_alias].a[i];
// FIXME hack the depth range to prevent view model
// from poking into walls
if (vmod && ent.id == vr_data.view_model.id) {
alias_depth_range (taskctx, 0, 0.3);
}
alias_draw_ent (taskctx, ent, pass);
// unhack in case the view_model is not the last
if (vmod && ent.id == vr_data.view_model.id) {
alias_depth_range (taskctx, 0, 1);
}
}
}
static exprtype_t *alias_draw_params[] = {
&cexpr_int,
};
static exprfunc_t alias_draw_func[] = {
{ .func = alias_draw },
{ .func = alias_draw, .num_params = 1, .param_types = alias_draw_params },
{}
};
static exprsym_t alias_task_syms[] = {
@ -313,8 +240,6 @@ static exprsym_t alias_task_syms[] = {
void
Vulkan_Alias_Init (vulkan_ctx_t *ctx)
{
qfv_device_t *device = ctx->device;
qfvPushDebug (ctx, "alias init");
QFV_Render_AddTasks (ctx, alias_task_syms);
@ -331,23 +256,6 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx)
actx->gbuf = Vulkan_CreateGraphicsPipeline (ctx, "alias_gbuf");
actx->layout = Vulkan_CreatePipelineLayout (ctx, "alias_layout");
actx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler");
for (size_t i = 0; i < frames; i++) {
__auto_type aframe = &actx->frames.a[i];
DARRAY_INIT (&aframe->cmdSet, QFV_aliasNumPasses);
DARRAY_RESIZE (&aframe->cmdSet, QFV_aliasNumPasses);
aframe->cmdSet.grow = 0;
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &aframe->cmdSet);
for (int j = 0; j < QFV_aliasNumPasses; j++) {
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
aframe->cmdSet.a[j],
va (ctx->va_ctx, "cmd:alias:%zd:%s", i,
alias_pass_names[j]));
}
}
qfvPopDebug (ctx);
}
@ -358,11 +266,6 @@ Vulkan_Alias_Shutdown (vulkan_ctx_t *ctx)
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
for (size_t i = 0; i < actx->frames.size; i++) {
__auto_type aframe = &actx->frames.a[i];
free (aframe->cmdSet.a);
}
dfunc->vkDestroyPipeline (device->dev, actx->depth, 0);
dfunc->vkDestroyPipeline (device->dev, actx->gbuf, 0);
free (actx->frames.a);

View file

@ -1365,6 +1365,28 @@ create_notexture (vulkan_ctx_t *ctx)
static void
bsp_draw_queue (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;
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;
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);
}
}
static exprenum_t bsp_stage_enum;
@ -1407,12 +1429,13 @@ static exprenum_t bsp_queue_enum = {
};
static exprtype_t *bsp_draw_queue_params[] = {
&cexpr_int,
&bsp_queue_type,
&bsp_stage_type,
};
static exprfunc_t bsp_draw_queue_func[] = {
{ 0, 2, bsp_draw_queue_params, bsp_draw_queue },
{ 0, 3, bsp_draw_queue_params, bsp_draw_queue },
{}
};
static exprsym_t bsp_task_syms[] = {

View file

@ -74,7 +74,6 @@ Vulkan_RenderEntities (entqueue_t *queue, qfv_orenderframe_t *rFrame)
if (!r_drawentities)
return;
//FIXME need a better way (components? but HasComponent isn't free)
int vmod = Entity_Valid (vr_data.view_model);
#define RE_LOOP(type_name, Type) \
do { \
int begun = 0; \
@ -85,22 +84,12 @@ Vulkan_RenderEntities (entqueue_t *queue, qfv_orenderframe_t *rFrame)
Vulkan_##Type##Begin (rFrame); \
begun = 1; \
} \
/* FIXME hack the depth range to prevent view model */\
/* from poking into walls */\
if (vmod && ent.id == vr_data.view_model.id) { \
Vulkan_AliasDepthRange (rFrame, 0, 0.3); \
} \
Vulkan_Draw##Type (ent, rFrame); \
/* unhack in case the view_model is not the last */\
if (vmod && ent.id == vr_data.view_model.id) { \
Vulkan_AliasDepthRange (rFrame, 0, 1); \
} \
} \
if (begun) \
Vulkan_##Type##End (rFrame); \
} while (0)
RE_LOOP (alias, Alias);
RE_LOOP (iqm, IQM);
RE_LOOP (sprite, Sprite);
}
@ -153,6 +142,7 @@ Vulkan_NewScene (scene_t *scene, vulkan_ctx_t *ctx)
}
r_refdef.worldmodel = scene->worldmodel;
EntQueue_Clear (r_ent_queue);
// Force a vis update
R_MarkLeaves (0, 0, 0, 0);

View file

@ -294,11 +294,11 @@ static exprtype_t *stepref_param[] = {
&cexpr_string,
};
static exprfunc_t acquire_output_func[] = {
{ .func = acquire_output, .num_params = 1, stepref_param },
{ .func = acquire_output, .num_params = 1, .param_types = stepref_param },
{}
};
static exprfunc_t update_input_func[] = {
{ .func = update_input, .num_params = 1, stepref_param },
{ .func = update_input, .num_params = 1, .param_types = stepref_param },
{}
};
static exprfunc_t output_draw_func[] = {

View file

@ -277,7 +277,6 @@ create_buffers (vulkan_ctx_t *ctx)
static void
particles_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
{
puts ("particles_draw");
}
static void

View file

@ -76,14 +76,9 @@ clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
VkCommandBuffer cmd = QFV_GetCmdBuffer (ctx, false);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
0, 0, 0,
0, 0, 0,
};
VkCommandBufferBeginInfo beginInfo = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &inherit,
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);