mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
[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.
This commit is contained in:
parent
aed1e7e077
commit
ff27da4a05
10 changed files with 280 additions and 138 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue