feat: basic shadow map + renderdoc labels

This commit is contained in:
2026-10-11 01:02:26 +02:00
parent 4bf87bd91b
commit 95d1497169
36 changed files with 880 additions and 228 deletions
+10 -1
View File
@@ -47,6 +47,7 @@ void LightComponent::Render(const RenderContext& ctx)
.range = m_Range,
.innerConeAngle = m_InnerConeAngle,
.outerConeAngle = m_OuterConeAngle,
.castShadows = m_CastShadows,
});
}
@@ -57,7 +58,8 @@ nlohmann::json LightComponent::Serialize() const {
{"intensity", m_Intensity},
{"range", m_Range},
{"innerConeAngle", m_InnerConeAngle},
{"outerConeAngle", m_OuterConeAngle}
{"outerConeAngle", m_OuterConeAngle},
{"castShadows", m_CastShadows}
};
}
@@ -88,6 +90,10 @@ void LightComponent::Deserialize(const nlohmann::json& data) {
outerConeAngle = data.at("outerConeAngle").get<float>();
}
SetConeAngles(innerConeAngle, outerConeAngle);
if (data.contains("castShadows")) {
m_CastShadows = data.at("castShadows").get<bool>();
}
}
void LightComponent::ImGuiInspector() {
@@ -106,6 +112,9 @@ void LightComponent::ImGuiInspector() {
}
if (m_Type == LightType::Directional) {
ImGui::Checkbox("Cast Shadows", &m_CastShadows);
ImGui::SameLine();
ImGui::TextDisabled("(first directional light only)");
return;
}
@@ -33,6 +33,9 @@ void MeshRendererComponent::Start() {
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
);
const std::string bufferName = GetGameObject()->GetName() + " (skinned vertices)";
vkutil::addDebugLabel(gfxDevice.getDevice(), m_skinnedMesh->skinnedVertexBuffer.buffer, bufferName.c_str());
}
}
@@ -74,6 +74,7 @@ void BindlessSetManager::init(
};
VK_CHECK(vkCreateDescriptorPool(device, &poolInfo, nullptr, &descPool));
vkutil::addDebugLabel(device, descPool, "bindless descriptor pool");
}
{ // build desc set layout
@@ -111,6 +112,7 @@ void BindlessSetManager::init(
};
VK_CHECK(vkCreateDescriptorSetLayout(device, &info, nullptr, &descSetLayout));
vkutil::addDebugLabel(device, descSetLayout, "bindless descriptor set layout");
}
{ // alloc desc set
@@ -122,6 +124,7 @@ void BindlessSetManager::init(
};
VK_CHECK(vkAllocateDescriptorSets(device, &allocInfo, &descSet));
vkutil::addDebugLabel(device, descSet, "bindless descriptor set");
}
initDefaultSamplers(device, maxAnisotropy);
+6 -1
View File
@@ -99,8 +99,13 @@ void ComputePipeline::CreateComputePipeline(const std::string& compPath,
throw std::runtime_error("Can't make compute pipeline!");
}
vkutil::addDebugLabel(m_device.getDevice(), m_compShaderModule, compFileName.c_str());
if (!configInfo.name.empty()) {
vkutil::addDebugLabel(GameState::GetInstance().Gfx().getDevice(), m_computePipeline, configInfo.name.c_str());
vkutil::addDebugLabel(m_device.getDevice(), m_computePipeline, configInfo.name.c_str());
const std::string layoutName = configInfo.name + " Layout";
vkutil::addDebugLabel(m_device.getDevice(), configInfo.pipelineLayout, layoutName.c_str());
}
}
+4
View File
@@ -156,6 +156,7 @@ void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const E
auto swapchainLayout = VK_IMAGE_LAYOUT_UNDEFINED; {
ZoneScopedN("Clear Swapchain Image");
vkutil::ScopedCmdLabel label(cmd, "Clear Swapchain Image", vkutil::labelColors::transfer);
const VkImageSubresourceRange clearRange = vkinit::imageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
vkutil::transitionImage(cmd, swapchainImage, swapchainLayout, VK_IMAGE_LAYOUT_GENERAL);
@@ -167,6 +168,7 @@ void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const E
if (true) {
ZoneScopedN("Copy DrawImage To Swapchain");
vkutil::ScopedCmdLabel label(cmd, "Copy DrawImage To Swapchain", vkutil::labelColors::transfer);
vkutil::transitionImage(
cmd,
@@ -190,6 +192,7 @@ void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const E
if (props.imguiPass) {
ZoneScopedN("ImGui Render");
vkutil::ScopedCmdLabel label(cmd, "ImGui Render", vkutil::labelColors::ui);
props.imguiPass->render(
cmd,
@@ -202,6 +205,7 @@ void GfxDevice::endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const E
{
ZoneScopedN("Transition Swapchain To Present");
vkutil::ScopedCmdLabel label(cmd, "Transition Swapchain To Present", vkutil::labelColors::transfer);
vkutil::transitionImage(cmd, swapchainImage, swapchainLayout, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
swapchainLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
@@ -40,6 +40,10 @@ void VulkanImmediateExecutor::init(
};
VK_CHECK(vkCreateFence(deviceHandle, &fenceCreateInfo, nullptr, &immFence));
vkutil::addDebugLabel(deviceHandle, immCommandPool, "immediate command pool");
vkutil::addDebugLabel(deviceHandle, immCommandBuffer, "immediate command buffer");
vkutil::addDebugLabel(deviceHandle, immFence, "immediate fence");
initialized = true;
} catch (...) {
cleanup(deviceHandle);
@@ -26,6 +26,11 @@ void FrameManager::init(VkDevice dev, std::uint32_t queueFamily) {
const auto cmdAllocInfo = vkinit::commandBufferAllocateInfo(commandPool, 1);
auto& mainCommandBuffer = frames[i].commandBuffer;
VK_CHECK(vkAllocateCommandBuffers(device, &cmdAllocInfo, &mainCommandBuffer));
const std::string poolName = "frame " + std::to_string(i) + " command pool";
const std::string cmdName = "frame " + std::to_string(i) + " command buffer";
vkutil::addDebugLabel(device, commandPool, poolName.c_str());
vkutil::addDebugLabel(device, mainCommandBuffer, cmdName.c_str());
}
} catch (...) {
cleanup(dev);
@@ -178,7 +178,9 @@ std::optional<GPUImage> ImageManager::loadImageFromFile(
}
image.debugName = path.string();
vkutil::addDebugLabel(device, image.image, path.string().c_str());
vkutil::addDebugLabel(device, image.image, image.debugName.c_str());
const std::string viewName = image.debugName + " (view)";
vkutil::addDebugLabel(device, image.imageView, viewName.c_str());
return image;
}
+3
View File
@@ -156,6 +156,9 @@ void MeshCache::uploadMesh(GfxDevice& gfxDevice, const CPUMesh& cpuMesh, GPUMesh
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE);
const auto skinningBufferName = cpuMesh.name + " (skinning data)";
vkutil::addDebugLabel(gfxDevice.getDevice(), gpuMesh.skinningDataBuffer.buffer, skinningBufferName.c_str());
auto skinningStaging =
gfxDevice.createBuffer(
skinningDataSize,
+17 -18
View File
@@ -146,11 +146,11 @@ void Pipeline::CreateGraphicsPipeline(const std::string& vertPath, const std::st
CreateShaderModule(vertCode, &m_vertShaderModule);
// vkutil::addDebugLabel(
// m_device.getDevice(),
// m_fragShaderModule,
// VertFileName.c_str()
// );
vkutil::addDebugLabel(
m_device.getDevice(),
m_vertShaderModule,
VertFileName.c_str()
);
VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -173,11 +173,11 @@ void Pipeline::CreateGraphicsPipeline(const std::string& vertPath, const std::st
CreateShaderModule(fragCode, &m_fragShaderModule);
// vkutil::addDebugLabel(
// m_device.getDevice(),
// m_fragShaderModule,
// FragFileName.c_str()
// );
vkutil::addDebugLabel(
m_device.getDevice(),
m_fragShaderModule,
FragFileName.c_str()
);
VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
@@ -231,18 +231,17 @@ void Pipeline::CreateGraphicsPipeline(const std::string& vertPath, const std::st
pipelineInfo.basePipelineIndex = -1;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
if (!configInfo.name.empty()) {
// DebugLabel::SetObjectName(
// reinterpret_cast<uint64_t>(pipelineInfo.layout),
// VK_OBJECT_TYPE_PIPELINE_LAYOUT,
// configInfo.name.c_str()
// );
}
if (vkCreateGraphicsPipelines(m_device.getDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_graphicsPipeline) != VK_SUCCESS) {
throw std::runtime_error("Can't make pipeline!");
}
if (!configInfo.name.empty()) {
vkutil::addDebugLabel(m_device.getDevice(), m_graphicsPipeline, configInfo.name.c_str());
const std::string layoutName = configInfo.name + " Layout";
vkutil::addDebugLabel(m_device.getDevice(), configInfo.pipelineLayout, layoutName.c_str());
}
}
void Pipeline::CreateShaderModule(const std::vector<char>& code, VkShaderModule* shaderModule) const {
@@ -158,7 +158,8 @@ void LightCullingPipeline::appendLight(const Light& light)
.type = static_cast<std::uint32_t>(light.type),
.spotInnerCos = std::cos(light.innerConeAngle),
.spotOuterCos = std::cos(light.outerConeAngle),
.padding = glm::vec2{0.0f},
.castShadows = light.castShadows ? 1u : 0u,
.padding = 0.0f,
};
lightsBuffer.append(gpuLight);
}
@@ -9,6 +9,7 @@
#include <destrum/Graphics/RenderResources.h>
#include <destrum/Graphics/Caches/MeshCache.h>
#include <destrum/Graphics/Frustum.h>
#include <destrum/Graphics/Util.h>
#include "volk.h"
#include "spdlog/spdlog.h"
@@ -219,6 +220,16 @@ void MeshPipeline::drawMeshes(
const auto& mesh = meshCache.getMesh(dc.meshId);
const std::string& meshKey = meshCache.getMeshKey(dc.meshId);
vkutil::cmdBeginLabelFormatted(
cmd,
vkutil::labelColors::draw,
"%s [mesh %zu, material %u%s]",
meshKey.empty() ? "Mesh" : meshKey.c_str(),
dc.meshId,
dc.materialId,
dc.skinnedMesh != nullptr ? ", skinned" : "");
if (dc.meshId != prevMeshId)
{
prevMeshId = dc.meshId;
@@ -254,6 +265,8 @@ void MeshPipeline::drawMeshes(
);
vkCmdDrawIndexed(cmd, mesh.numIndices, 1, 0, 0, 0);
vkutil::cmdEndLabel(cmd);
};
if (!sortedDrawCommands.empty())
@@ -42,12 +42,14 @@ void QuadRendererPass::init(GfxDevice& gfxDevice, RenderResources& resources, Vk
vertexBytes,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_HOST);
vkutil::addDebugLabel(gfxDevice.getDevice(), vertexBuffer.buffer, "quad vertices");
const std::size_t indexBytes = InitialQuadCapacity * IndicesPerQuad * sizeof(std::uint32_t);
indexBuffer = gfxDevice.createBuffer(
indexBytes,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_HOST);
vkutil::addDebugLabel(gfxDevice.getDevice(), indexBuffer.buffer, "quad indices");
quadCapacity = InitialQuadCapacity;
@@ -321,6 +323,7 @@ void QuadRendererPass::ensureCapacity(
newCapacity * VerticesPerQuad * sizeof(QuadVertex),
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_HOST);
vkutil::addDebugLabel(gfxDevice.getDevice(), vertexBuffer.buffer, "quad vertices");
if (indexBuffer.buffer != VK_NULL_HANDLE) {
gfxDevice.destroyBuffer(indexBuffer);
@@ -329,6 +332,7 @@ void QuadRendererPass::ensureCapacity(
newCapacity * IndicesPerQuad * sizeof(std::uint32_t),
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_HOST);
vkutil::addDebugLabel(gfxDevice.getDevice(), indexBuffer.buffer, "quad indices");
quadCapacity = newCapacity;
}
@@ -0,0 +1,265 @@
#include <destrum/Graphics/Pipelines/ShadowMapPipeline.h>
#include <array>
#include <cassert>
#include <cmath>
#include <stdexcept>
#include <glm/gtc/matrix_transform.hpp>
#include <destrum/FS/AssetFS.h>
#include <destrum/Graphics/GfxDevice.h>
#include <destrum/Graphics/RenderResources.h>
#include <destrum/Graphics/Caches/MeshCache.h>
#include <destrum/Graphics/Util.h>
#include "volk.h"
#include "spdlog/spdlog.h"
void ShadowMapPipeline::init(GfxDevice& gfxDevice, RenderResources& resources)
{
try
{
const auto vertexShader =
AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/shadow.vert");
const auto bufferRange = VkPushConstantRange{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
.size = sizeof(PushConstants),
};
const auto pushConstantRanges = std::array{bufferRange};
const auto layouts = std::array{
resources.getBindlessDescSetLayout()
};
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = static_cast<std::uint32_t>(layouts.size());
pipelineLayoutInfo.pSetLayouts = layouts.data();
pipelineLayoutInfo.pushConstantRangeCount = static_cast<std::uint32_t>(pushConstantRanges.size());
pipelineLayoutInfo.pPushConstantRanges = pushConstantRanges.data();
if (vkCreatePipelineLayout(
gfxDevice.getDevice(),
&pipelineLayoutInfo,
nullptr,
&m_pipelineLayout) != VK_SUCCESS)
{
throw std::runtime_error("Could not create shadow map pipeline layout");
}
PipelineConfigInfo pipelineConfig{};
Pipeline::DefaultPipelineConfigInfo(pipelineConfig);
pipelineConfig.name = "Shadow Map Pipeline";
pipelineConfig.pipelineLayout = m_pipelineLayout;
pipelineConfig.vertexAttributeDescriptions = {};
pipelineConfig.vertexBindingDescriptions = {};
pipelineConfig.colorAttachments = {};
pipelineConfig.colorBlendInfo.attachmentCount = 0;
pipelineConfig.depthAttachment = shadowMapFormat;
// the light projection isn't Y flipped like the camera's, so the winding is mirrored
pipelineConfig.rasterizationInfo.cullMode = VK_CULL_MODE_NONE;
pipelineConfig.rasterizationInfo.depthBiasEnable = VK_TRUE;
pipelineConfig.rasterizationInfo.depthBiasConstantFactor = 0.0f;
pipelineConfig.rasterizationInfo.depthBiasSlopeFactor = 2.0f;
m_pipeline = std::make_unique<Pipeline>(
gfxDevice,
vertexShader.string(),
"",
pipelineConfig
);
const auto createInfo = vkutil::CreateImageInfo{
.format = shadowMapFormat,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.extent = VkExtent3D{SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 1},
};
shadowMapId = resources.createImage(gfxDevice, createInfo, "shadow map", nullptr, shadowMapId);
spdlog::info("Created {0}x{0} shadow map with id {1}", SHADOW_MAP_SIZE, shadowMapId);
}
catch (...)
{
cleanup(gfxDevice.getDevice());
throw;
}
}
void ShadowMapPipeline::cleanup(VkDevice device)
{
m_pipeline.reset();
if (m_pipelineLayout != VK_NULL_HANDLE && device != VK_NULL_HANDLE)
{
vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr);
}
m_pipelineLayout = VK_NULL_HANDLE;
shadowMapId = NULL_IMAGE_ID;
}
glm::mat4 ShadowMapPipeline::calculateLightViewProj(const glm::vec3& lightDirection, const glm::vec3& center) const
{
const glm::vec3 direction = glm::normalize(lightDirection);
const glm::vec3 up = std::abs(direction.y) > 0.99f ? glm::vec3{0.0f, 0.0f, 1.0f} : glm::vec3{0.0f, 1.0f, 0.0f};
const glm::mat4 lightView = glm::lookAt(glm::vec3{0.0f}, direction, up);
const float texelSize = (2.0f * shadowDistance) / static_cast<float>(SHADOW_MAP_SIZE);
glm::vec3 lightSpaceCenter = glm::vec3(lightView * glm::vec4(center, 1.0f));
lightSpaceCenter.x = std::floor(lightSpaceCenter.x / texelSize) * texelSize;
lightSpaceCenter.y = std::floor(lightSpaceCenter.y / texelSize) * texelSize;
const glm::mat4 lightProj = glm::orthoRH_ZO(
lightSpaceCenter.x - shadowDistance,
lightSpaceCenter.x + shadowDistance,
lightSpaceCenter.y - shadowDistance,
lightSpaceCenter.y + shadowDistance,
-lightSpaceCenter.z - shadowDepthRange,
-lightSpaceCenter.z + shadowDepthRange);
return lightProj * lightView;
}
float ShadowMapPipeline::getNormalOffset() const
{
const float texelSize = (2.0f * shadowDistance) / static_cast<float>(SHADOW_MAP_SIZE);
return texelSize * 1.5f;
}
void ShadowMapPipeline::draw(
VkCommandBuffer cmd,
const RenderResources& resources,
const GPUBuffer& sceneDataBuffer,
const std::vector<MeshDrawCommand>& drawCommands,
const std::vector<std::size_t>& sortedDrawCommands)
{
if (!m_pipeline || shadowMapId == NULL_IMAGE_ID)
{
return;
}
const auto& shadowMap = resources.getImage(shadowMapId);
vkutil::transitionImage(
cmd,
shadowMap.image,
shadowMap.layout,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
shadowMap.setLayout(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
auto renderInfo = vkutil::createRenderingInfo({
.renderExtent = shadowMap.getExtent2D(),
.depthImageView = shadowMap.imageView,
.depthImageClearValue = 1.f,
});
renderInfo.renderingInfo.pDepthAttachment = &renderInfo.depthAttachment;
vkCmdBeginRendering(cmd, &renderInfo.renderingInfo);
m_pipeline->bind(cmd);
resources.bindBindlessDescSet(cmd, m_pipelineLayout);
const auto viewport = VkViewport{
.x = 0.f,
.y = 0.f,
.width = static_cast<float>(SHADOW_MAP_SIZE),
.height = static_cast<float>(SHADOW_MAP_SIZE),
.minDepth = 0.f,
.maxDepth = 1.f,
};
vkCmdSetViewport(cmd, 0, 1, &viewport);
const auto scissor = VkRect2D{
.offset = {},
.extent = shadowMap.getExtent2D(),
};
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetPolygonModeEXT(cmd, VK_POLYGON_MODE_FILL);
const MeshCache& meshCache = resources.meshes();
MeshID prevMeshId = NULL_MESH_ID;
const auto drawOne = [&](const MeshDrawCommand& dc)
{
if (!dc.castShadow)
{
return;
}
const auto& mesh = meshCache.getMesh(dc.meshId);
const std::string& meshKey = meshCache.getMeshKey(dc.meshId);
vkutil::cmdBeginLabelFormatted(
cmd,
vkutil::labelColors::draw,
"%s [mesh %zu, material %u%s]",
meshKey.empty() ? "Mesh" : meshKey.c_str(),
dc.meshId,
dc.materialId,
dc.skinnedMesh != nullptr ? ", skinned" : "");
if (dc.meshId != prevMeshId)
{
prevMeshId = dc.meshId;
vkCmdBindIndexBuffer(cmd, mesh.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
}
const auto pushConstants = PushConstants{
.transform = dc.transformMatrix,
.sceneDataBuffer = sceneDataBuffer.address,
.vertexBuffer =
dc.skinnedMesh != nullptr
? dc.skinnedMesh->skinnedVertexBuffer.address
: mesh.vertexBuffer.address,
.materialId = dc.materialId,
.padding = 0,
};
vkCmdPushConstants(
cmd,
m_pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT,
0,
sizeof(PushConstants),
&pushConstants);
vkCmdDrawIndexed(cmd, mesh.numIndices, 1, 0, 0, 0);
vkutil::cmdEndLabel(cmd);
};
if (!sortedDrawCommands.empty())
{
for (std::size_t drawIndex : sortedDrawCommands)
{
assert(drawIndex < drawCommands.size());
drawOne(drawCommands[drawIndex]);
}
}
else
{
for (const MeshDrawCommand& dc : drawCommands)
{
drawOne(dc);
}
}
vkCmdEndRendering(cmd);
vkutil::transitionImage(
cmd,
shadowMap.image,
shadowMap.layout,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
shadowMap.setLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
@@ -53,6 +53,9 @@ void SkinningPipeline::init(GfxDevice& gfxDevice) {
MAX_JOINT_MATRICES * sizeof(glm::mat4),
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_CPU_TO_GPU);
const std::string bufferName = "joint matrices (frame " + std::to_string(i) + ")";
vkutil::addDebugLabel(device, jointMatricesBuffer.buffer.buffer, bufferName.c_str());
}
} catch (...) {
cleanup(gfxDevice);
@@ -84,6 +87,9 @@ void SkinningPipeline::doSkinning(VkCommandBuffer cmd,
assert(mesh.hasSkeleton);
assert(dc.skinnedMesh);
const std::string& meshKey = meshCache.getMeshKey(dc.meshId);
vkutil::ScopedCmdLabel label(cmd, meshKey.empty() ? "Skin Mesh" : meshKey.c_str(), vkutil::labelColors::compute);
const auto cs = PushConstants{
.jointMatricesBuffer = getCurrentFrameData(frameIndex).jointMatricesBuffer.buffer.address,
.jointMatricesStartIndex = static_cast<std::uint32_t>(dc.jointMatricesStartIndex),
+2
View File
@@ -130,6 +130,8 @@ ImageID RenderResources::createImage(
if (!debugName.empty()) {
vkutil::addDebugLabel(gfxDevice.getVkDevice(), image.image, debugName.c_str());
const std::string viewName = debugName + " (view)";
vkutil::addDebugLabel(gfxDevice.getVkDevice(), image.imageView, viewName.c_str());
image.debugName = debugName;
}
+58 -2
View File
@@ -44,6 +44,9 @@ void GameRenderer::init(GfxDevice& gfxDevice, RenderResources& _resources, glm::
lightCullingPipeline = std::make_unique<LightCullingPipeline>();
lightCullingPipeline->init(gfxDevice, _resources, drawImageSize);
shadowMapPipeline = std::make_unique<ShadowMapPipeline>();
shadowMapPipeline->init(gfxDevice, _resources);
lineRenderingPass = std::make_unique<LineRenderingPass>();
lineRenderingPass->init(gfxDevice, drawImageFormat);
@@ -66,6 +69,7 @@ void GameRenderer::beginDrawing(GfxDevice& gfxDevice)
meshDrawCommands.clear();
skinningPipeline->beginDrawing(gfxDevice.getCurrentFrameIndex());
lightCullingPipeline->beginDrawing(gfxDevice.getCurrentFrameIndex());
shadowLightDirection.reset();
QuadRenderingManager::GetInstance().ClearQuads();
}
@@ -97,9 +101,11 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
ZoneScopedN("GameRenderer::draw");
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "GameRenderer::draw");
vkutil::ScopedCmdLabel frameLabel(cmd, "GameRenderer::draw", vkutil::labelColors::frame);
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Skinning");
vkutil::ScopedCmdLabel label(cmd, "Skinning", vkutil::labelColors::compute);
skinningPipeline->flushCurrentFrame(
cmd,
@@ -118,10 +124,17 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Lights Buffer Flush");
vkutil::ScopedCmdLabel label(cmd, "Lights Buffer Flush", vkutil::labelColors::transfer);
lightCullingPipeline->flushCurrentFrame(cmd, gfxDevice);
}
const glm::mat4 lightViewProj = shadowLightDirection
? shadowMapPipeline->calculateLightViewProj(
*shadowLightDirection,
sceneData.camera.GetPosition())
: glm::mat4{1.0f};
// TODO: there has to be a better way to do this
const auto gpuSceneData = GPUSceneData{
.view = sceneData.camera.GetViewMatrix(),
@@ -139,11 +152,15 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
.numLights = lightCullingPipeline->getNumLights(),
.tileCountX = lightCullingPipeline->getTileCount().x,
.debugLightHeatmap = renderLightHeatmap ? 1u : 0u,
.shadowMapId = static_cast<std::uint32_t>(shadowMapPipeline->getShadowMapId()),
.shadowNormalOffset = shadowMapPipeline->getNormalOffset(),
.padding = 0,
.lightViewProj = lightViewProj,
};
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Material Buffer Barrier");
vkutil::ScopedCmdLabel label(cmd, "Material Buffer Barrier", vkutil::labelColors::transfer);
vkutil::bufferHostWriteToShaderReadBarrier(
cmd,
@@ -155,6 +172,7 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Upload Scene Data");
vkutil::ScopedCmdLabel label(cmd, "Upload Scene Data", vkutil::labelColors::transfer);
sceneDataBuffer.uploadNewData(
cmd,
@@ -189,8 +207,22 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
depthImage.setLayout(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
}
if (shadowLightDirection)
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Shadow Map");
vkutil::ScopedCmdLabel label(cmd, "Shadow Map", vkutil::labelColors::shadow);
shadowMapPipeline->draw(
cmd,
*resources,
sceneDataBuffer.getBuffer(),
meshDrawCommands,
sortedMeshDrawCommands);
}
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Depth Prepass");
vkutil::ScopedCmdLabel label(cmd, "Depth Prepass", vkutil::labelColors::depth);
auto depthPrepassInfo = vkutil::createRenderingInfo({
.renderExtent = drawImage.getExtent2D(),
@@ -215,6 +247,7 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Light Culling");
vkutil::ScopedCmdLabel label(cmd, "Light Culling", vkutil::labelColors::compute);
vkutil::transitionImage(
cmd,
@@ -247,6 +280,8 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
renderInfo.renderingInfo.pColorAttachments = &renderInfo.colorAttachment;
renderInfo.renderingInfo.pDepthAttachment = &renderInfo.depthAttachment;
vkutil::cmdBeginLabel(cmd, "Forward Pass", vkutil::labelColors::opaque);
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "vkCmdBeginRendering");
@@ -255,6 +290,7 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "MeshPipeline::draw");
vkutil::ScopedCmdLabel label(cmd, "MeshPipeline::draw", vkutil::labelColors::opaque);
meshPipeline->draw(
cmd,
@@ -268,6 +304,7 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "SkyboxPipeline::draw");
vkutil::ScopedCmdLabel label(cmd, "SkyboxPipeline::draw", vkutil::labelColors::sky);
skyboxPipeline->draw(cmd, *resources, camera);
}
@@ -278,8 +315,11 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
vkCmdEndRendering(cmd);
}
vkutil::cmdEndLabel(cmd);
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "LineRenderingPass::draw");
vkutil::ScopedCmdLabel label(cmd, "LineRenderingPass::draw", vkutil::labelColors::debug);
lineRenderingPass->draw(
cmd,
@@ -291,6 +331,7 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "QuadRendererPass::draw");
vkutil::ScopedCmdLabel label(cmd, "QuadRendererPass::draw", vkutil::labelColors::ui);
quadRendererPass->draw(
cmd,
@@ -302,7 +343,6 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
static_cast<float>(drawImage.extent.height),
0.0f, -1.0f, 1.0f));
}
// vkutil::cmdEndLabel(cmd);
}
void GameRenderer::drawQuads(
@@ -335,6 +375,9 @@ void GameRenderer::cleanup(GfxDevice& gfxDevice)
if (lightCullingPipeline)
lightCullingPipeline->cleanup(gfxDevice);
if (shadowMapPipeline)
shadowMapPipeline->cleanup(device);
if (skyboxPipeline)
skyboxPipeline->cleanup(device);
@@ -358,6 +401,8 @@ void GameRenderer::cleanup(GfxDevice& gfxDevice)
lineRenderingPass.reset();
quadRendererPass.reset();
lightCullingPipeline.reset();
shadowMapPipeline.reset();
shadowLightDirection.reset();
pendingMaterialUploads.clear();
meshDrawCommands.clear();
sortedMeshDrawCommands.clear();
@@ -402,7 +447,18 @@ void GameRenderer::drawSkinnedMesh(MeshID id,
void GameRenderer::submitLight(const Light& light)
{
lightCullingPipeline->appendLight(light);
Light submittedLight = light;
// there's a single shadow map, the first shadow casting directional light gets it
submittedLight.castShadows =
light.castShadows && light.type == LightType::Directional && !shadowLightDirection;
if (submittedLight.castShadows)
{
shadowLightDirection = light.direction;
}
lightCullingPipeline->appendLight(submittedLight);
}
const GPUImage& GameRenderer::getDrawImage() const
@@ -71,6 +71,8 @@ void CubeMap::RenderToCubemap(
}
gfxDevice.getImmediateExecuter().immediateSubmit([&](VkCommandBuffer cmd) {
vkutil::ScopedCmdLabel label(cmd, "HDRI To Cubemap", vkutil::labelColors::sky);
VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@@ -108,6 +110,8 @@ void CubeMap::RenderToCubemap(
scissor.extent = {size, size};
for (std::uint32_t face = 0; face < 6; ++face) {
vkutil::cmdBeginLabelFormatted(cmd, vkutil::labelColors::draw, "Cubemap Face %u", face);
PC pc{};
pc.viewMtx = viewMatrices[face];
pc.projMtx = m_projection;
@@ -153,6 +157,8 @@ void CubeMap::RenderToCubemap(
vkCmdDraw(cmd, 36, 1, 0, 0);
vkCmdEndRendering(cmd);
vkutil::cmdEndLabel(cmd);
}
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@@ -199,6 +205,7 @@ void CubeMap::CreateCubeMap(
.mipMap = false,
.isCubemap = true
});
vkutil::addDebugLabel(gfxDevice.getDevice(), cubeMapImage.image, "skybox cubemap");
std::array<VkImageView, 6> faceViews{};
@@ -220,6 +227,9 @@ void CubeMap::CreateCubeMap(
&viewInfo,
nullptr,
&faceViews[face]));
const std::string faceViewName = "skybox cubemap face " + std::to_string(face) + " (view)";
vkutil::addDebugLabel(gfxDevice.getDevice(), faceViews[face], faceViewName.c_str());
}
spdlog::info("HDRI image id = {}", m_hdrImage);
@@ -305,6 +315,7 @@ void CubeMap::InitCubemapPipeline(
PipelineConfigInfo pipelineConfig{};
Pipeline::DefaultPipelineConfigInfo(pipelineConfig);
pipelineConfig.name = "HDRI To Cubemap Pipeline";
pipelineConfig.vertexAttributeDescriptions = {};
pipelineConfig.vertexBindingDescriptions = {};
+20
View File
@@ -21,6 +21,22 @@ void Swapchain::initSync(VkDevice device) {
for (std::uint32_t i = 0; i < FRAMES_IN_FLIGHT; ++i) {
VK_CHECK(vkCreateFence(device, &fenceCreateInfo, nullptr, &frames[i].renderFence));
VK_CHECK(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &frames[i].swapchainSemaphore));
const auto fenceName = std::format("frame {} render fence", i);
const auto semaphoreName = std::format("frame {} swapchain semaphore", i);
vkutil::addDebugLabel(device, frames[i].renderFence, fenceName.c_str());
vkutil::addDebugLabel(device, frames[i].swapchainSemaphore, semaphoreName.c_str());
}
}
void Swapchain::nameSwapchainObjects(VkDevice device) const {
for (std::size_t i = 0; i < images.size(); ++i) {
const auto imageName = std::format("swapchain image {}", i);
const auto viewName = std::format("swapchain image {} (view)", i);
const auto semaphoreName = std::format("swapchain image {} render semaphore", i);
vkutil::addDebugLabel(device, images[i], imageName.c_str());
vkutil::addDebugLabel(device, imageViews[i], viewName.c_str());
vkutil::addDebugLabel(device, imageRenderSemaphores[i], semaphoreName.c_str());
}
}
@@ -85,6 +101,8 @@ void Swapchain::createSwapchain(
VK_CHECK(vkCreateSemaphore(vkbDevice, &sci, nullptr, &sem));
}
nameSwapchainObjects(vkbDevice);
extent = m_swapchain.extent;
dirty = false;
}
@@ -187,6 +205,8 @@ void Swapchain::recreateSwapchain(
VK_CHECK(vkCreateSemaphore(vkbDevice, &sci, nullptr, &sem));
}
nameSwapchainObjects(vkbDevice);
extent = m_swapchain.extent;
dirty = false;
}
+101 -101
View File
@@ -188,54 +188,124 @@ void vkutil::bufferHostWriteToTransferReadBarrier(
}
void vkutil::addDebugLabel(VkDevice device, VkImage image, const char* label) {
void vkutil::addDebugLabel(VkDevice device, VkObjectType objectType, std::uint64_t objectHandle, const char* label) {
if (!vkSetDebugUtilsObjectNameEXT || device == VK_NULL_HANDLE || objectHandle == 0 || label == nullptr) {
return;
}
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_IMAGE,
.objectHandle = (std::uint64_t)image,
.objectType = objectType,
.objectHandle = objectHandle,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void vkutil::addDebugLabel(VkDevice device, VkImage image, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_IMAGE, reinterpret_cast<std::uint64_t>(image), label);
}
void vkutil::addDebugLabel(VkDevice device, VkImageView imageView, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast<std::uint64_t>(imageView), label);
}
void vkutil::addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_SHADER_MODULE,
.objectHandle = (std::uint64_t)shaderModule,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
addDebugLabel(device, VK_OBJECT_TYPE_SHADER_MODULE, reinterpret_cast<std::uint64_t>(shaderModule), label);
}
void vkutil::addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_PIPELINE,
.objectHandle = (std::uint64_t)pipeline,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
addDebugLabel(device, VK_OBJECT_TYPE_PIPELINE, reinterpret_cast<std::uint64_t>(pipeline), label);
}
void vkutil::addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, reinterpret_cast<std::uint64_t>(layout), label);
}
void vkutil::addDebugLabel(VkDevice device, VkBuffer buffer, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (std::uint64_t)buffer,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
addDebugLabel(device, VK_OBJECT_TYPE_BUFFER, reinterpret_cast<std::uint64_t>(buffer), label);
}
void vkutil::addDebugLabel(VkDevice device, VkSampler sampler, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_SAMPLER,
.objectHandle = (std::uint64_t)sampler,
.pObjectName = label,
addDebugLabel(device, VK_OBJECT_TYPE_SAMPLER, reinterpret_cast<std::uint64_t>(sampler), label);
}
void vkutil::addDebugLabel(VkDevice device, VkDescriptorPool descriptorPool, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_DESCRIPTOR_POOL, reinterpret_cast<std::uint64_t>(descriptorPool), label);
}
void vkutil::addDebugLabel(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, reinterpret_cast<std::uint64_t>(descriptorSetLayout), label);
}
void vkutil::addDebugLabel(VkDevice device, VkDescriptorSet descriptorSet, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_DESCRIPTOR_SET, reinterpret_cast<std::uint64_t>(descriptorSet), label);
}
void vkutil::addDebugLabel(VkDevice device, VkCommandPool commandPool, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_COMMAND_POOL, reinterpret_cast<std::uint64_t>(commandPool), label);
}
void vkutil::addDebugLabel(VkDevice device, VkCommandBuffer commandBuffer, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_COMMAND_BUFFER, reinterpret_cast<std::uint64_t>(commandBuffer), label);
}
void vkutil::addDebugLabel(VkDevice device, VkFence fence, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_FENCE, reinterpret_cast<std::uint64_t>(fence), label);
}
void vkutil::addDebugLabel(VkDevice device, VkSemaphore semaphore, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast<std::uint64_t>(semaphore), label);
}
void vkutil::addDebugLabel(VkDevice device, VkQueue queue, const char* label) {
addDebugLabel(device, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<std::uint64_t>(queue), label);
}
bool vkutil::debugLabelsEnabled() {
return vkCmdBeginDebugUtilsLabelEXT != nullptr && vkCmdEndDebugUtilsLabelEXT != nullptr;
}
void vkutil::cmdBeginLabel(VkCommandBuffer cmd, const char* label, const glm::vec4& color) {
if (!debugLabelsEnabled() || label == nullptr) {
return;
}
const auto labelInfo = VkDebugUtilsLabelEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
.pLabelName = label,
.color = {color.x, color.y, color.z, color.w},
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
vkCmdBeginDebugUtilsLabelEXT(cmd, &labelInfo);
}
void vkutil::cmdEndLabel(VkCommandBuffer cmd) {
if (!debugLabelsEnabled()) {
return;
}
vkCmdEndDebugUtilsLabelEXT(cmd);
}
void vkutil::cmdInsertLabel(VkCommandBuffer cmd, const char* label, const glm::vec4& color) {
if (!vkCmdInsertDebugUtilsLabelEXT || label == nullptr) {
return;
}
const auto labelInfo = VkDebugUtilsLabelEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
.pLabelName = label,
.color = {color.x, color.y, color.z, color.w},
};
vkCmdInsertDebugUtilsLabelEXT(cmd, &labelInfo);
}
vkutil::ScopedCmdLabel::ScopedCmdLabel(VkCommandBuffer cmd, const char* label, const glm::vec4& color)
: cmd(cmd) {
cmdBeginLabel(cmd, label, color);
}
vkutil::ScopedCmdLabel::~ScopedCmdLabel() {
cmdEndLabel(cmd);
}
vkutil::RenderInfo vkutil::createRenderingInfo(const RenderingInfoParams& params) {
@@ -319,76 +389,6 @@ VkShaderModule vkutil::loadShaderModule(const std::filesystem::path& path, VkDev
return shaderModule;
}
void addDebugLabel(VkDevice device, VkImage image, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_IMAGE,
.objectHandle = (std::uint64_t)image,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkImageView imageView, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_IMAGE_VIEW,
.objectHandle = (std::uint64_t)imageView,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_SHADER_MODULE,
.objectHandle = (std::uint64_t)shaderModule,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkPipeline pipeline, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_PIPELINE,
.objectHandle = (std::uint64_t)pipeline,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkPipelineLayout layout, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_PIPELINE_LAYOUT,
.objectHandle = (std::uint64_t)layout,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkBuffer buffer, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (std::uint64_t)buffer,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
void addDebugLabel(VkDevice device, VkSampler sampler, const char* label) {
const auto nameInfo = VkDebugUtilsObjectNameInfoEXT{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_SAMPLER,
.objectHandle = (std::uint64_t)sampler,
.pObjectName = label,
};
if (vkSetDebugUtilsObjectNameEXT) vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
}
vkutil::RenderInfo createRenderingInfo(const vkutil::RenderingInfoParams& params) {
return vkutil::createRenderingInfo(params);
}