Add render graph runtime depth support
This commit is contained in:
@@ -22,6 +22,9 @@ struct MockTransientAllocationState {
|
||||
int createRenderTargetViewCalls = 0;
|
||||
int shutdownRenderTargetViewCalls = 0;
|
||||
int destroyRenderTargetViewCalls = 0;
|
||||
int createDepthViewCalls = 0;
|
||||
int shutdownDepthViewCalls = 0;
|
||||
int destroyDepthViewCalls = 0;
|
||||
int createShaderViewCalls = 0;
|
||||
int shutdownShaderViewCalls = 0;
|
||||
int destroyShaderViewCalls = 0;
|
||||
@@ -83,6 +86,8 @@ public:
|
||||
~MockTransientView() override {
|
||||
if (m_viewType == ResourceViewType::RenderTarget) {
|
||||
++m_state->destroyRenderTargetViewCalls;
|
||||
} else if (m_viewType == ResourceViewType::DepthStencil) {
|
||||
++m_state->destroyDepthViewCalls;
|
||||
} else {
|
||||
++m_state->destroyShaderViewCalls;
|
||||
}
|
||||
@@ -91,6 +96,8 @@ public:
|
||||
void Shutdown() override {
|
||||
if (m_viewType == ResourceViewType::RenderTarget) {
|
||||
++m_state->shutdownRenderTargetViewCalls;
|
||||
} else if (m_viewType == ResourceViewType::DepthStencil) {
|
||||
++m_state->shutdownDepthViewCalls;
|
||||
} else {
|
||||
++m_state->shutdownShaderViewCalls;
|
||||
}
|
||||
@@ -110,12 +117,23 @@ private:
|
||||
|
||||
class MockImportedView final : public RHIResourceView {
|
||||
public:
|
||||
explicit MockImportedView(
|
||||
ResourceViewType viewType = ResourceViewType::RenderTarget,
|
||||
Format format = Format::R8G8B8A8_UNorm)
|
||||
: m_viewType(viewType)
|
||||
, m_format(format) {
|
||||
}
|
||||
|
||||
void Shutdown() override {}
|
||||
void* GetNativeHandle() override { return nullptr; }
|
||||
bool IsValid() const override { return true; }
|
||||
ResourceViewType GetViewType() const override { return ResourceViewType::RenderTarget; }
|
||||
ResourceViewType GetViewType() const override { return m_viewType; }
|
||||
ResourceViewDimension GetDimension() const override { return ResourceViewDimension::Texture2D; }
|
||||
Format GetFormat() const override { return Format::R8G8B8A8_UNorm; }
|
||||
Format GetFormat() const override { return m_format; }
|
||||
|
||||
private:
|
||||
ResourceViewType m_viewType = ResourceViewType::RenderTarget;
|
||||
Format m_format = Format::R8G8B8A8_UNorm;
|
||||
};
|
||||
|
||||
class MockTransientDevice final : public RHIDevice {
|
||||
@@ -183,7 +201,15 @@ public:
|
||||
static_cast<Format>(desc.format));
|
||||
}
|
||||
|
||||
RHIResourceView* CreateDepthStencilView(RHITexture*, const ResourceViewDesc&) override { return nullptr; }
|
||||
RHIResourceView* CreateDepthStencilView(
|
||||
RHITexture*,
|
||||
const ResourceViewDesc& desc) override {
|
||||
++m_state->createDepthViewCalls;
|
||||
return new MockTransientView(
|
||||
m_state,
|
||||
ResourceViewType::DepthStencil,
|
||||
static_cast<Format>(desc.format));
|
||||
}
|
||||
RHIResourceView* CreateShaderResourceView(RHIBuffer*, const ResourceViewDesc&) override { return nullptr; }
|
||||
|
||||
RHIResourceView* CreateShaderResourceView(
|
||||
@@ -574,6 +600,127 @@ TEST(RenderGraph_Test, TracksDepthAttachmentTransitionPlan) {
|
||||
EXPECT_EQ(transitionPlan.finalState, ResourceStates::DepthWrite);
|
||||
}
|
||||
|
||||
TEST(RenderGraph_Test, ExecutesTransientDepthTransitionsWithDepthStencilView) {
|
||||
RenderGraph graph;
|
||||
RenderGraphBuilder builder(graph);
|
||||
|
||||
const RenderGraphTextureDesc depthDesc = BuildTestDepthTextureDesc();
|
||||
const RenderGraphTextureHandle depthTexture =
|
||||
builder.CreateTransientTexture("SceneDepth", depthDesc);
|
||||
|
||||
RHIResourceView* depthWriteView = nullptr;
|
||||
RHIResourceView* depthReadView = nullptr;
|
||||
builder.AddRasterPass(
|
||||
"DepthPrepass",
|
||||
[&](RenderGraphPassBuilder& pass) {
|
||||
pass.WriteDepthTexture(depthTexture);
|
||||
pass.SetExecuteCallback(
|
||||
[&](const RenderGraphExecutionContext& executionContext) {
|
||||
depthWriteView =
|
||||
executionContext.ResolveTextureView(
|
||||
depthTexture,
|
||||
RenderGraphTextureViewType::DepthStencil);
|
||||
EXPECT_NE(depthWriteView, nullptr);
|
||||
});
|
||||
});
|
||||
|
||||
builder.AddRasterPass(
|
||||
"DepthConsumer",
|
||||
[&](RenderGraphPassBuilder& pass) {
|
||||
pass.ReadDepthTexture(depthTexture);
|
||||
pass.SetExecuteCallback(
|
||||
[&](const RenderGraphExecutionContext& executionContext) {
|
||||
depthReadView =
|
||||
executionContext.ResolveTextureView(
|
||||
depthTexture,
|
||||
RenderGraphTextureViewType::DepthStencil);
|
||||
EXPECT_EQ(depthReadView, depthWriteView);
|
||||
});
|
||||
});
|
||||
|
||||
CompiledRenderGraph compiledGraph;
|
||||
XCEngine::Containers::String errorMessage;
|
||||
ASSERT_TRUE(RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage))
|
||||
<< errorMessage.CStr();
|
||||
|
||||
auto allocationState = std::make_shared<MockTransientAllocationState>();
|
||||
MockTransientDevice device(allocationState);
|
||||
MockTransientCommandList commandList;
|
||||
RenderContext renderContext = {};
|
||||
renderContext.device = &device;
|
||||
renderContext.commandList = &commandList;
|
||||
renderContext.commandQueue = reinterpret_cast<RHICommandQueue*>(1);
|
||||
ASSERT_TRUE(RenderGraphExecutor::Execute(compiledGraph, renderContext, &errorMessage))
|
||||
<< errorMessage.CStr();
|
||||
|
||||
ASSERT_EQ(commandList.transitionCalls.size(), 2u);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].resource, depthWriteView);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].before, ResourceStates::Common);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].after, ResourceStates::DepthWrite);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].resource, depthReadView);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].before, ResourceStates::DepthWrite);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].after, ResourceStates::DepthRead);
|
||||
EXPECT_EQ(allocationState->createTextureCalls, 1);
|
||||
EXPECT_EQ(allocationState->createRenderTargetViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->createDepthViewCalls, 1);
|
||||
EXPECT_EQ(allocationState->createShaderViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->shutdownTextureCalls, 1);
|
||||
EXPECT_EQ(allocationState->shutdownRenderTargetViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->shutdownDepthViewCalls, 1);
|
||||
EXPECT_EQ(allocationState->shutdownShaderViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->destroyTextureCalls, 1);
|
||||
EXPECT_EQ(allocationState->destroyRenderTargetViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->destroyDepthViewCalls, 1);
|
||||
EXPECT_EQ(allocationState->destroyShaderViewCalls, 0);
|
||||
}
|
||||
|
||||
TEST(RenderGraph_Test, ExecutesGraphOwnedImportedDepthTransitionsAtGraphBoundaries) {
|
||||
RenderGraph graph;
|
||||
RenderGraphBuilder builder(graph);
|
||||
|
||||
const RenderGraphTextureDesc depthDesc = BuildTestDepthTextureDesc();
|
||||
RenderGraphImportedTextureOptions importedOptions = {};
|
||||
importedOptions.initialState = ResourceStates::DepthWrite;
|
||||
importedOptions.finalState = ResourceStates::DepthWrite;
|
||||
importedOptions.graphOwnsTransitions = true;
|
||||
|
||||
MockImportedView importedDepthView(
|
||||
ResourceViewType::DepthStencil,
|
||||
Format::D24_UNorm_S8_UInt);
|
||||
const RenderGraphTextureHandle importedDepth = builder.ImportTexture(
|
||||
"ImportedDepth",
|
||||
depthDesc,
|
||||
&importedDepthView,
|
||||
importedOptions);
|
||||
|
||||
builder.AddRasterPass(
|
||||
"ReadOnlyDepth",
|
||||
[&](RenderGraphPassBuilder& pass) {
|
||||
pass.ReadDepthTexture(importedDepth);
|
||||
});
|
||||
|
||||
CompiledRenderGraph compiledGraph;
|
||||
XCEngine::Containers::String errorMessage;
|
||||
ASSERT_TRUE(RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage))
|
||||
<< errorMessage.CStr();
|
||||
|
||||
MockTransientCommandList commandList;
|
||||
RenderContext renderContext = {};
|
||||
renderContext.device = reinterpret_cast<RHIDevice*>(1);
|
||||
renderContext.commandList = &commandList;
|
||||
renderContext.commandQueue = reinterpret_cast<RHICommandQueue*>(1);
|
||||
ASSERT_TRUE(RenderGraphExecutor::Execute(compiledGraph, renderContext, &errorMessage))
|
||||
<< errorMessage.CStr();
|
||||
|
||||
ASSERT_EQ(commandList.transitionCalls.size(), 2u);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].resource, &importedDepthView);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].before, ResourceStates::DepthWrite);
|
||||
EXPECT_EQ(commandList.transitionCalls[0].after, ResourceStates::DepthRead);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].resource, &importedDepthView);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].before, ResourceStates::DepthRead);
|
||||
EXPECT_EQ(commandList.transitionCalls[1].after, ResourceStates::DepthWrite);
|
||||
}
|
||||
|
||||
TEST(RenderGraph_Test, ExecutesCompiledPassCallbacksInCompiledOrder) {
|
||||
RenderGraph graph;
|
||||
RenderGraphBuilder builder(graph);
|
||||
|
||||
Reference in New Issue
Block a user