feat: basic shadow map + renderdoc labels
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user