Apparently it is still not working???
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
subprocess.run(['build/Benchmark.exe'])
|
||||||
|
subprocess.run(['build/Benchmark.exe', 'NOCULL'])
|
||||||
@@ -78,30 +78,28 @@ void taskMain(
|
|||||||
uint threadID: SV_GroupThreadID,
|
uint threadID: SV_GroupThreadID,
|
||||||
uint groupID: SV_GroupID, )
|
uint groupID: SV_GroupID, )
|
||||||
{
|
{
|
||||||
if (threadID == 0)
|
head = 0;
|
||||||
{
|
instance = pScene.instances[pOffsets.instanceOffset + groupID];
|
||||||
head = 0;
|
mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
||||||
instance = pScene.instances[pOffsets.instanceOffset + groupID];
|
p.instanceId = pOffsets.instanceOffset + groupID;
|
||||||
mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
p.meshletOffset = mesh.meshletOffset;
|
||||||
p.instanceId = pOffsets.instanceOffset + groupID;
|
p.cullingOffset = pScene.cullingOffsets[p.instanceId];
|
||||||
p.meshletOffset = mesh.meshletOffset;
|
modelViewProjection = mul(mul(pViewParams.projectionMatrix, pViewParams.viewMatrix), instance.transformMatrix);
|
||||||
p.cullingOffset = pScene.cullingOffsets[p.instanceId];
|
float3 origin = viewToModel(instance.inverseTransformMatrix, float4(0, 0, 0, 1)).xyz;
|
||||||
modelViewProjection = mul(mul(pViewParams.projectionMatrix, pViewParams.viewMatrix), instance.transformMatrix);
|
const float offset = 0.0f;
|
||||||
float3 origin = viewToModel(instance.inverseTransformMatrix, float4(0, 0, 0, 1)).xyz;
|
float3 corners[4] = {
|
||||||
const float offset = 0.0f;
|
screenToModel(instance.inverseTransformMatrix, float4(offset, offset, -1.0f, 1.0f)).xyz,
|
||||||
float3 corners[4] = {
|
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions.x - offset, offset, -1.0f, 1.0f)).xyz,
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(offset, offset, -1.0f, 1.0f)).xyz,
|
screenToModel(instance.inverseTransformMatrix, float4(offset, pViewParams.screenDimensions.y - offset, -1.0f, 1.0f)).xyz,
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions.x - offset, offset, -1.0f, 1.0f)).xyz,
|
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions - float2(offset, offset), -1.0f, 1.0f)).xyz
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(offset, pViewParams.screenDimensions.y - offset, -1.0f, 1.0f)).xyz,
|
};
|
||||||
screenToModel(instance.inverseTransformMatrix, float4(pViewParams.screenDimensions - float2(offset, offset), -1.0f, 1.0f)).xyz
|
viewFrustum.sides[0] = computePlane(origin, corners[2], corners[0]);
|
||||||
};
|
viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]);
|
||||||
viewFrustum.sides[0] = computePlane(origin, corners[2], corners[0]);
|
viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]);
|
||||||
viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]);
|
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
||||||
viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]);
|
meshVisible = mesh.bounding.insideFrustum(viewFrustum) && isBoxVisible(mesh.bounding);
|
||||||
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
//meshVisible = true;
|
||||||
//meshVisible = isBoxVisible(mesh.bounding);
|
|
||||||
meshVisible = true;
|
|
||||||
}
|
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
if(!meshVisible)
|
if(!meshVisible)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ float4 clipToScreen(float4 clip)
|
|||||||
float oz = 1;
|
float oz = 1;
|
||||||
float pz = 0 - 1;
|
float pz = 0 - 1;
|
||||||
float zf = pz * ndc.z + oz;
|
float zf = pz * ndc.z + oz;
|
||||||
return float4(float2(texCoords.x, 1 - texCoords.y) * pViewParams.screenDimensions, zf, 1.0f);
|
return float4(float2(texCoords.x, 1 - texCoords.y) * pViewParams.screenDimensions, 1 / zf, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Plane
|
struct Plane
|
||||||
|
|||||||
+22
-24
@@ -15,44 +15,42 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
|||||||
Gfx::PPipelineStatisticsQuery baseQuery = res->requestQuery("BASEPASS_QUERY");
|
Gfx::PPipelineStatisticsQuery baseQuery = res->requestQuery("BASEPASS_QUERY");
|
||||||
Gfx::PPipelineStatisticsQuery lightCullQuery = res->requestQuery("LIGHTCULL_QUERY");
|
Gfx::PPipelineStatisticsQuery lightCullQuery = res->requestQuery("LIGHTCULL_QUERY");
|
||||||
Gfx::PPipelineStatisticsQuery visibilityQuery = res->requestQuery("VISIBILITY_QUERY");
|
Gfx::PPipelineStatisticsQuery visibilityQuery = res->requestQuery("VISIBILITY_QUERY");
|
||||||
Gfx::PTimestampQuery cachedTS = res->requestTimestampQuery("CACHED_TS");
|
Gfx::PTimestampQuery timestamps = res->requestTimestampQuery("TIMESTAMPS");
|
||||||
Gfx::PTimestampQuery depthTS = res->requestTimestampQuery("DEPTH_TS");
|
|
||||||
Gfx::PTimestampQuery lightCullTS = res->requestTimestampQuery("LIGHTCULL_TS");
|
|
||||||
Gfx::PTimestampQuery visibilityTS = res->requestTimestampQuery("VISIBILITY_TS");
|
|
||||||
Gfx::PTimestampQuery baseTS = res->requestTimestampQuery("BASE_TS");
|
|
||||||
std::ofstream stats(fmt::format("stats{}.csv", useMeshCulling ? "" : "NOCULL"));
|
std::ofstream stats(fmt::format("stats{}.csv", useMeshCulling ? "" : "NOCULL"));
|
||||||
stats << "RelTime,"
|
stats << "RelTime,"
|
||||||
<< "CACHED,MIPGEN,DEPTHCULL,VISIBILITY,LIGHTCULL,BASE,FrameTime,"
|
<< "CACHED,MIPGEN,DEPTHCULL,VISIBILITY,LIGHTCULL,BASE,FrameTime,"
|
||||||
<< "CachedIAV,CachedIAP,CachedVS,CachedClipInv,CachedClipPrim,CachedFS,CachedCS,"
|
<< "CachedIAV,CachedIAP,CachedVS,CachedClipInv,CachedClipPrim,CachedFS,CachedCS,CachedTS,CachedMS,"
|
||||||
<< "DepthIAV,DepthIAP,DepthVS,DepthClipInv,DepthClipPrim,DepthFS,DepthCS,"
|
<< "DepthIAV,DepthIAP,DepthVS,DepthClipInv,DepthClipPrim,DepthFS,DepthCS,DepthTS,DepthMS,"
|
||||||
<< "BaseIAV,BaseIAP,BaseVS,BaseClipInv,BaseClipPrim,BaseFS,BaseCS,"
|
<< "BaseIAV,BaseIAP,BaseVS,BaseClipInv,BaseClipPrim,BaseFS,BaseCS,BaseTS,BaseMS,"
|
||||||
<< "LightCullIAV,LightCullIAP,LightCullVS,LightCullClipInv,LightCullClipPrim,LightCullFS,LightCullCS,"
|
<< "LightCullIAV,LightCullIAP,LightCullVS,LightCullClipInv,LightCullClipPrim,LightCullFS,LightCullCS,LightCullTS,LightCullMS,"
|
||||||
<< "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS" << std::endl;
|
<< "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS,VisibilityMS,VisibilityMS," << std::endl;
|
||||||
uint64 start = 0;
|
uint64 start = 0;
|
||||||
uint64 prevBegin = 0;
|
uint64 prevBegin = 0;
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
stats << std::fixed << std::setprecision(0);
|
stats << std::fixed << std::setprecision(0);
|
||||||
while (getGlobals().running) {
|
while (getGlobals().running) {
|
||||||
auto cached = cachedTS->getResults();
|
|
||||||
auto depth = depthTS->getResults();
|
|
||||||
auto lightCull = lightCullTS->getResults();
|
|
||||||
auto visibility = visibilityTS->getResults();
|
|
||||||
auto base = baseTS->getResults();
|
|
||||||
auto cachedResults = cachedQuery->getResults();
|
auto cachedResults = cachedQuery->getResults();
|
||||||
auto depthResults = depthQuery->getResults();
|
auto depthResults = depthQuery->getResults();
|
||||||
auto baseResults = baseQuery->getResults();
|
auto baseResults = baseQuery->getResults();
|
||||||
auto lightCullResults = lightCullQuery->getResults();
|
auto lightCullResults = lightCullQuery->getResults();
|
||||||
auto visiblityResults = visibilityQuery->getResults();
|
auto visiblityResults = visibilityQuery->getResults();
|
||||||
if (start == 0) {
|
Map<std::string, uint64> results;
|
||||||
start = cached[0].time;
|
for (uint32 i = 0; i < 11; ++i)
|
||||||
|
{
|
||||||
|
auto ts = timestamps->getResult();
|
||||||
|
results[ts.name] = ts.time;
|
||||||
}
|
}
|
||||||
int64 relTime = cached[0].time - start;
|
if (start == 0) {
|
||||||
int64 cachedTime = cached[1].time - cached[0].time;
|
start = results.at("CachedBegin");
|
||||||
int64 mipTime = depth[1].time - depth[0].time;
|
}
|
||||||
int64 depthTime = depth[2].time - depth[0].time;
|
int64 relTime = results.at("CachedBegin") - start;
|
||||||
int64 baseTime = base[1].time - base[0].time;
|
int64 cachedTime = results.at("CachedEnd") - results.at("CachedBegin");
|
||||||
int64 lightCullTime = lightCull[1].time - lightCull[0].time;
|
int64 mipTime = results.at("CullingBegin") - results.at("MipBegin");
|
||||||
int64 visibilityTime = visibility[1].time - visibility[0].time;
|
int64 depthTime = results.at("CullingEnd") - results.at("CullingBegin");
|
||||||
|
int64 baseTime = results.at("BaseEnd") - results.at("BaseBegin");
|
||||||
|
int64 lightCullTime = results.at("LightCullEnd") - results.at("LightCullBegin");
|
||||||
|
int64 visibilityTime = results.at("VisibilityEnd") - results.at("VisibilityBegin");
|
||||||
int64 frameTime = cachedTime + mipTime + depthTime + baseTime + lightCullTime + visibilityTime;
|
int64 frameTime = cachedTime + mipTime + depthTime + baseTime + lightCullTime + visibilityTime;
|
||||||
|
|
||||||
stats << relTime << "," << cachedTime << "," << mipTime << "," << depthTime << ","
|
stats << relTime << "," << cachedTime << "," << mipTime << "," << depthTime << ","
|
||||||
|
|||||||
+4
-4
@@ -72,10 +72,10 @@ int main() {
|
|||||||
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||||
.importPath = "Whitechapel",
|
.importPath = "Whitechapel",
|
||||||
});
|
});
|
||||||
//AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
.filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
||||||
// .importPath = "suburbs",
|
.importPath = "suburbs",
|
||||||
//});
|
});
|
||||||
getThreadPool().waitIdle();
|
getThreadPool().waitIdle();
|
||||||
vd->commitMeshes();
|
vd->commitMeshes();
|
||||||
WindowCreateInfo mainWindowInfo = {
|
WindowCreateInfo mainWindowInfo = {
|
||||||
|
|||||||
@@ -57,10 +57,8 @@ class TimestampQuery {
|
|||||||
public:
|
public:
|
||||||
TimestampQuery();
|
TimestampQuery();
|
||||||
virtual ~TimestampQuery();
|
virtual ~TimestampQuery();
|
||||||
virtual void begin() = 0;
|
|
||||||
virtual void write(SePipelineStageFlagBits stage, const std::string& name = "") = 0;
|
virtual void write(SePipelineStageFlagBits stage, const std::string& name = "") = 0;
|
||||||
virtual void end() = 0;
|
virtual Timestamp getResult() = 0;
|
||||||
virtual Array<Timestamp> getResults() = 0;
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(TimestampQuery)
|
DEFINE_REF(TimestampQuery)
|
||||||
} // namespace Gfx
|
} // namespace Gfx
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); }
|
|||||||
void Seele::addDebugVertices(Array<DebugVertex> verts) { gDebugVertices.addAll(verts); }
|
void Seele::addDebugVertices(Array<DebugVertex> verts) { gDebugVertices.addAll(verts); }
|
||||||
|
|
||||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||||
waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout);
|
//waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout);
|
||||||
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
||||||
|
|
||||||
basePassLayout->addDescriptorLayout(viewParamsLayout);
|
basePassLayout->addDescriptorLayout(viewParamsLayout);
|
||||||
@@ -145,7 +145,6 @@ void BasePass::render() {
|
|||||||
transparentCulling->writeChanges();
|
transparentCulling->writeChanges();
|
||||||
|
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->begin();
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
@@ -196,7 +195,7 @@ void BasePass::render() {
|
|||||||
},
|
},
|
||||||
.rasterizationState =
|
.rasterizationState =
|
||||||
{
|
{
|
||||||
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
|
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||||
},
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
@@ -374,7 +373,6 @@ void BasePass::render() {
|
|||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd");
|
||||||
timestamps->end();
|
|
||||||
gDebugVertices.clear();
|
gDebugVertices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,13 +424,13 @@ void BasePass::publishOutputs() {
|
|||||||
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
|
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(2, "BaseTS");
|
timestamps = graphics->createTimestampQuery(2, "BaseTS");
|
||||||
resources->registerTimestampQueryOutput("BASE_TS", timestamps);
|
|
||||||
query = graphics->createPipelineStatisticsQuery("BasePassPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("BasePassPipelineStatistics");
|
||||||
resources->registerQueryOutput("BASEPASS_QUERY", query);
|
resources->registerQueryOutput("BASEPASS_QUERY", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePass::createRenderPass() {
|
void BasePass::createRenderPass() {
|
||||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
|
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {msColorAttachment},
|
.colorAttachments = {msColorAttachment},
|
||||||
@@ -472,7 +470,7 @@ void BasePass::createRenderPass() {
|
|||||||
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
|
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
|
||||||
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
|
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
|
||||||
|
|
||||||
waterRenderer->setViewport(viewport, renderPass);
|
//waterRenderer->setViewport(viewport, renderPass);
|
||||||
|
|
||||||
// Debug rendering
|
// Debug rendering
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class BasePass : public RenderPass {
|
|||||||
Gfx::ODescriptorLayout lightCullingLayout;
|
Gfx::ODescriptorLayout lightCullingLayout;
|
||||||
|
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
|
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,10 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : Render
|
|||||||
|
|
||||||
CachedDepthPass::~CachedDepthPass() {}
|
CachedDepthPass::~CachedDepthPass() {}
|
||||||
|
|
||||||
void CachedDepthPass::beginFrame(const Component::Camera& cam) {
|
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||||
RenderPass::beginFrame(cam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CachedDepthPass::render() {
|
void CachedDepthPass::render() {
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->begin();
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
@@ -78,6 +75,10 @@ void CachedDepthPass::render() {
|
|||||||
.fragmentShader = collection->fragmentShader,
|
.fragmentShader = collection->fragmentShader,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||||
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
@@ -91,6 +92,10 @@ void CachedDepthPass::render() {
|
|||||||
.fragmentShader = collection->fragmentShader,
|
.fragmentShader = collection->fragmentShader,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||||
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
@@ -128,7 +133,6 @@ void CachedDepthPass::render() {
|
|||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd");
|
||||||
timestamps->end();
|
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,8 +167,8 @@ void CachedDepthPass::publishOutputs() {
|
|||||||
query = graphics->createPipelineStatisticsQuery("CachedPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("CachedPipelineStatistics");
|
||||||
resources->registerQueryOutput("CACHED_QUERY", query);
|
resources->registerQueryOutput("CACHED_QUERY", query);
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(2, "CachedTS");
|
timestamps = graphics->createTimestampQuery(7, "CachedTS");
|
||||||
resources->registerTimestampQueryOutput("CACHED_TS", timestamps);
|
resources->registerTimestampQueryOutput("TIMESTAMPS", timestamps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CachedDepthPass::createRenderPass() {
|
void CachedDepthPass::createRenderPass() {
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ void DepthCullingPass::render() {
|
|||||||
set->updateBuffer(1, depthMipBuffer);
|
set->updateBuffer(1, depthMipBuffer);
|
||||||
set->writeChanges();
|
set->writeChanges();
|
||||||
|
|
||||||
timestamps->begin();
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "MipBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "MipBegin");
|
||||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("InitialReduce");
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("InitialReduce");
|
||||||
computeCommand->bindPipeline(depthInitialReduce);
|
computeCommand->bindPipeline(depthInitialReduce);
|
||||||
@@ -160,6 +159,10 @@ void DepthCullingPass::render() {
|
|||||||
.fragmentShader = collection->fragmentShader,
|
.fragmentShader = collection->fragmentShader,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||||
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
@@ -173,6 +176,10 @@ void DepthCullingPass::render() {
|
|||||||
.fragmentShader = collection->fragmentShader,
|
.fragmentShader = collection->fragmentShader,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = collection->pipelineLayout,
|
.pipelineLayout = collection->pipelineLayout,
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||||
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
@@ -210,7 +217,6 @@ void DepthCullingPass::render() {
|
|||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CullingEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CullingEnd");
|
||||||
timestamps->end();
|
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
// Sync depth read/write with compute read
|
// Sync depth read/write with compute read
|
||||||
depthAttachment.getTexture()->pipelineBarrier(
|
depthAttachment.getTexture()->pipelineBarrier(
|
||||||
@@ -243,8 +249,6 @@ void DepthCullingPass::publishOutputs() {
|
|||||||
.data = nullptr,
|
.data = nullptr,
|
||||||
},
|
},
|
||||||
.numElements = bufferSize,
|
.numElements = bufferSize,
|
||||||
.clearValue = 0,
|
|
||||||
.createCleared = true,
|
|
||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "DepthMipBuffer",
|
.name = "DepthMipBuffer",
|
||||||
});
|
});
|
||||||
@@ -269,14 +273,13 @@ void DepthCullingPass::publishOutputs() {
|
|||||||
|
|
||||||
depthMipGen = graphics->createComputePipeline(pipelineCreateInfo);
|
depthMipGen = graphics->createComputePipeline(pipelineCreateInfo);
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(3, "CullingTS");
|
|
||||||
resources->registerTimestampQueryOutput("DEPTH_TS", timestamps);
|
|
||||||
query = graphics->createPipelineStatisticsQuery("DepthPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("DepthPipelineStatistics");
|
||||||
resources->registerQueryOutput("DEPTH_QUERY", query);
|
resources->registerQueryOutput("DEPTH_QUERY", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthCullingPass::createRenderPass() {
|
void DepthCullingPass::createRenderPass() {
|
||||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
|
|
||||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class DepthCullingPass : public RenderPass {
|
|||||||
Gfx::ODescriptorLayout depthAttachmentLayout;
|
Gfx::ODescriptorLayout depthAttachmentLayout;
|
||||||
Gfx::OPipelineLayout depthCullingLayout;
|
Gfx::OPipelineLayout depthCullingLayout;
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
|
|
||||||
Gfx::OPipelineLayout depthComputeLayout;
|
Gfx::OPipelineLayout depthComputeLayout;
|
||||||
Gfx::OComputeShader depthInitialReduceShader;
|
Gfx::OComputeShader depthInitialReduceShader;
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) {
|
|||||||
|
|
||||||
void LightCullingPass::render() {
|
void LightCullingPass::render() {
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->begin();
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin");
|
||||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
@@ -64,7 +63,6 @@ void LightCullingPass::render() {
|
|||||||
// std::cout << "Execute" << std::endl;
|
// std::cout << "Execute" << std::endl;
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "LightCullEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "LightCullEnd");
|
||||||
timestamps->end();
|
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
oLightIndexList->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
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);
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
@@ -227,13 +225,12 @@ void LightCullingPass::publishOutputs() {
|
|||||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", Gfx::PTexture2D(oLightGrid));
|
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", Gfx::PTexture2D(oLightGrid));
|
||||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid));
|
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid));
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(2, "LightCullTS");
|
|
||||||
resources->registerTimestampQueryOutput("LIGHTCULL_TS", timestamps);
|
|
||||||
query = graphics->createPipelineStatisticsQuery("LightCullPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("LightCullPipelineStatistics");
|
||||||
resources->registerQueryOutput("LIGHTCULL_QUERY", query);
|
resources->registerQueryOutput("LIGHTCULL_QUERY", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::createRenderPass() {
|
void LightCullingPass::createRenderPass() {
|
||||||
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
|
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class LightCullingPass : public RenderPass {
|
|||||||
Gfx::PComputePipeline cullingPipeline;
|
Gfx::PComputePipeline cullingPipeline;
|
||||||
Gfx::PComputePipeline cullingEnabledPipeline;
|
Gfx::PComputePipeline cullingEnabledPipeline;
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
};
|
};
|
||||||
DEFINE_REF(LightCullingPass)
|
DEFINE_REF(LightCullingPass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ void VisibilityPass::render() {
|
|||||||
visibilitySet->writeChanges();
|
visibilitySet->writeChanges();
|
||||||
|
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->begin();
|
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "VisibilityBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "VisibilityBegin");
|
||||||
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
|
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
|
||||||
command->bindPipeline(visibilityPipeline);
|
command->bindPipeline(visibilityPipeline);
|
||||||
@@ -36,7 +35,6 @@ void VisibilityPass::render() {
|
|||||||
commands.add(std::move(command));
|
commands.add(std::move(command));
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "VisibilityEnd");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "VisibilityEnd");
|
||||||
timestamps->end();
|
|
||||||
query->endQuery();
|
query->endQuery();
|
||||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
@@ -88,11 +86,11 @@ void VisibilityPass::publishOutputs() {
|
|||||||
});
|
});
|
||||||
resources->registerBufferOutput("CULLINGBUFFER", cullingBuffer);
|
resources->registerBufferOutput("CULLINGBUFFER", cullingBuffer);
|
||||||
|
|
||||||
timestamps = graphics->createTimestampQuery(2, "VisibilityTS");
|
|
||||||
resources->registerTimestampQueryOutput("VISIBILITY_TS", timestamps);
|
|
||||||
|
|
||||||
query = graphics->createPipelineStatisticsQuery("VisibilityPipelineStatistics");
|
query = graphics->createPipelineStatisticsQuery("VisibilityPipelineStatistics");
|
||||||
resources->registerQueryOutput("VISIBILITY_QUERY", query);
|
resources->registerQueryOutput("VISIBILITY_QUERY", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::createRenderPass() { visibilityAttachment = resources->requestRenderTarget("VISIBILITY"); }
|
void VisibilityPass::createRenderPass() {
|
||||||
|
visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||||
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class VisibilityPass : public RenderPass {
|
|||||||
Gfx::OComputeShader visibilityShader;
|
Gfx::OComputeShader visibilityShader;
|
||||||
Gfx::PComputePipeline visibilityPipeline;
|
Gfx::PComputePipeline visibilityPipeline;
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::OTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
|
|
||||||
// Holds culling information for every meshlet for each instance
|
// Holds culling information for every meshlet for each instance
|
||||||
Gfx::OShaderBuffer cullingBuffer;
|
Gfx::OShaderBuffer cullingBuffer;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 24;//17962284;
|
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 17962284;
|
||||||
Map<VertexData::MeshMapping, VertexData::CullingMapping> VertexData::instanceIdMap;
|
Map<VertexData::MeshMapping, VertexData::CullingMapping> VertexData::instanceIdMap;
|
||||||
uint64 VertexData::instanceCount = 0;
|
uint64 VertexData::instanceCount = 0;
|
||||||
uint64 VertexData::meshletCount = 0;
|
uint64 VertexData::meshletCount = 0;
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ Gfx::OPipelineStatisticsQuery Graphics::createPipelineStatisticsQuery(const std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const std::string& name) {
|
Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const std::string& name) {
|
||||||
return new TimestampQuery(this, name, numTimestamps);
|
return new TimestampQuery(this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||||
@@ -635,9 +635,9 @@ Array<const char*> Graphics::getRequiredExtensions() {
|
|||||||
for (unsigned int i = 0; i < glfwExtensionCount; i++) {
|
for (unsigned int i = 0; i < glfwExtensionCount; i++) {
|
||||||
extensions.add(glfwExtensions[i]);
|
extensions.add(glfwExtensions[i]);
|
||||||
}
|
}
|
||||||
#if ENABLE_VALIDATION
|
#ifdef ENABLE_VALIDATION
|
||||||
extensions.add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
extensions.add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
#endif // ENABLE_VALIDATION
|
#endif
|
||||||
return extensions;
|
return extensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,65 @@ using namespace Seele::Vulkan;
|
|||||||
|
|
||||||
QueryPool::QueryPool(PGraphics graphics, VkQueryType type, VkQueryPipelineStatisticFlags flags, uint32 resultsStride, uint32 numBuffered,
|
QueryPool::QueryPool(PGraphics graphics, VkQueryType type, VkQueryPipelineStatisticFlags flags, uint32 resultsStride, uint32 numBuffered,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
: graphics(graphics), flags(flags), numQueries(numBuffered), resultsStride(resultsStride) {
|
: graphics(graphics), type(type), name(name), flags(flags), numQueries(numBuffered), resultsStride(resultsStride) {
|
||||||
|
createPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryPool::~QueryPool() {
|
||||||
|
for (auto handle : pools) {
|
||||||
|
vkDestroyQueryPool(graphics->getDevice(), handle, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryPool::begin() {
|
||||||
|
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
||||||
|
vkCmdResetQueryPool(cmd->getHandle(), pools.back(), head, 1);
|
||||||
|
vkCmdBeginQuery(cmd->getHandle(), pools.back(), head, 0);
|
||||||
|
cmd->setPipelineStatisticsFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryPool::end() {
|
||||||
|
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
||||||
|
vkCmdEndQuery(cmd->getHandle(), pools.back(), head);
|
||||||
|
std::unique_lock l(queryMutex);
|
||||||
|
head++;
|
||||||
|
if (head == numQueries) {
|
||||||
|
createPool();
|
||||||
|
head = 0;
|
||||||
|
}
|
||||||
|
numAvailable++;
|
||||||
|
queryCV.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryPool::getQueryResults(Array<uint64>& results) {
|
||||||
|
{
|
||||||
|
std::unique_lock l(queryMutex);
|
||||||
|
while (numAvailable == 0) {
|
||||||
|
queryCV.wait(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results.resize(resultsStride / sizeof(uint64));
|
||||||
|
vkGetQueryPoolResults(graphics->getDevice(), pools.front(), tail, 1, resultsStride, results.data(), resultsStride,
|
||||||
|
VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
|
||||||
|
std::unique_lock l(queryMutex);
|
||||||
|
tail++;
|
||||||
|
if (tail == numQueries)
|
||||||
|
{
|
||||||
|
vkDestroyQueryPool(graphics->getDevice(), pools.front(), nullptr);
|
||||||
|
pools.popFront();
|
||||||
|
tail = 0;
|
||||||
|
}
|
||||||
|
numAvailable--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryPool::createPool() {
|
||||||
|
VkQueryPool handle;
|
||||||
VkQueryPoolCreateInfo info = {
|
VkQueryPoolCreateInfo info = {
|
||||||
.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.queryType = type,
|
.queryType = type,
|
||||||
.queryCount = numBuffered,
|
.queryCount = numQueries,
|
||||||
.pipelineStatistics = flags,
|
.pipelineStatistics = flags,
|
||||||
};
|
};
|
||||||
VK_CHECK(vkCreateQueryPool(graphics->getDevice(), &info, nullptr, &handle));
|
VK_CHECK(vkCreateQueryPool(graphics->getDevice(), &info, nullptr, &handle));
|
||||||
@@ -30,36 +82,12 @@ QueryPool::QueryPool(PGraphics graphics, VkQueryType type, VkQueryPipelineStatis
|
|||||||
.pObjectName = name.c_str(),
|
.pObjectName = name.c_str(),
|
||||||
};
|
};
|
||||||
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
||||||
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
pools.add(handle);
|
||||||
vkCmdResetQueryPool(cmd->getHandle(), handle, head, numQueries);
|
if (pools.size() > 5)
|
||||||
}
|
{
|
||||||
|
vkDestroyQueryPool(graphics->getDevice(), pools.front(), nullptr);
|
||||||
QueryPool::~QueryPool() { vkDestroyQueryPool(graphics->getDevice(), handle, nullptr); }
|
pools.popFront();
|
||||||
|
|
||||||
void QueryPool::begin() {
|
|
||||||
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
|
||||||
vkCmdResetQueryPool(cmd->getHandle(), handle, head, 1);
|
|
||||||
vkCmdBeginQuery(cmd->getHandle(), handle, head, 0);
|
|
||||||
cmd->setPipelineStatisticsFlags(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryPool::end() {
|
|
||||||
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
|
||||||
vkCmdEndQuery(cmd->getHandle(), handle, head);
|
|
||||||
std::unique_lock l(queryMutex);
|
|
||||||
head = (head + 1) % numQueries;
|
|
||||||
queryCV.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryPool::getQueryResults(Array<uint64>& results) {
|
|
||||||
while (tail == head) {
|
|
||||||
std::unique_lock l(queryMutex);
|
|
||||||
queryCV.wait(l);
|
|
||||||
}
|
}
|
||||||
results.resize(resultsStride / sizeof(uint64));
|
|
||||||
vkGetQueryPoolResults(graphics->getDevice(), handle, tail, 1, resultsStride, results.data(), resultsStride,
|
|
||||||
VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
|
|
||||||
tail = (tail + 1) % numQueries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OcclusionQuery::OcclusionQuery(PGraphics graphics, const std::string& name)
|
OcclusionQuery::OcclusionQuery(PGraphics graphics, const std::string& name)
|
||||||
@@ -111,48 +139,52 @@ Gfx::PipelineStatisticsResult PipelineStatisticsQuery::getResults() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TimestampQuery::TimestampQuery(PGraphics graphics, const std::string& name, uint32 numTimestamps)
|
TimestampQuery::TimestampQuery(PGraphics graphics, const std::string& name)
|
||||||
: QueryPool(graphics, VK_QUERY_TYPE_TIMESTAMP, 0, sizeof(uint64), 512 * numTimestamps, name), numTimestamps(numTimestamps) {
|
: QueryPool(graphics, VK_QUERY_TYPE_TIMESTAMP, 0, sizeof(uint64), 512, name) {
|
||||||
pendingTimestamps.resize(numQueries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimestampQuery::~TimestampQuery() {}
|
TimestampQuery::~TimestampQuery() {}
|
||||||
|
|
||||||
void TimestampQuery::begin() {
|
|
||||||
currentTimestamp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimestampQuery::write(Gfx::SePipelineStageFlagBits stage, const std::string& name) {
|
void TimestampQuery::write(Gfx::SePipelineStageFlagBits stage, const std::string& name) {
|
||||||
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
|
||||||
uint32 queryIndex = (head * numTimestamps) + currentTimestamp;
|
vkCmdResetQueryPool(cmd->getHandle(), pools.back(), head, 1);
|
||||||
vkCmdResetQueryPool(cmd->getHandle(), handle, queryIndex, 1);
|
vkCmdWriteTimestamp(cmd->getHandle(), cast(stage), pools.back(), head);
|
||||||
vkCmdWriteTimestamp(cmd->getHandle(), cast(stage), handle, queryIndex);
|
pendingTimestamps.add(name);
|
||||||
pendingTimestamps[queryIndex] = name;
|
{
|
||||||
currentTimestamp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimestampQuery::end() {
|
|
||||||
std::unique_lock l(queryMutex);
|
|
||||||
head = (head + 1) % 512;
|
|
||||||
queryCV.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<Gfx::Timestamp> TimestampQuery::getResults() {
|
|
||||||
while (head == tail) {
|
|
||||||
std::unique_lock l(queryMutex);
|
std::unique_lock l(queryMutex);
|
||||||
queryCV.wait(l);
|
head++;
|
||||||
|
if (head == numQueries) {
|
||||||
|
createPool();
|
||||||
|
head = 0;
|
||||||
|
}
|
||||||
|
numAvailable++;
|
||||||
}
|
}
|
||||||
Array<uint64> results(numTimestamps);
|
}
|
||||||
uint32 firstQuery = (tail * numTimestamps);
|
|
||||||
vkGetQueryPoolResults(graphics->getDevice(), handle, firstQuery, numTimestamps, numTimestamps * sizeof(uint64), results.data(),
|
Gfx::Timestamp TimestampQuery::getResult() {
|
||||||
resultsStride, VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
|
{
|
||||||
tail = (tail + 1) % 512;
|
std::unique_lock l(queryMutex);
|
||||||
Array<Gfx::Timestamp> res;
|
while (numAvailable == 0) {
|
||||||
for (uint64 i = 0; i < numTimestamps; ++i) {
|
queryCV.wait(l);
|
||||||
res.add(Gfx::Timestamp{
|
}
|
||||||
.name = pendingTimestamps[firstQuery + i],
|
}
|
||||||
.time = uint64((results[i] + wrapping) * graphics->getTimestampPeriod()),
|
uint64 result;
|
||||||
});
|
vkGetQueryPoolResults(graphics->getDevice(), pools.front(), tail, 1, sizeof(uint64), &result, resultsStride,
|
||||||
|
VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
|
||||||
|
{
|
||||||
|
std::unique_lock l(queryMutex);
|
||||||
|
tail++;
|
||||||
|
if (tail == numQueries) {
|
||||||
|
vkDestroyQueryPool(graphics->getDevice(), pools.front(), nullptr);
|
||||||
|
pools.popFront();
|
||||||
|
tail = 0;
|
||||||
|
}
|
||||||
|
numAvailable--;
|
||||||
|
Gfx::Timestamp res = Gfx::Timestamp{
|
||||||
|
.name = pendingTimestamps.front(),
|
||||||
|
.time = result,
|
||||||
|
};
|
||||||
|
pendingTimestamps.popFront();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
@@ -14,14 +14,18 @@ class QueryPool {
|
|||||||
void end();
|
void end();
|
||||||
// stalls for the currently first pending query, dont call in render thread
|
// stalls for the currently first pending query, dont call in render thread
|
||||||
void getQueryResults(Array<uint64>& results);
|
void getQueryResults(Array<uint64>& results);
|
||||||
|
void createPool();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
VkQueryPool handle;
|
List<VkQueryPool> pools;
|
||||||
|
VkQueryType type;
|
||||||
|
std::string name;
|
||||||
VkQueryPipelineStatisticFlags flags;
|
VkQueryPipelineStatisticFlags flags;
|
||||||
// ring buffer
|
// ring buffer
|
||||||
uint64 head = 0;
|
uint64 head = 0;
|
||||||
uint64 tail = 0;
|
uint64 tail = 0;
|
||||||
|
uint64 numAvailable;
|
||||||
uint32 numQueries;
|
uint32 numQueries;
|
||||||
uint32 resultsStride;
|
uint32 resultsStride;
|
||||||
std::mutex queryMutex;
|
std::mutex queryMutex;
|
||||||
@@ -48,19 +52,15 @@ DEFINE_REF(PipelineStatisticsQuery)
|
|||||||
|
|
||||||
class TimestampQuery : public Gfx::TimestampQuery, public QueryPool {
|
class TimestampQuery : public Gfx::TimestampQuery, public QueryPool {
|
||||||
public:
|
public:
|
||||||
TimestampQuery(PGraphics graphics, const std::string& name, uint32 numTimestamps);
|
TimestampQuery(PGraphics graphics, const std::string& name);
|
||||||
virtual ~TimestampQuery();
|
virtual ~TimestampQuery();
|
||||||
virtual void begin() override;
|
|
||||||
virtual void write(Gfx::SePipelineStageFlagBits stage, const std::string& name = "") override;
|
virtual void write(Gfx::SePipelineStageFlagBits stage, const std::string& name = "") override;
|
||||||
virtual void end() override;
|
virtual Gfx::Timestamp getResult() override;
|
||||||
virtual Array<Gfx::Timestamp> getResults() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 wrapping = 0;
|
uint64 wrapping = 0;
|
||||||
uint64 lastMeasure = 0;
|
uint64 lastMeasure = 0;
|
||||||
uint32 numTimestamps = 0;
|
List<std::string> pendingTimestamps;
|
||||||
uint32 currentTimestamp = 0;
|
|
||||||
Array<std::string> pendingTimestamps;
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(TimestampQuery)
|
DEFINE_REF(TimestampQuery)
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
Reference in New Issue
Block a user