diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index e4eb5bba8..1594a8aab 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -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; diff --git a/libs/video/renderer/vulkan/shader/alias_shadow.vert b/libs/video/renderer/vulkan/shader/alias_shadow.vert index fcd6ff890..e37dc8276 100644 --- a/libs/video/renderer/vulkan/shader/alias_shadow.vert +++ b/libs/video/renderer/vulkan/shader/alias_shadow.vert @@ -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); } diff --git a/libs/video/renderer/vulkan/shader/bsp_shadow.vert b/libs/video/renderer/vulkan/shader/bsp_shadow.vert index 1ff1d929c..72ef32b93 100644 --- a/libs/video/renderer/vulkan/shader/bsp_shadow.vert +++ b/libs/video/renderer/vulkan/shader/bsp_shadow.vert @@ -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; } diff --git a/libs/video/renderer/vulkan/shader/iqm.vert b/libs/video/renderer/vulkan/shader/iqm.vert index 5362083bd..0ac7ff2b6 100644 --- a/libs/video/renderer/vulkan/shader/iqm.vert +++ b/libs/video/renderer/vulkan/shader/iqm.vert @@ -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); } diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 36a809a87..83e5c784d 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -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;