Adding Pipeline statistics queries

This commit is contained in:
Dynamitos
2024-06-15 21:47:20 +02:00
parent 86c179e2e7
commit 0fd331b3b5
30 changed files with 344 additions and 95 deletions
@@ -87,6 +87,7 @@ void BasePass::render() {
opaqueCulling->writeChanges();
transparentCulling->writeChanges();
query->beginQuery();
graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands;
@@ -184,6 +185,7 @@ void BasePass::render() {
graphics->executeCommands(std::move(commands));
graphics->endRenderPass();
query->endQuery();
}
void BasePass::endFrame() {}
@@ -205,6 +207,9 @@ void BasePass::publishOutputs() {
Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
query = graphics->createPipelineStatisticsQuery();
resources->registerQueryOutput("BASEPASS_QUERY", query);
}
void BasePass::createRenderPass() {
@@ -35,6 +35,8 @@ class BasePass : public RenderPass {
Gfx::OPipelineLayout basePassLayout;
Gfx::ODescriptorLayout lightCullingLayout;
Gfx::OPipelineStatisticsQuery query;
Gfx::PShaderBuffer cullingBuffer;
};
DEFINE_REF(BasePass)
@@ -46,6 +46,7 @@ CachedDepthPass::~CachedDepthPass() {}
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
void CachedDepthPass::render() {
query->beginQuery();
graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands;
@@ -141,6 +142,7 @@ void CachedDepthPass::render() {
graphics->executeCommands(std::move(commands));
graphics->endRenderPass();
query->endQuery();
}
void CachedDepthPass::endFrame() {}
@@ -171,6 +173,8 @@ void CachedDepthPass::publishOutputs() {
Gfx::RenderTargetAttachment(visibilityBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
query = graphics->createPipelineStatisticsQuery();
resources->registerQueryOutput("CACHED_QUERY", query);
}
void CachedDepthPass::createRenderPass() {
@@ -21,6 +21,7 @@ class CachedDepthPass : public RenderPass {
Gfx::OTexture2D depthBuffer;
Gfx::OTexture2D visibilityBuffer;
Gfx::OPipelineLayout depthPrepassLayout;
Gfx::OPipelineStatisticsQuery query;
Gfx::PShaderBuffer cullingBuffer;
};
@@ -75,7 +75,7 @@ void DepthCullingPass::render() {
Gfx::PDescriptorSet set = depthTextureLayout->allocateDescriptorSet();
set->updateTexture(0, Gfx::PTexture2D(depthMipTexture));
set->writeChanges();
query->beginQuery();
graphics->beginRenderPass(renderPass);
if (useDepthCulling) {
@@ -173,6 +173,7 @@ void DepthCullingPass::render() {
graphics->executeCommands(std::move(commands));
}
graphics->endRenderPass();
query->endQuery();
// Sync depth read/write with compute read
depthAttachment.getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
@@ -192,6 +193,8 @@ void DepthCullingPass::publishOutputs() {
TextureCreateInfo depthMipInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT, .width = width, .height = height, .mipLevels = mipLevels, .name = "DepthMipTexture"};
depthMipTexture = graphics->createTexture2D(depthMipInfo);
query = graphics->createPipelineStatisticsQuery();
resources->registerQueryOutput("DEPTH_QUERY", query);
}
void DepthCullingPass::createRenderPass() {
@@ -22,6 +22,7 @@ class DepthCullingPass : public RenderPass {
Gfx::RenderTargetAttachment visibilityAttachment;
Gfx::ODescriptorLayout depthTextureLayout;
Gfx::OPipelineLayout depthPrepassLayout;
Gfx::OPipelineStatisticsQuery query;
Gfx::PShaderBuffer cullingBuffer;
};
@@ -40,6 +40,7 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) {
}
void LightCullingPass::render() {
query->beginQuery();
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
cullingDescriptorSet->updateTexture(0, depthAttachment);
cullingDescriptorSet->updateBuffer(1, oLightIndexCounter);
@@ -61,7 +62,7 @@ void LightCullingPass::render() {
commands.add(std::move(computeCommand));
// std::cout << "Execute" << std::endl;
graphics->executeCommands(std::move(commands));
query->endQuery();
oLightIndexList->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
tLightIndexList->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
@@ -212,7 +213,11 @@ void LightCullingPass::publishOutputs() {
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid));
}
void LightCullingPass::createRenderPass() { depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture(); }
void LightCullingPass::createRenderPass() {
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
query = graphics->createPipelineStatisticsQuery();
resources->registerQueryOutput("LIGHTCULL_QUERY", query);
}
void LightCullingPass::setupFrustums() {
uint32_t viewportWidth = viewport->getWidth();
@@ -1,4 +1,5 @@
#pragma once
#include "Graphics/Query.h"
#include "Graphics/Shader.h"
#include "RenderPass.h"
#include "Scene/Scene.h"
@@ -63,6 +64,7 @@ class LightCullingPass : public RenderPass {
Gfx::OComputeShader cullingEnabledShader;
Gfx::PComputePipeline cullingPipeline;
Gfx::PComputePipeline cullingEnabledPipeline;
Gfx::OPipelineStatisticsQuery query;
};
DEFINE_REF(LightCullingPass)
} // namespace Seele
+4 -1
View File
@@ -1,4 +1,5 @@
#pragma once
#include "RenderGraphResources.h"
#include "RenderPass.h"
namespace Seele {
@@ -33,7 +34,9 @@ class RenderGraph {
pass->endFrame();
}
}
PRenderGraphResources getResources() {
return res;
}
private:
PRenderGraphResources res;
List<ORenderPass> passes;
@@ -1,5 +1,7 @@
#include "RenderGraphResources.h"
#include "Graphics/Query.h"
#include <iostream>
#include <string>
using namespace Seele;
@@ -17,6 +19,8 @@ Gfx::PShaderBuffer RenderGraphResources::requestBuffer(const std::string& output
Gfx::PUniformBuffer RenderGraphResources::requestUniform(const std::string& outputName) { return registeredUniforms.at(outputName); }
Gfx::PPipelineStatisticsQuery RenderGraphResources::requestQuery(const std::string& outputName) { return registeredQueries.at(outputName); }
void RenderGraphResources::registerRenderPassOutput(const std::string& outputName, Gfx::RenderTargetAttachment attachment) {
registeredAttachments[outputName] = attachment;
}
@@ -30,4 +34,8 @@ void RenderGraphResources::registerBufferOutput(const std::string& outputName, G
}
void RenderGraphResources::registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer) {
registeredUniforms[outputName] = buffer;
}
void RenderGraphResources::registerQueryOutput(const std::string& outputName, Gfx::PPipelineStatisticsQuery query) {
registeredQueries[outputName] = query;
}
@@ -1,5 +1,6 @@
#pragma once
#include "Graphics/Buffer.h"
#include "Graphics/Query.h"
#include "Graphics/RenderTarget.h"
#include "Graphics/Texture.h"
#include "MinimalEngine.h"
@@ -16,16 +17,19 @@ class RenderGraphResources {
Gfx::PTexture requestTexture(const std::string& outputName);
Gfx::PShaderBuffer requestBuffer(const std::string& outputName);
Gfx::PUniformBuffer requestUniform(const std::string& outputName);
Gfx::PPipelineStatisticsQuery requestQuery(const std::string& outputName);
void registerRenderPassOutput(const std::string& outputName, Gfx::RenderTargetAttachment attachment);
void registerTextureOutput(const std::string& outputName, Gfx::PTexture buffer);
void registerBufferOutput(const std::string& outputName, Gfx::PShaderBuffer buffer);
void registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer);
void registerQueryOutput(const std::string& outputName, Gfx::PPipelineStatisticsQuery query);
protected:
Map<std::string, Gfx::RenderTargetAttachment> registeredAttachments;
Map<std::string, Gfx::PTexture> registeredTextures;
Map<std::string, Gfx::PShaderBuffer> registeredBuffers;
Map<std::string, Gfx::PUniformBuffer> registeredUniforms;
Map<std::string, Gfx::PPipelineStatisticsQuery> registeredQueries;
};
DEFINE_REF(RenderGraphResources)
} // namespace Seele
@@ -3,13 +3,12 @@
#include "Graphics/Command.h"
#include "Graphics/Graphics.h"
using namespace Seele;
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
skybox = Seele::Component::Skybox{
//.day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast<Gfx::TextureCube>(),
//.night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast<Gfx::TextureCube>(),
.day = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
.night = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
.fogColor = Vector(0.1, 0.1, 0.8),
.blendFactor = 0,
};
@@ -86,14 +85,41 @@ void SkyboxRenderPass::publishOutputs() {
void SkyboxRenderPass::createRenderPass() {
colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
// colorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
// depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
// Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout{
// .colorAttachments = { colorAttachment },
// .depthAttachment = depthAttachment
// };
// renderPass = graphics->createRenderPass(std::move(layout), viewport);
colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
depthAttachment = resources->requestRenderTarget("BASEPASS_DEPTH");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = {colorAttachment},
.depthAttachment = depthAttachment,
};
Array<Gfx::SubPassDependency> dependency = {
{
.srcSubpass = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport);
skyboxData.transformMatrix = Matrix4(1);
skyboxData.fogColor = skybox.fogColor;
@@ -108,10 +134,16 @@ void SkyboxRenderPass::createRenderPass() {
.dynamic = true,
});
pipelineLayout = graphics->createPipelineLayout("SkyboxLayout");
pipelineLayout->addDescriptorLayout(viewParamsLayout);
pipelineLayout->addDescriptorLayout(skyboxDataLayout);
pipelineLayout->addDescriptorLayout(textureLayout);
ShaderCreateInfo createInfo = {
.name = "SkyboxVertex",
.mainModule = "Skybox",
.entryPoint = "vertexMain",
.rootSignature = pipelineLayout,
};
vertexShader = graphics->createVertexShader(createInfo);
@@ -119,19 +151,26 @@ void SkyboxRenderPass::createRenderPass() {
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
pipelineLayout = graphics->createPipelineLayout("SkyboxLayout");
pipelineLayout->addDescriptorLayout(viewParamsLayout);
pipelineLayout->addDescriptorLayout(skyboxDataLayout);
pipelineLayout->addDescriptorLayout(textureLayout);
pipelineLayout->create();
Gfx::LegacyPipelineCreateInfo gfxInfo;
gfxInfo.vertexShader = vertexShader;
gfxInfo.fragmentShader = fragmentShader;
gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL;
gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
gfxInfo.pipelineLayout = pipelineLayout;
gfxInfo.renderPass = renderPass;
gfxInfo.multisampleState.samples = viewport->getSamples();
Gfx::LegacyPipelineCreateInfo gfxInfo = {
.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
.vertexShader = vertexShader,
.fragmentShader = fragmentShader,
.renderPass = renderPass,
.pipelineLayout = pipelineLayout,
.multisampleState =
{
.samples = viewport->getSamples(),
},
.rasterizationState =
{
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
},
.colorBlend =
{
.attachmentCount = 1,
},
};
pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo));
}
@@ -27,6 +27,7 @@ void VisibilityPass::render() {
visibilitySet->updateBuffer(1, cullingBuffer);
visibilitySet->writeChanges();
query->beginQuery();
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
command->bindPipeline(visibilityPipeline);
command->bindDescriptor({viewParamsSet, visibilitySet});
@@ -34,6 +35,7 @@ void VisibilityPass::render() {
Array<Gfx::OComputeCommand> commands;
commands.add(std::move(command));
graphics->executeCommands(std::move(commands));
query->endQuery();
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
@@ -77,6 +79,9 @@ void VisibilityPass::publishOutputs() {
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.dynamic = true, .name = "CullingBuffer"});
resources->registerBufferOutput("CULLINGBUFFER", cullingBuffer);
query = graphics->createPipelineStatisticsQuery();
resources->registerQueryOutput("VISIBILITY_QUERY", query);
}
void VisibilityPass::createRenderPass() { visibilityAttachment = resources->requestRenderTarget("VISIBILITY"); }
@@ -1,4 +1,5 @@
#pragma once
#include "Graphics/Query.h"
#include "RenderPass.h"
namespace Seele {
@@ -22,6 +23,7 @@ class VisibilityPass : public RenderPass {
Gfx::OPipelineLayout visibilityLayout;
Gfx::OComputeShader visibilityShader;
Gfx::PComputePipeline visibilityPipeline;
Gfx::OPipelineStatisticsQuery query;
// Holds culling information for every meshlet for each instance
Gfx::OShaderBuffer cullingBuffer;