mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-16 06:11:15 +00:00
[vulkan] Add a level of indirection to shadow matrices
Batching shadow map rendering needs be able to reference matrices for multiple lights in a single batch, but the only input is the view index, so use that to look up the matrix index rather than using it to index the matrices directly (modulo the base index that's still there).
This commit is contained in:
parent
3a31fa111d
commit
72ef0662f5
5 changed files with 64 additions and 13 deletions
|
@ -85,6 +85,7 @@ typedef struct lightingframe_s {
|
|||
VkDescriptorSet attach_set;
|
||||
|
||||
VkBuffer shadowmat_buffer;
|
||||
VkBuffer shadowmat_id_buffer;
|
||||
VkBuffer light_buffer;
|
||||
VkBuffer render_buffer;
|
||||
VkBuffer style_buffer;
|
||||
|
|
|
@ -6,6 +6,10 @@ layout (set = 0, binding = 0) buffer ShadowView {
|
|||
mat4x4 shadowView[];
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) buffer ShadowId {
|
||||
uint shadowId[];
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
mat4 Model;
|
||||
float blend;
|
||||
|
@ -21,5 +25,6 @@ void
|
|||
main (void)
|
||||
{
|
||||
vec4 pos = mix (vertexa, vertexb, blend);
|
||||
gl_Position = shadowView[MatrixBase + gl_ViewIndex] * (Model * pos);
|
||||
uint matid = shadowId[MatrixBase + gl_ViewIndex];
|
||||
gl_Position = shadowView[matid] * (Model * pos);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ layout (set = 0, binding = 0) buffer ShadowView {
|
|||
mat4x4 shadowView[];
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) buffer ShadowId {
|
||||
uint shadowId[];
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
uint MatrixBase;
|
||||
};
|
||||
|
@ -25,5 +29,6 @@ void
|
|||
main (void)
|
||||
{
|
||||
vec4 pos = vec4 (vertex * entities[entid].transform, 1);
|
||||
gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos;
|
||||
uint matid = shadowId[MatrixBase + gl_ViewIndex];
|
||||
gl_Position = shadowView[matid] * pos;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ layout (set = 1, binding = 0) buffer ShadowView {
|
|||
mat4x4 shadowView[];
|
||||
};
|
||||
|
||||
layout (set = 1, binding = 1) buffer ShadowId {
|
||||
uint shadowId[];
|
||||
};
|
||||
|
||||
layout (set = 3, binding = 0) buffer Bones {
|
||||
// NOTE these are transposed, so v * m
|
||||
mat3x4 bones[];
|
||||
|
@ -49,7 +53,8 @@ main (void)
|
|||
m += mat3x4(1,0,0,0,0,1,0,0,0,0,1,0) * (1 - dot(vweights, vec4(1,1,1,1)));
|
||||
vec4 pos = Model * vec4 (vec4(vposition, 1) * m, 1);
|
||||
if (IQMShadow) {
|
||||
gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos;
|
||||
uint matid = shadowId[MatrixBase + gl_ViewIndex];
|
||||
gl_Position = shadowView[matid] * pos;
|
||||
} else {
|
||||
gl_Position = Projection3d * (View[gl_ViewIndex] * pos);
|
||||
}
|
||||
|
|
|
@ -1090,6 +1090,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
+ 3 * sizeof (qfv_resobj_t)
|
||||
// light matrices
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light matrix ids
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light ids
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light data
|
||||
|
@ -1104,7 +1106,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.name = "lights",
|
||||
.va_ctx = ctx->va_ctx,
|
||||
.memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
.num_objects = 2 + 3 + 6 * frames,
|
||||
.num_objects = 2 + 3 + 7 * frames,
|
||||
.objects = (qfv_resobj_t *) &lctx->light_resources[1],
|
||||
};
|
||||
auto splat_verts = lctx->light_resources->objects;
|
||||
|
@ -1113,7 +1115,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
auto default_view_cube = &default_map[1];
|
||||
auto default_view_2d = &default_view_cube[1];
|
||||
auto light_mats = &default_view_2d[1];
|
||||
auto light_ids = &light_mats[frames];
|
||||
auto light_mat_ids = &light_mats[frames];
|
||||
auto light_ids = &light_mat_ids[frames];
|
||||
auto light_data = &light_ids[frames];
|
||||
auto light_render = &light_data[frames];
|
||||
auto light_styles = &light_render[frames];
|
||||
|
@ -1237,6 +1240,16 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
light_mat_ids[i] = (qfv_resobj_t) {
|
||||
.name = va (ctx->va_ctx, "matrix ids:%zd", i),
|
||||
.type = qfv_res_buffer,
|
||||
.buffer = {
|
||||
// never need more than 6 matrices per light
|
||||
.size = sizeof (uint32_t[MaxLights * 6]),
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
QFV_CreateResource (device, lctx->light_resources);
|
||||
|
@ -1266,6 +1279,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.lights_set = QFV_DSManager_AllocSet (lights_mgr),
|
||||
.attach_set = QFV_DSManager_AllocSet (attach_mgr),
|
||||
.shadowmat_buffer = light_mats[i].buffer.buffer,
|
||||
.shadowmat_id_buffer = light_mat_ids[i].buffer.buffer,
|
||||
.light_buffer = light_data[i].buffer.buffer,
|
||||
.render_buffer = light_render[i].buffer.buffer,
|
||||
.style_buffer = light_styles[i].buffer.buffer,
|
||||
|
@ -1289,6 +1303,8 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
VkDescriptorBufferInfo bufferInfo[] = {
|
||||
{ .buffer = lframe->shadowmat_buffer,
|
||||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
{ .buffer = lframe->shadowmat_id_buffer,
|
||||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
{ .buffer = lframe->id_buffer,
|
||||
.offset = 0, .range = VK_WHOLE_SIZE, },
|
||||
{ .buffer = lframe->light_buffer,
|
||||
|
@ -1307,39 +1323,45 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[0], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->shadowmat_set,
|
||||
.dstBinding = 1,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[1], },
|
||||
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[1], },
|
||||
.pBufferInfo = &bufferInfo[2], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 1,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[2], },
|
||||
.pBufferInfo = &bufferInfo[3], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 2,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[3], },
|
||||
.pBufferInfo = &bufferInfo[4], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 3,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[4], },
|
||||
.pBufferInfo = &bufferInfo[5], },
|
||||
{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = lframe->lights_set,
|
||||
.dstBinding = 4,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.pBufferInfo = &bufferInfo[5], },
|
||||
.pBufferInfo = &bufferInfo[6], },
|
||||
};
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 6, bufferWrite, 0, 0);
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 7, bufferWrite, 0, 0);
|
||||
}
|
||||
|
||||
make_default_map (64, lctx->default_map, ctx);
|
||||
|
@ -1501,6 +1523,19 @@ upload_light_matrices (lightingctx_t *lctx, vulkan_ctx_t *ctx)
|
|||
QFV_PacketCopyBuffer (packet, lframe->shadowmat_buffer, 0, bb);
|
||||
}
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
// FIXME temporary until batched shadow rendering is implemented
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
size_t id_size = sizeof (uint32_t[MaxLights * 6]);
|
||||
uint32_t *id_data = QFV_PacketExtend (packet, id_size);
|
||||
for (int i = 0; i < MaxLights * 6; i++) {
|
||||
id_data[i] = i;
|
||||
}
|
||||
for (size_t i = 0; i < lctx->frames.size; i++) {
|
||||
auto lframe = &lctx->frames.a[i];
|
||||
QFV_PacketCopyBuffer (packet, lframe->shadowmat_id_buffer, 0, bb);
|
||||
}
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1839,10 +1874,10 @@ build_shadow_maps (lightingctx_t *lctx, vulkan_ctx_t *ctx)
|
|||
|
||||
switch (lr->numLayers) {
|
||||
case 6:
|
||||
lr->renderpass_index = 2;
|
||||
lr->renderpass_index = 6 - 1;
|
||||
break;
|
||||
case num_cascade:
|
||||
lr->renderpass_index = 1;
|
||||
lr->renderpass_index = num_cascade - 1;
|
||||
break;
|
||||
case 1:
|
||||
lr->renderpass_index = 0;
|
||||
|
|
Loading…
Reference in a new issue