From ff27da4a0508d8916521257f1895a9c3967b18a3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 30 Jul 2023 11:52:13 +0900 Subject: [PATCH] [vulkan] Use the shadow matrices when rendering maps It turns out bsp faces are still back-face culled despite the null point being on the front of every possible plane... or really, because it's on the front of every possible plane: sometimes the back face is the front face, and this breaks the face selection code (a separate traversal function will be needed for non-culling rendering). Despite that, other than having to deal with different pipelines, getting the model renderers working went better than expected. --- include/QF/Vulkan/qf_lighting.h | 2 + libs/video/renderer/vulkan/rp_main_def.plist | 62 ++++-- .../renderer/vulkan/shader/alias_shadow.vert | 16 +- .../renderer/vulkan/shader/bsp_shadow.vert | 14 +- libs/video/renderer/vulkan/shader/iqm.frag | 4 +- libs/video/renderer/vulkan/shader/iqm.vert | 14 +- libs/video/renderer/vulkan/vulkan_alias.c | 186 +++++++++++------- libs/video/renderer/vulkan/vulkan_bsp.c | 77 +++++--- libs/video/renderer/vulkan/vulkan_iqm.c | 29 +-- libs/video/renderer/vulkan/vulkan_lighting.c | 14 +- 10 files changed, 280 insertions(+), 138 deletions(-) diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index 2b739e272..5bb448de2 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -123,5 +123,7 @@ void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx); void Vulkan_Lighting_Setup (struct vulkan_ctx_s *ctx); void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx); +VkDescriptorSet Vulkan_Lighting_Descriptors (struct vulkan_ctx_s *ctx, + int frame) __attribute__((pure)); #endif//__QF_Vulkan_qf_lighting_h diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index ce331249c..ec5aae302 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -232,6 +232,11 @@ properties = { brush = { shader = { + shadow_vertex = { + stage = vertex; + name = main; + module = $builtin/bsp_shadow.vert; + }; depth_vertex = { stage = vertex; name = main; @@ -324,9 +329,22 @@ properties = { }; }; }; + shadow_layout = { + descriptorSets = (shadowmat_set, entity_set); + pushConstants = { + vertex = { + MatrixBase = uint; + }; + }; + }; }; alias = { shader = { + shadow_vertex = { + stage = vertex; + name = main; + module = $builtin/alias_shadow.vert; + }; depth_vertex = { stage = vertex; name = main; @@ -369,6 +387,12 @@ properties = { fragment = { colors = uint; base_color = vec4; fog = vec4; }; }; }; + shadow_layout = { + descriptorSets = (shadowmat_set); + pushConstants = { + vertex = { Model = mat4; blend = float; MatrixBase = uint; }; + }; + }; }; iqm = { shader = { @@ -376,16 +400,27 @@ properties = { mapEntries = ( // IQMDepthOnly { size = 4; offset = 0; constantID = 0; }, + { size = 4; offset = 4; constantID = 1; }, ); }; + shadow_vertex = { + stage = vertex; + name = main; + module = $builtin/iqm.vert; + specializationInfo = { + @inherit = $iqm.shader.specialization; + // IQMDepthOnly, IQMShadow + data = "array(1, 1)"; + }; + }; depth_vertex = { stage = vertex; name = main; module = $builtin/iqm.vert; specializationInfo = { @inherit = $iqm.shader.specialization; - // IQMDepthOnly - data = "array(1)"; + // IQMDepthOnly, IQMShadow + data = "array(1, 0)"; }; }; gbuf_vertex = { @@ -394,8 +429,8 @@ properties = { module = $builtin/iqm.vert; specializationInfo = { @inherit = $iqm.shader.specialization; - // IQMDepthOnly - data = "array(0)"; + // IQMDepthOnly, IQMShadow + data = "array(0, 0)"; }; }; gbuf_fragment = { @@ -426,13 +461,10 @@ properties = { primitiveRestartEnable = false; }; layout = { - // skin - descriptorSets = (matrix_set, texture_set, bone_set); + // skin + descriptorSets = (matrix_set, shadowmat_set, texture_set, bone_set); pushConstants = { - vertex = { - Model = mat4; - blend = float; - }; + vertex = { Model = mat4; blend = float; MatrixBase = uint; }; fragment = { colorA = uint; colorB = uint; @@ -1811,7 +1843,7 @@ renderpasses = { ); stages = ( - $brush.shader.depth_vertex, + $brush.shader.shadow_vertex, ); vertexInput = { bindings = ( @@ -1824,7 +1856,7 @@ renderpasses = { ); }; inputAssembly = $brush.inputAssembly; - layout = $brush.layout; + layout = $brush.shadow_layout; }; alias:shadow = { color = $color.alias; @@ -1834,7 +1866,7 @@ renderpasses = { ); stages = ( - $alias.shader.depth_vertex, + $alias.shader.shadow_vertex, ); vertexInput = { // depth/shadow pass doesn't use UVs @@ -1850,7 +1882,7 @@ renderpasses = { ); }; inputAssembly = $alias.inputAssembly; - layout = $alias.layout; + layout = $alias.shadow_layout; }; iqm:shadow = { color = $color.iqm; @@ -1860,7 +1892,7 @@ renderpasses = { ); stages = ( - $iqm.shader.depth_vertex, + $iqm.shader.shadow_vertex, ); vertexInput = $iqm.vertexInput; inputAssembly = $iqm.inputAssembly; diff --git a/libs/video/renderer/vulkan/shader/alias_shadow.vert b/libs/video/renderer/vulkan/shader/alias_shadow.vert index d99c1b445..fcd6ff890 100644 --- a/libs/video/renderer/vulkan/shader/alias_shadow.vert +++ b/libs/video/renderer/vulkan/shader/alias_shadow.vert @@ -1,8 +1,15 @@ #version 450 +#extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_multiview : enable + +layout (set = 0, binding = 0) buffer ShadowView { + mat4x4 shadowView[]; +}; layout (push_constant) uniform PushConstants { mat4 Model; float blend; + uint MatrixBase; }; layout (location = 0) in vec4 vertexa; @@ -10,14 +17,9 @@ layout (location = 1) in vec3 normala; layout (location = 2) in vec4 vertexb; layout (location = 3) in vec3 normalb; -layout (location = 0) out int InstanceIndex; - void main (void) { - vec4 vertex; - - vertex = mix (vertexa, vertexb, blend); - gl_Position = Model * vertex; - InstanceIndex = gl_InstanceIndex; + vec4 pos = mix (vertexa, vertexb, blend); + gl_Position = shadowView[MatrixBase + gl_ViewIndex] * (Model * pos); } diff --git a/libs/video/renderer/vulkan/shader/bsp_shadow.vert b/libs/video/renderer/vulkan/shader/bsp_shadow.vert index ea1dfb8d6..1ff1d929c 100644 --- a/libs/video/renderer/vulkan/shader/bsp_shadow.vert +++ b/libs/video/renderer/vulkan/shader/bsp_shadow.vert @@ -1,5 +1,14 @@ #version 450 #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_multiview : enable + +layout (set = 0, binding = 0) buffer ShadowView { + mat4x4 shadowView[]; +}; + +layout (push_constant) uniform PushConstants { + uint MatrixBase; +}; #include "entity.h" @@ -15,7 +24,6 @@ layout (location = 0) out int InstanceIndex; void main (void) { - vec3 vert = vertex * entities[entid].transform; - gl_Position = vec4 (vert, 1);; - InstanceIndex = gl_InstanceIndex; + vec4 pos = vec4 (vertex * entities[entid].transform, 1); + gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos; } diff --git a/libs/video/renderer/vulkan/shader/iqm.frag b/libs/video/renderer/vulkan/shader/iqm.frag index 543ee0bdb..db8e781e8 100644 --- a/libs/video/renderer/vulkan/shader/iqm.frag +++ b/libs/video/renderer/vulkan/shader/iqm.frag @@ -1,9 +1,9 @@ #version 450 -layout (set = 1, binding = 0) uniform sampler2D Skin; +layout (set = 2, binding = 0) uniform sampler2D Skin; layout (push_constant) uniform PushConstants { - layout (offset = 68) + layout (offset = 72) uint colorA; uint colorB; vec4 base_color; diff --git a/libs/video/renderer/vulkan/shader/iqm.vert b/libs/video/renderer/vulkan/shader/iqm.vert index 4b5d06433..7c86acff5 100644 --- a/libs/video/renderer/vulkan/shader/iqm.vert +++ b/libs/video/renderer/vulkan/shader/iqm.vert @@ -3,12 +3,17 @@ #extension GL_EXT_multiview : enable layout (constant_id = 0) const bool IQMDepthOnly = false; +layout (constant_id = 1) const bool IQMShadow = false; layout (set = 0, binding = 0) uniform #include "matrices.h" ; -layout (set = 2, binding = 0) buffer Bones { +layout (set = 1, binding = 0) buffer ShadowView { + mat4x4 shadowView[]; +}; + +layout (set = 3, binding = 0) buffer Bones { // NOTE these are transposed, so v * m mat3x4 bones[]; }; @@ -16,6 +21,7 @@ layout (set = 2, binding = 0) buffer Bones { layout (push_constant) uniform PushConstants { mat4 Model; float blend; + uint MatrixBase; }; layout (location = 0) in vec3 vposition; @@ -41,7 +47,11 @@ main (void) m += bones[vbones.z] * vweights.z; m += bones[vbones.w] * vweights.w; vec4 pos = Model * vec4 (vec4(vposition, 1) * m, 1); - gl_Position = Projection3d * (View[gl_ViewIndex] * pos); + if (IQMShadow) { + gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos; + } else { + gl_Position = Projection3d * (View[gl_ViewIndex] * pos); + } if (!IQMDepthOnly) { position = pos; diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index 387304763..046e106a6 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -41,6 +41,7 @@ #include "QF/scene/entity.h" #include "QF/Vulkan/qf_alias.h" +#include "QF/Vulkan/qf_lighting.h" #include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_palette.h" #include "QF/Vulkan/qf_texture.h" @@ -60,48 +61,11 @@ typedef struct { vec4f_t fog; } alias_push_constants_t; -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_taskctx_t *taskctx, entity_t ent) -{ - auto ctx = taskctx->ctx; - auto device = ctx->device; - auto dfunc = device->funcs; - auto layout = taskctx->pipeline->layout; - - __auto_type mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands); - - VkDeviceSize offsets[] = { - pose1 * hdr->poseverts * sizeof (aliasvrt_t), - pose2 * hdr->poseverts * sizeof (aliasvrt_t), - 0, - }; - VkBuffer buffers[] = { - mesh->vertex_buffer, - mesh->vertex_buffer, - mesh->uv_buffer, - }; - int bindingCount = skin ? 3 : 2; - - Vulkan_BeginEntityLabel (ctx, cmd, ent); - - dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets); - dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0, - VK_INDEX_TYPE_UINT32); - QFV_PushConstants (device, cmd, layout, numPC, constants); - if (skin) { - VkDescriptorSet sets[] = { - skin->descriptor, - }; - dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 2, 1, sets, 0, 0); - } - dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0); - - QFV_CmdEndLabel (device, cmd); -} +typedef struct { + mat4f_t mat; + float blend; + uint32_t matrix_base; +} shadow_push_constants_t; static void alias_depth_range (qfv_taskctx_t *taskctx, float minDepth, float maxDepth) @@ -133,27 +97,24 @@ Vulkan_AliasRemoveSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin) } static void -alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) +push_alias_constants (const mat4f_t mat, float blend, byte *colors, + vec4f_t base_color, int pass, qfv_taskctx_t *taskctx) { - renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); - auto model = renderer->model; - aliashdr_t *hdr; - qfv_alias_skin_t *skin; - alias_push_constants_t constants = {}; + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto cmd = taskctx->cmd; + auto layout = taskctx->pipeline->layout; - if (!(hdr = model->aliashdr)) { - hdr = Cache_Get (&model->cache); - } + alias_push_constants_t constants = { + .blend = blend, + .colors = { VEC4_EXP (colors) }, + .base_color = base_color, + }; - animation_t *animation = Ent_GetComponent (ent.id, scene_animation, - ent.reg); - constants.blend = R_AliasGetLerpedFrames (animation, hdr); - - transform_t transform = Entity_Transform (ent); qfv_push_constants_t push_constants[] = { { VK_SHADER_STAGE_VERTEX_BIT, field_offset (alias_push_constants_t, mat), - sizeof (mat4f_t), Transform_GetWorldMatrixPtr (transform) }, + sizeof (mat4f_t), mat }, { VK_SHADER_STAGE_VERTEX_BIT, field_offset (alias_push_constants_t, blend), sizeof (float), &constants.blend }, @@ -167,6 +128,55 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) field_offset (alias_push_constants_t, fog), sizeof (constants.fog), &constants.fog }, }; + QFV_PushConstants (device, cmd, layout, pass ? 5 : 2, push_constants); +} + +static void +push_shadow_constants (const mat4f_t mat, float blend, uint16_t *matrix_base, + qfv_taskctx_t *taskctx) +{ + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto cmd = taskctx->cmd; + auto layout = taskctx->pipeline->layout; + + shadow_push_constants_t constants = { + .blend = blend, + .matrix_base = *matrix_base, + }; + + qfv_push_constants_t push_constants[] = { + { VK_SHADER_STAGE_VERTEX_BIT, + field_offset (shadow_push_constants_t, mat), + sizeof (mat4f_t), mat }, + { VK_SHADER_STAGE_VERTEX_BIT, + field_offset (shadow_push_constants_t, blend), + sizeof (float), &constants.blend }, + { VK_SHADER_STAGE_VERTEX_BIT, + field_offset (shadow_push_constants_t, matrix_base), + sizeof (uint32_t), &constants.matrix_base }, + }; + QFV_PushConstants (device, cmd, layout, 3, push_constants); +} + +static void +alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) +{ + renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); + auto model = renderer->model; + aliashdr_t *hdr; + qfv_alias_skin_t *skin; + uint16_t *matrix_base = taskctx->data; + + if (!(hdr = model->aliashdr)) { + hdr = Cache_Get (&model->cache); + } + + animation_t *animation = Ent_GetComponent (ent.id, scene_animation, + ent.reg); + float blend = R_AliasGetLerpedFrames (animation, hdr); + + transform_t transform = Entity_Transform (ent); if (0/*XXX ent->skin && ent->skin->tex*/) { //skin = ent->skin->tex; @@ -175,19 +185,57 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) skindesc = R_AliasGetSkindesc (animation, renderer->skinnum, hdr); skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin); } - QuatCopy (renderer->colormod, constants.base_color); - QuatCopy (skin->colors, constants.colors); + vec4f_t base_color; + byte colors[4]; + QuatCopy (renderer->colormod, base_color); + QuatCopy (skin->colors, colors); if (Ent_HasComponent (ent.id, scene_colormap, ent.reg)) { colormap_t *colormap=Ent_GetComponent (ent.id, scene_colormap, ent.reg); - constants.colors[0] = colormap->top * 16 + 8; - constants.colors[1] = colormap->bottom * 16 + 8; + colors[0] = colormap->top * 16 + 8; + colors[1] = colormap->bottom * 16 + 8; } - QuatZero (constants.fog); - emit_commands (taskctx->cmd, animation->pose1, animation->pose2, - pass ? skin : 0, - pass ? 5 : 2, push_constants, - hdr, taskctx, ent); + auto ctx = taskctx->ctx; + auto device = ctx->device; + auto dfunc = device->funcs; + auto cmd = taskctx->cmd; + auto layout = taskctx->pipeline->layout; + + auto mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands); + + VkDeviceSize offsets[] = { + animation->pose1 * hdr->poseverts * sizeof (aliasvrt_t), + animation->pose2 * hdr->poseverts * sizeof (aliasvrt_t), + 0, + }; + VkBuffer buffers[] = { + mesh->vertex_buffer, + mesh->vertex_buffer, + mesh->uv_buffer, + }; + int bindingCount = skin ? 3 : 2; + + Vulkan_BeginEntityLabel (ctx, cmd, ent); + + dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets); + dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0, + VK_INDEX_TYPE_UINT32); + if (pass && skin) { + VkDescriptorSet sets[] = { + skin->descriptor, + }; + dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + layout, 2, 1, sets, 0, 0); + } + if (matrix_base) { + push_shadow_constants (Transform_GetWorldMatrixPtr (transform), + blend, matrix_base, taskctx); + } else { + push_alias_constants (Transform_GetWorldMatrixPtr (transform), + blend, colors, base_color, pass, taskctx); + } + dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0); + QFV_CmdEndLabel (device, cmd); } static void @@ -202,12 +250,14 @@ alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) auto dfunc = device->funcs; auto layout = taskctx->pipeline->layout; auto cmd = taskctx->cmd; + bool shadow = !!taskctx->data; VkDescriptorSet sets[] = { - Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), + shadow ? Vulkan_Lighting_Descriptors (ctx, ctx->curFrame) + : Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), Vulkan_Palette_Descriptor (ctx), }; dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 0, 2, sets, 0, 0); + layout, 0, shadow ? 1 : 2, sets, 0, 0); auto queue = r_ent_queue; //FIXME fetch from scene for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) { diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 4955fbb94..2ba3fa2a8 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -50,6 +50,7 @@ #include "QF/scene/entity.h" #include "QF/Vulkan/qf_bsp.h" +#include "QF/Vulkan/qf_lighting.h" #include "QF/Vulkan/qf_lightmap.h" #include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_scene.h" @@ -80,7 +81,7 @@ typedef struct bsp_push_constants_s { float time; float alpha; float turb_scale; -} bsp_push_constants_t; +} bsp_frag_constants_t; static void add_texture (texture_t *tx, vulkan_ctx_t *ctx) @@ -798,27 +799,44 @@ bind_texture (vulktex_t *tex, uint32_t setnum, VkPipelineLayout layout, } static void -push_fragconst (bsp_push_constants_t *constants, VkPipelineLayout layout, +push_fragconst (QFV_BspQueue queue, VkPipelineLayout layout, qfv_device_t *device, VkCommandBuffer cmd) { + //XXX glsl_Fog_GetColor (fog); + //XXX fog[3] = glsl_Fog_GetDensity () / 64.0; + bsp_frag_constants_t constants = { + .time = vr_data.realtime, + .alpha = queue == QFV_bspTurb ? r_wateralpha : 1, + .turb_scale = queue == QFV_bspTurb ? 1 : 0, + }; + qfv_push_constants_t push_constants[] = { - //{ VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (mat), mat }, { VK_SHADER_STAGE_FRAGMENT_BIT, - field_offset (bsp_push_constants_t, fog), - sizeof (constants->fog), &constants->fog }, + field_offset (bsp_frag_constants_t, fog), + sizeof (constants.fog), &constants.fog }, { VK_SHADER_STAGE_FRAGMENT_BIT, - field_offset (bsp_push_constants_t, time), - sizeof (constants->time), &constants->time }, + field_offset (bsp_frag_constants_t, time), + sizeof (constants.time), &constants.time }, { VK_SHADER_STAGE_FRAGMENT_BIT, - field_offset (bsp_push_constants_t, alpha), - sizeof (constants->alpha), &constants->alpha }, + field_offset (bsp_frag_constants_t, alpha), + sizeof (constants.alpha), &constants.alpha }, { VK_SHADER_STAGE_FRAGMENT_BIT, - field_offset (bsp_push_constants_t, turb_scale), - sizeof (constants->turb_scale), &constants->turb_scale }, + field_offset (bsp_frag_constants_t, turb_scale), + sizeof (constants.turb_scale), &constants.turb_scale }, }; QFV_PushConstants (device, cmd, layout, 4, push_constants); } +static void +push_shadowconst (uint32_t matrix_base, VkPipelineLayout layout, + qfv_device_t *device, VkCommandBuffer cmd) +{ + qfv_push_constants_t push_constants[] = { + { VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (uint32_t), &matrix_base }, + }; + QFV_PushConstants (device, cmd, layout, 1, push_constants); +} + static void clear_queues (bspctx_t *bctx, bsp_pass_t *pass) { @@ -1146,6 +1164,7 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx) auto bctx = ctx->bsp_context; auto layout = taskctx->pipeline->layout; auto cmd = taskctx->cmd; + uint16_t *matrix_base = taskctx->data; if (!bctx->vertex_buffer) { return; @@ -1168,22 +1187,28 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx) 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); + if (matrix_base) { + VkDescriptorSet sets[] = { + Vulkan_Lighting_Descriptors (ctx, ctx->curFrame), + Vulkan_Scene_Descriptors (ctx), + }; + dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + layout, 0, 2, sets, 0, 0); + } else { + 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 (matrix_base) { + push_shadowconst (*matrix_base, layout, device, cmd); + } else { + push_fragconst (queue, layout, device, cmd); + } if (queue == QFV_bspSky) { vulktex_t skybox = { .descriptor = bctx->skybox_descriptor }; bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd); diff --git a/libs/video/renderer/vulkan/vulkan_iqm.c b/libs/video/renderer/vulkan/vulkan_iqm.c index 1fc653a95..9d40751f6 100644 --- a/libs/video/renderer/vulkan/vulkan_iqm.c +++ b/libs/video/renderer/vulkan/vulkan_iqm.c @@ -40,6 +40,7 @@ #include "QF/scene/entity.h" #include "QF/Vulkan/qf_iqm.h" +#include "QF/Vulkan/qf_lighting.h" #include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_texture.h" #include "QF/Vulkan/debug.h" @@ -56,6 +57,7 @@ typedef struct { mat4f_t mat; float blend; + uint32_t matrix_base; byte colorA[4]; byte colorB[4]; vec4f_t base_color; @@ -96,14 +98,14 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2, }; dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 1, 2, sets, 0, 0); + layout, 2, 2, sets, 0, 0); } else { VkDescriptorSet sets[] = { mesh->bones_descriptors[ctx->curFrame], }; dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 2, 1, sets, 0, 0); + layout, 3, 1, sets, 0, 0); } dfunc->vkCmdDrawIndexed (cmd, 3 * iqm->meshes[i].num_triangles, 1, 3 * iqm->meshes[i].first_triangle, 0, 0); @@ -195,12 +197,18 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) auto iqm = (iqm_t *) model->aliashdr; qfv_iqm_t *mesh = iqm->extra_data; auto skins = mesh->skins; - iqm_push_constants_t constants = {}; iqmframe_t *frame; + uint16_t *matrix_base = taskctx->data; animation_t *animation = Ent_GetComponent (ent.id, scene_animation, ent.reg); - constants.blend = R_IQMGetLerpedFrames (animation, iqm); + iqm_push_constants_t constants = { + .blend = R_IQMGetLerpedFrames (animation, iqm), + .matrix_base = matrix_base ? *matrix_base : 0, + .colorA = { VEC4_EXP (skins[0].colora) }, + .colorB = { VEC4_EXP (skins[0].colorb) }, + .base_color = { VEC4_EXP (renderer->colormod) }, + }; frame = R_IQMBlendFrames (iqm, animation->pose1, animation->pose2, constants.blend, 0); @@ -236,6 +244,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) { VK_SHADER_STAGE_VERTEX_BIT, field_offset (iqm_push_constants_t, blend), sizeof (float), &constants.blend }, + { VK_SHADER_STAGE_VERTEX_BIT, + field_offset (iqm_push_constants_t, matrix_base), + sizeof (uint32_t), &constants.matrix_base }, { VK_SHADER_STAGE_FRAGMENT_BIT, field_offset (iqm_push_constants_t, colorA), sizeof (constants.colorA), constants.colorA }, @@ -250,14 +261,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) sizeof (constants.fog), &constants.fog }, }; - QuatCopy (renderer->colormod, constants.base_color); - QuatCopy (skins[0].colora, constants.colorA); - QuatCopy (skins[0].colorb, constants.colorB); - QuatZero (constants.fog); - emit_commands (taskctx->cmd, animation->pose1, animation->pose2, pass ? skins : 0, - pass ? 6 : 2, push_constants, + pass ? 7 : 3, push_constants, iqm, taskctx, ent); } @@ -275,9 +281,10 @@ iqm_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) VkDescriptorSet sets[] = { Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), + Vulkan_Lighting_Descriptors (ctx, ctx->curFrame), }; dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, 0, 1, sets, 0, 0); + layout, 0, 2, sets, 0, 0); auto queue = r_ent_queue; //FIXME fetch from scene for (size_t i = 0; i < queue->ent_queues[mod_iqm].size; i++) { diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index dede9b474..e33745c90 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -263,12 +263,11 @@ lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result, 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); + if (!r->numLayers || !d_lightstylevalue[ls]) { + continue; + } auto renderpass = &render->renderpasses[r->renderpass_index]; auto view = create_view (ctx, r); auto bi = &renderpass->beginInfo; @@ -1188,3 +1187,10 @@ Vulkan_LoadLights (scene_t *scene, vulkan_ctx_t *ctx) lctx->ldata = scene->lights; } } + +VkDescriptorSet +Vulkan_Lighting_Descriptors (vulkan_ctx_t *ctx, int frame) +{ + auto lctx = ctx->lighting_context; + return lctx->frames.a[frame].shadowmat_set; +}