Adding Pipeline statistics queries
This commit is contained in:
@@ -89,7 +89,7 @@ struct TextureData
|
||||
SamplerState sampler;
|
||||
};
|
||||
layout(set=2)
|
||||
ParameterBlock<TextureData> pTextures;
|
||||
ParameterBlock<TextureData> pSkyboxTextures;
|
||||
static const float lowerLimit = 0.0;
|
||||
static const float upperLimit = 0.1;
|
||||
|
||||
@@ -97,8 +97,8 @@ static const float upperLimit = 0.1;
|
||||
float4 fragmentMain(
|
||||
VertexShaderOutput output) : SV_Target
|
||||
{
|
||||
float4 texture1 = pTextures.cubeMap.Sample(pTextures.sampler, output.texCoords);
|
||||
float4 texture2 = pTextures.cubeMap2.Sample(pTextures.sampler, output.texCoords);
|
||||
float4 texture1 = pSkyboxTextures.cubeMap.Sample(pSkyboxTextures.sampler, output.texCoords);
|
||||
float4 texture2 = pSkyboxTextures.cubeMap2.Sample(pSkyboxTextures.sampler, output.texCoords);
|
||||
float4 finalColor = lerp(texture1, texture2, pSkyboxData.fogBlend.w);
|
||||
|
||||
float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit);
|
||||
|
||||
@@ -64,6 +64,9 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) {
|
||||
ss << "toktx --encode etc1s ";
|
||||
if (args.type == TextureImportType::TEXTURE_NORMAL) {
|
||||
// ss << "--normal_mode ";
|
||||
}
|
||||
if (args.type == TextureImportType::TEXTURE_CUBEMAP) {
|
||||
|
||||
}
|
||||
ss << ktxFile << " " << args.filePath;
|
||||
system(ss.str().c_str());
|
||||
|
||||
@@ -59,6 +59,10 @@ int main() {
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import/models/cube.fbx",
|
||||
});
|
||||
AssetImporter::importTexture(TextureImportArgs{
|
||||
.filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg",
|
||||
.type = TextureImportType::TEXTURE_CUBEMAP,
|
||||
});
|
||||
// AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import/models/greek-temple/source/greek-temple.fbx",
|
||||
// .importPath = "temple"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Containers/Array.h"
|
||||
#include "Initializer.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Query.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
|
||||
@@ -81,6 +82,7 @@ class Graphics {
|
||||
virtual OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) = 0;
|
||||
|
||||
virtual Gfx::OOcclusionQuery createOcclusionQuery() = 0;
|
||||
virtual Gfx::OPipelineStatisticsQuery createPipelineStatisticsQuery() = 0;
|
||||
|
||||
virtual void resolveTexture(PTexture source, PTexture destination) = 0;
|
||||
virtual void copyTexture(PTexture src, PTexture dst) = 0;
|
||||
|
||||
@@ -35,5 +35,9 @@ class ComputePipeline {
|
||||
PPipelineLayout layout;
|
||||
};
|
||||
DEFINE_REF(ComputePipeline)
|
||||
class PipelineLibrary {
|
||||
|
||||
};
|
||||
DEFINE_REF(PipelineLibrary)
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -7,4 +7,10 @@ OcclusionQuery::OcclusionQuery()
|
||||
{}
|
||||
|
||||
OcclusionQuery::~OcclusionQuery()
|
||||
{}
|
||||
|
||||
PipelineStatisticsQuery::PipelineStatisticsQuery()
|
||||
{}
|
||||
|
||||
PipelineStatisticsQuery::~PipelineStatisticsQuery()
|
||||
{}
|
||||
@@ -3,17 +3,37 @@
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
struct OcclusionResult {
|
||||
uint64 numFragments;
|
||||
};
|
||||
class OcclusionQuery {
|
||||
public:
|
||||
OcclusionQuery();
|
||||
virtual ~OcclusionQuery();
|
||||
virtual void beginQuery() = 0;
|
||||
virtual void endQuery() = 0;
|
||||
virtual void resetQuery() = 0;
|
||||
virtual uint64 getResults() = 0;
|
||||
|
||||
private:
|
||||
virtual OcclusionResult getResults() = 0;
|
||||
};
|
||||
DEFINE_REF(OcclusionQuery)
|
||||
struct PipelineStatisticsResult {
|
||||
uint64 inputAssemblyVertices;
|
||||
uint64 inputAssemblyPrimitives;
|
||||
uint64 vertexShaderInvocations;
|
||||
uint64 clippingInvocations;
|
||||
uint64 clippingPrimitives;
|
||||
uint64 fragmentShaderInvocations;
|
||||
uint64 computeShaderInvocations;
|
||||
uint64 taskShaderInvocations;
|
||||
uint64 meshShaderInvocations;
|
||||
};
|
||||
class PipelineStatisticsQuery {
|
||||
public:
|
||||
PipelineStatisticsQuery();
|
||||
virtual ~PipelineStatisticsQuery();
|
||||
virtual void beginQuery() = 0;
|
||||
virtual void endQuery() = 0;
|
||||
virtual PipelineStatisticsResult getResults() = 0;
|
||||
};
|
||||
DEFINE_REF(PipelineStatisticsQuery)
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -160,7 +160,7 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void
|
||||
|
||||
uint8* data;
|
||||
VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data));
|
||||
std::memcpy(buffer, data + regionOffset, regionSize);
|
||||
std::memcpy(ptr, data + regionOffset, regionSize);
|
||||
VK_CHECK(vmaFlushAllocation(graphics->getAllocator(), staging->allocation, regionOffset, regionSize));
|
||||
vmaUnmapMemory(graphics->getAllocator(), staging->allocation);
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging));
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Command::Command(PGraphics graphics, PCommandPool pool) : graphics(graphics), pool(pool) {
|
||||
Command::Command(PGraphics graphics, PCommandPool pool) : graphics(graphics), pool(pool), statisticsFlags(0) {
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -151,6 +151,9 @@ void Command::waitForCommand(uint32 timeout) {
|
||||
checkFence();
|
||||
}
|
||||
|
||||
void Command::setPipelineStatisticsFlags(VkQueryPipelineStatisticFlags flags)
|
||||
{ statisticsFlags = flags; }
|
||||
|
||||
void Command::bindResource(PCommandBoundResource resource) {
|
||||
resource->bind();
|
||||
boundResources.add(resource);
|
||||
@@ -173,7 +176,7 @@ RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool) : graphi
|
||||
|
||||
RenderCommand::~RenderCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
|
||||
|
||||
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer) {
|
||||
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer, VkQueryPipelineStatisticFlags pipelineFlags) {
|
||||
threadId = std::this_thread::get_id();
|
||||
ready = false;
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo = {
|
||||
@@ -181,9 +184,9 @@ void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer) {
|
||||
.renderPass = renderPass->getHandle(),
|
||||
.subpass = 0,
|
||||
.framebuffer = framebuffer->getHandle(),
|
||||
.occlusionQueryEnable = 1,
|
||||
.queryFlags = VK_QUERY_CONTROL_PRECISE_BIT,
|
||||
.pipelineStatistics = 0,
|
||||
.occlusionQueryEnable = 0,
|
||||
.queryFlags = 0,
|
||||
.pipelineStatistics = pipelineFlags,
|
||||
};
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
@@ -323,7 +326,7 @@ ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : grap
|
||||
|
||||
ComputeCommand::~ComputeCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
|
||||
|
||||
void ComputeCommand::begin() {
|
||||
void ComputeCommand::begin(VkQueryPipelineStatisticFlags pipelineFlags) {
|
||||
threadId = std::this_thread::get_id();
|
||||
ready = false;
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo = {
|
||||
@@ -333,7 +336,7 @@ void ComputeCommand::begin() {
|
||||
.framebuffer = VK_NULL_HANDLE,
|
||||
.occlusionQueryEnable = 0,
|
||||
.queryFlags = 0,
|
||||
.pipelineStatistics = 0,
|
||||
.pipelineStatistics = pipelineFlags,
|
||||
};
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
@@ -440,6 +443,7 @@ CommandPool::~CommandPool() {
|
||||
}
|
||||
|
||||
PCommand CommandPool::getCommands() { return command; }
|
||||
|
||||
void CommandPool::cacheCommands(Array<ORenderCommand> commands) {
|
||||
for (auto&& cmd : commands) {
|
||||
allocatedRenderCommands.add(std::move(cmd));
|
||||
@@ -458,13 +462,13 @@ ORenderCommand CommandPool::createRenderCommand(const std::string& name) {
|
||||
ORenderCommand cmdBuffer = std::move(allocatedRenderCommands[i]);
|
||||
allocatedRenderCommands.removeAt(i, false);
|
||||
cmdBuffer->name = name;
|
||||
cmdBuffer->begin(command->boundRenderPass, command->boundFramebuffer);
|
||||
cmdBuffer->begin(command->boundRenderPass, command->boundFramebuffer, command->statisticsFlags);
|
||||
return cmdBuffer;
|
||||
}
|
||||
}
|
||||
ORenderCommand result = new RenderCommand(graphics, commandPool);
|
||||
result->name = name;
|
||||
result->begin(command->boundRenderPass, command->boundFramebuffer);
|
||||
result->begin(command->boundRenderPass, command->boundFramebuffer, command->statisticsFlags);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -474,13 +478,13 @@ OComputeCommand CommandPool::createComputeCommand(const std::string& name) {
|
||||
OComputeCommand cmdBuffer = std::move(allocatedComputeCommands[i]);
|
||||
allocatedComputeCommands.removeAt(i, false);
|
||||
cmdBuffer->name = name;
|
||||
cmdBuffer->begin();
|
||||
cmdBuffer->begin(command->statisticsFlags);
|
||||
return cmdBuffer;
|
||||
}
|
||||
}
|
||||
OComputeCommand result = new ComputeCommand(graphics, commandPool);
|
||||
result->name = name;
|
||||
result->begin();
|
||||
result->begin(command->statisticsFlags);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class Command {
|
||||
void bindResource(PCommandBoundResource resource);
|
||||
void checkFence();
|
||||
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||
void setPipelineStatisticsFlags(VkQueryPipelineStatisticFlags flags);
|
||||
PFence getFence();
|
||||
PCommandPool getPool();
|
||||
enum State {
|
||||
@@ -55,6 +56,7 @@ class Command {
|
||||
Array<ORenderCommand> executingRenders;
|
||||
Array<OComputeCommand> executingComputes;
|
||||
Array<PDescriptorSet> boundResources;
|
||||
VkQueryPipelineStatisticFlags statisticsFlags;
|
||||
friend class RenderCommand;
|
||||
friend class CommandPool;
|
||||
friend class Queue;
|
||||
@@ -68,7 +70,7 @@ class RenderCommand : public Gfx::RenderCommand {
|
||||
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~RenderCommand();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void begin(PRenderPass renderPass, PFramebuffer framebuffer, VkQueryPipelineStatisticFlags pipelineFlags);
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
@@ -103,7 +105,7 @@ class ComputeCommand : public Gfx::ComputeCommand {
|
||||
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~ComputeCommand();
|
||||
inline VkCommandBuffer getHandle() { return handle; }
|
||||
void begin();
|
||||
void begin(VkQueryPipelineStatisticFlags pipelineFlags);
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
|
||||
@@ -233,6 +233,8 @@ Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createI
|
||||
|
||||
Gfx::OOcclusionQuery Graphics::createOcclusionQuery() { return new OcclusionQuery(this); }
|
||||
|
||||
Gfx::OPipelineStatisticsQuery Graphics::createPipelineStatisticsQuery() { return new PipelineStatisticsQuery(this); }
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
PTextureBase sourceTex = source.cast<TextureBase>();
|
||||
PTextureBase destinationTex = destination.cast<TextureBase>();
|
||||
@@ -287,16 +289,8 @@ void Graphics::copyTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
},
|
||||
.srcOffsets =
|
||||
{
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
{
|
||||
(int32)src->getWidth(),
|
||||
(int32)src->getHeight(),
|
||||
(int32)src->getDepth(),
|
||||
},
|
||||
{0, 0, 0},
|
||||
{(int32)src->getWidth(), (int32)src->getHeight(), (int32)src->getDepth()},
|
||||
},
|
||||
.dstSubresource =
|
||||
{
|
||||
@@ -307,16 +301,8 @@ void Graphics::copyTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
},
|
||||
.dstOffsets =
|
||||
{
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
{
|
||||
(int32)dst->getWidth(),
|
||||
(int32)dst->getHeight(),
|
||||
(int32)dst->getDepth(),
|
||||
},
|
||||
{0, 0, 0},
|
||||
{(int32)dst->getWidth(), (int32)dst->getHeight(), (int32)dst->getDepth()},
|
||||
},
|
||||
};
|
||||
PCommand command = getGraphicsCommands()->getCommands();
|
||||
@@ -517,6 +503,7 @@ void Graphics::pickPhysicalDevice() {
|
||||
.fillModeNonSolid = true,
|
||||
.wideLines = true,
|
||||
.occlusionQueryPrecise = true,
|
||||
.pipelineStatisticsQuery = true,
|
||||
.fragmentStoresAndAtomics = true,
|
||||
.shaderInt64 = true,
|
||||
.inheritedQueries = true,
|
||||
|
||||
@@ -68,6 +68,7 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) override;
|
||||
|
||||
virtual Gfx::OOcclusionQuery createOcclusionQuery() override;
|
||||
virtual Gfx::OPipelineStatisticsQuery createPipelineStatisticsQuery() override;
|
||||
|
||||
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
|
||||
virtual void copyTexture(Gfx::PTexture src, Gfx::PTexture dst) override;
|
||||
|
||||
@@ -1,32 +1,116 @@
|
||||
#include "Query.h"
|
||||
#include "Buffer.h"
|
||||
#include "Command.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Query.h"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
OcclusionQuery::OcclusionQuery(PGraphics graphics) :graphics(graphics){
|
||||
QueryPool::QueryPool(PGraphics graphics, VkQueryType type, VkQueryPipelineStatisticFlags flags, uint32 resultsStride, uint32 numBuffered)
|
||||
: graphics(graphics), flags(flags), numQueries(numBuffered), resultsStride(resultsStride) {
|
||||
VkQueryPoolCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.queryType = VK_QUERY_TYPE_OCCLUSION,
|
||||
.queryCount = 1,
|
||||
.pipelineStatistics = 0,
|
||||
.queryType = type,
|
||||
.queryCount = numBuffered,
|
||||
.pipelineStatistics = flags,
|
||||
};
|
||||
VK_CHECK(vkCreateQueryPool(graphics->getDevice(), &info, nullptr, &handle));
|
||||
//VkBufferCreateInfo bufferInfo = {
|
||||
// .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
// .pNext = nullptr,
|
||||
// .flags = 0,
|
||||
// .size = (resultsStride + 1) * numQueries * sizeof(uint64),
|
||||
// .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
//};
|
||||
//VmaAllocationCreateInfo allocInfo = {
|
||||
// .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
|
||||
// .usage = VMA_MEMORY_USAGE_AUTO,
|
||||
// .requiredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
//};
|
||||
//resultsAlloc = new BufferAllocation(graphics, "QueryResults", bufferInfo, allocInfo, Gfx::QueueType::GRAPHICS);
|
||||
//VK_CHECK(vmaMapMemory(graphics->getAllocator(), resultsAlloc->allocation, (void**) & resultsPtr));
|
||||
}
|
||||
|
||||
OcclusionQuery::~OcclusionQuery() { vkDestroyQueryPool(graphics->getDevice(), handle, nullptr); }
|
||||
QueryPool::~QueryPool() { vkDestroyQueryPool(graphics->getDevice(), handle, nullptr); }
|
||||
|
||||
void OcclusionQuery::beginQuery() { vkCmdBeginQuery(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, 0, VK_QUERY_CONTROL_PRECISE_BIT); }
|
||||
void QueryPool::begin() {
|
||||
vkCmdResetQueryPool(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, currentQuery, 1);
|
||||
vkCmdBeginQuery(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, currentQuery, 0);
|
||||
graphics->getGraphicsCommands()->getCommands()->setPipelineStatisticsFlags(flags);
|
||||
}
|
||||
|
||||
void OcclusionQuery::endQuery() { vkCmdEndQuery(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, 0); }
|
||||
|
||||
void OcclusionQuery::resetQuery() { vkCmdResetQueryPool(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, 0, 1); }
|
||||
|
||||
uint64 OcclusionQuery::getResults() {
|
||||
void QueryPool::end() {
|
||||
vkCmdEndQuery(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, currentQuery);
|
||||
//vkCmdCopyQueryPoolResults(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, currentQuery, 1, resultsAlloc->buffer,
|
||||
// sizeof(uint64) * currentQuery, resultsStride + sizeof(uint64),
|
||||
// VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
uint64 result;
|
||||
vkGetQueryPoolResults(graphics->getDevice(), handle, 0, 1, sizeof(uint64), &result, sizeof(uint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
|
||||
return result;
|
||||
currentQuery = (currentQuery + 1) % numQueries;
|
||||
}
|
||||
|
||||
void QueryPool::getQueryResults(Array<uint64>& results) {
|
||||
//uint64 numInts = resultsStride / sizeof(uint64);
|
||||
while (currentQuery == pendingQuery)
|
||||
;
|
||||
results.resize(resultsStride/ sizeof(uint64));
|
||||
vkGetQueryPoolResults(graphics->getDevice(), handle, pendingQuery, 1, resultsStride, results.data(), resultsStride,
|
||||
VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
|
||||
//uint64* currentPtr = resultsPtr + (pendingQuery * (numInts + 1));
|
||||
//std::cout << pendingQuery << *(currentPtr + numInts) << std::endl;
|
||||
//std::memcpy(results.data(), currentPtr, resultsStride);
|
||||
pendingQuery = (pendingQuery + 1) % numQueries;
|
||||
}
|
||||
|
||||
OcclusionQuery::OcclusionQuery(PGraphics graphics) : QueryPool(graphics, VK_QUERY_TYPE_OCCLUSION, 0, sizeof(uint64), 16) {}
|
||||
|
||||
OcclusionQuery::~OcclusionQuery() {}
|
||||
|
||||
void OcclusionQuery::beginQuery() { begin(); }
|
||||
|
||||
void OcclusionQuery::endQuery() { end(); }
|
||||
|
||||
Gfx::OcclusionResult OcclusionQuery::getResults() {
|
||||
Array<uint64> result(1);
|
||||
getQueryResults(result);
|
||||
return Gfx::OcclusionResult{
|
||||
.numFragments = result[0],
|
||||
};
|
||||
}
|
||||
|
||||
PipelineStatisticsQuery::PipelineStatisticsQuery(PGraphics graphics)
|
||||
: QueryPool(graphics, VK_QUERY_TYPE_PIPELINE_STATISTICS,
|
||||
VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT,
|
||||
sizeof(PipelineStatisticsQuery), 16) {}
|
||||
|
||||
PipelineStatisticsQuery::~PipelineStatisticsQuery() {}
|
||||
|
||||
void PipelineStatisticsQuery::beginQuery() { begin(); }
|
||||
|
||||
void PipelineStatisticsQuery::endQuery() { end(); }
|
||||
|
||||
Gfx::PipelineStatisticsResult PipelineStatisticsQuery::getResults() {
|
||||
Array<uint64> result(9);
|
||||
getQueryResults(result);
|
||||
return Gfx::PipelineStatisticsResult{
|
||||
.inputAssemblyVertices = result[0],
|
||||
.inputAssemblyPrimitives = result[1],
|
||||
.vertexShaderInvocations = result[2],
|
||||
.clippingInvocations = result[3],
|
||||
.clippingPrimitives = result[4],
|
||||
.fragmentShaderInvocations = result[5],
|
||||
.computeShaderInvocations = result[6],
|
||||
.taskShaderInvocations = result[7],
|
||||
.meshShaderInvocations = result[8],
|
||||
};
|
||||
}
|
||||
@@ -1,22 +1,48 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Query.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
class OcclusionQuery : public Gfx::OcclusionQuery {
|
||||
class QueryPool {
|
||||
public:
|
||||
QueryPool(PGraphics graphics, VkQueryType type, VkQueryPipelineStatisticFlags flags, uint32 resultsStride, uint32 numBuffered);
|
||||
virtual ~QueryPool();
|
||||
void begin();
|
||||
void end();
|
||||
// stalls for the currently first pending query, dont call in render thread
|
||||
void getQueryResults(Array<uint64>& results);
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
VkQueryPool handle;
|
||||
VkQueryPipelineStatisticFlags flags;
|
||||
OBufferAllocation resultsAlloc;
|
||||
uint64* resultsPtr;
|
||||
uint32 pendingQuery = 0;
|
||||
uint32 currentQuery = 0;
|
||||
uint32 numQueries;
|
||||
uint32 resultsStride;
|
||||
};
|
||||
class OcclusionQuery : public Gfx::OcclusionQuery, public QueryPool {
|
||||
public:
|
||||
OcclusionQuery(PGraphics graphics);
|
||||
virtual ~OcclusionQuery();
|
||||
virtual void beginQuery() override;
|
||||
virtual void endQuery() override;
|
||||
virtual void resetQuery() override;
|
||||
virtual uint64 getResults() override;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkQueryPool handle;
|
||||
virtual Gfx::OcclusionResult getResults() override;
|
||||
};
|
||||
DEFINE_REF(OcclusionQuery)
|
||||
class PipelineStatisticsQuery : public Gfx::PipelineStatisticsQuery, public QueryPool {
|
||||
public:
|
||||
PipelineStatisticsQuery(PGraphics graphics);
|
||||
virtual ~PipelineStatisticsQuery();
|
||||
virtual void beginQuery() override;
|
||||
virtual void endQuery() override;
|
||||
virtual Gfx::PipelineStatisticsResult getResults() override;
|
||||
};
|
||||
DEFINE_REF(PipelineStatisticsQuery)
|
||||
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -3,13 +3,15 @@
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Component/KeyboardInput.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||
#include "Graphics/RenderPass/DepthCullingPass.h"
|
||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||
#include "Graphics/Query.h"
|
||||
#include "Graphics/RenderPass/BasePass.h"
|
||||
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
||||
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||
#include "Graphics/RenderPass/DebugPass.h"
|
||||
#include "Graphics/RenderPass/DepthCullingPass.h"
|
||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||
#include "Graphics/RenderPass/RenderGraphResources.h"
|
||||
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||
#include "System/CameraUpdater.h"
|
||||
#include "System/LightGather.h"
|
||||
#include "System/MeshUpdater.h"
|
||||
@@ -30,9 +32,28 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||
renderGraph.addPass(new BasePass(graphics, scene));
|
||||
renderGraph.addPass(new DebugPass(graphics, scene));
|
||||
// renderGraph.addPass(new SkyboxRenderPass(graphics, scene));
|
||||
// renderGraph.addPass(new SkyboxRenderPass(graphics, scene));
|
||||
renderGraph.setViewport(viewport);
|
||||
renderGraph.createRenderPass();
|
||||
queryThread = std::thread([&]() {
|
||||
PRenderGraphResources res = renderGraph.getResources();
|
||||
Gfx::PPipelineStatisticsQuery cachedQuery = res->requestQuery("CACHED_QUERY");
|
||||
Gfx::PPipelineStatisticsQuery depthQuery = res->requestQuery("DEPTH_QUERY");
|
||||
Gfx::PPipelineStatisticsQuery baseQuery = res->requestQuery("BASEPASS_QUERY");
|
||||
Gfx::PPipelineStatisticsQuery lightCullQuery = res->requestQuery("LIGHTCULL_QUERY");
|
||||
Gfx::PPipelineStatisticsQuery visibilityQuery = res->requestQuery("VISIBILITY_QUERY");
|
||||
while (true) {
|
||||
auto cachedResults = cachedQuery->getResults();
|
||||
auto depthResults = depthQuery->getResults();
|
||||
auto baseResults = baseQuery->getResults();
|
||||
auto lightCullResults = lightCullQuery->getResults();
|
||||
auto visiblityResults = visibilityQuery->getResults();
|
||||
std::cout << "Pipeline Stats: "
|
||||
<< cachedResults.meshShaderInvocations + depthResults.meshShaderInvocations + baseResults.meshShaderInvocations +
|
||||
lightCullResults.meshShaderInvocations + visiblityResults.meshShaderInvocations
|
||||
<< std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GameView::~GameView() {}
|
||||
|
||||
@@ -28,6 +28,7 @@ class GameView : public View {
|
||||
OScene scene;
|
||||
GameInterface gameInterface;
|
||||
RenderGraph renderGraph;
|
||||
std::thread queryThread;
|
||||
|
||||
PSystemGraph systemGraph;
|
||||
System::PKeyboardInput keyboardSystem;
|
||||
|
||||
Reference in New Issue
Block a user