Add render graph depth access semantics
This commit is contained in:
@@ -38,6 +38,7 @@ private:
|
||||
struct TextureAccess {
|
||||
RenderGraphTextureHandle texture = {};
|
||||
RenderGraphAccessMode mode = RenderGraphAccessMode::Read;
|
||||
RenderGraphTextureAspect aspect = RenderGraphTextureAspect::Color;
|
||||
};
|
||||
|
||||
struct PassNode {
|
||||
@@ -60,6 +61,8 @@ class RenderGraphPassBuilder {
|
||||
public:
|
||||
void ReadTexture(RenderGraphTextureHandle texture);
|
||||
void WriteTexture(RenderGraphTextureHandle texture);
|
||||
void ReadDepthTexture(RenderGraphTextureHandle texture);
|
||||
void WriteDepthTexture(RenderGraphTextureHandle texture);
|
||||
void SetExecuteCallback(RenderGraphExecuteCallback callback);
|
||||
|
||||
private:
|
||||
|
||||
@@ -31,6 +31,7 @@ private:
|
||||
struct CompiledTextureAccess {
|
||||
RenderGraphTextureHandle texture = {};
|
||||
RenderGraphAccessMode mode = RenderGraphAccessMode::Read;
|
||||
RenderGraphTextureAspect aspect = RenderGraphTextureAspect::Color;
|
||||
RHI::ResourceStates requiredState = RHI::ResourceStates::Common;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ enum class RenderGraphAccessMode : Core::uint8 {
|
||||
Write = 1
|
||||
};
|
||||
|
||||
enum class RenderGraphTextureAspect : Core::uint8 {
|
||||
Color = 0,
|
||||
Depth = 1
|
||||
};
|
||||
|
||||
enum class RenderGraphTextureViewType : Core::uint8 {
|
||||
RenderTarget = 0,
|
||||
ShaderResource = 1
|
||||
|
||||
@@ -217,7 +217,7 @@ void ReadRenderGraphSurface(
|
||||
}
|
||||
|
||||
if (surface.depthTexture.IsValid()) {
|
||||
passBuilder.ReadTexture(surface.depthTexture);
|
||||
passBuilder.ReadDepthTexture(surface.depthTexture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ void WriteRenderGraphSurface(
|
||||
}
|
||||
|
||||
if (surface.depthTexture.IsValid()) {
|
||||
passBuilder.WriteTexture(surface.depthTexture);
|
||||
passBuilder.WriteDepthTexture(surface.depthTexture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ void RenderGraphPassBuilder::ReadTexture(RenderGraphTextureHandle texture) {
|
||||
RenderGraph::TextureAccess access = {};
|
||||
access.texture = texture;
|
||||
access.mode = RenderGraphAccessMode::Read;
|
||||
access.aspect = RenderGraphTextureAspect::Color;
|
||||
m_graph->m_passes[m_passHandle.index].accesses.push_back(access);
|
||||
}
|
||||
|
||||
@@ -36,6 +37,31 @@ void RenderGraphPassBuilder::WriteTexture(RenderGraphTextureHandle texture) {
|
||||
RenderGraph::TextureAccess access = {};
|
||||
access.texture = texture;
|
||||
access.mode = RenderGraphAccessMode::Write;
|
||||
access.aspect = RenderGraphTextureAspect::Color;
|
||||
m_graph->m_passes[m_passHandle.index].accesses.push_back(access);
|
||||
}
|
||||
|
||||
void RenderGraphPassBuilder::ReadDepthTexture(RenderGraphTextureHandle texture) {
|
||||
if (m_graph == nullptr || !m_passHandle.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderGraph::TextureAccess access = {};
|
||||
access.texture = texture;
|
||||
access.mode = RenderGraphAccessMode::Read;
|
||||
access.aspect = RenderGraphTextureAspect::Depth;
|
||||
m_graph->m_passes[m_passHandle.index].accesses.push_back(access);
|
||||
}
|
||||
|
||||
void RenderGraphPassBuilder::WriteDepthTexture(RenderGraphTextureHandle texture) {
|
||||
if (m_graph == nullptr || !m_passHandle.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderGraph::TextureAccess access = {};
|
||||
access.texture = texture;
|
||||
access.mode = RenderGraphAccessMode::Write;
|
||||
access.aspect = RenderGraphTextureAspect::Depth;
|
||||
m_graph->m_passes[m_passHandle.index].accesses.push_back(access);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,24 @@ namespace {
|
||||
|
||||
RHI::ResourceStates ResolveRequiredState(
|
||||
RenderGraphPassType passType,
|
||||
RenderGraphAccessMode accessMode) {
|
||||
RenderGraphAccessMode accessMode,
|
||||
RenderGraphTextureAspect aspect) {
|
||||
if (accessMode == RenderGraphAccessMode::Write) {
|
||||
if (passType == RenderGraphPassType::Raster &&
|
||||
aspect == RenderGraphTextureAspect::Depth) {
|
||||
return RHI::ResourceStates::DepthWrite;
|
||||
}
|
||||
|
||||
return passType == RenderGraphPassType::Compute
|
||||
? RHI::ResourceStates::UnorderedAccess
|
||||
: RHI::ResourceStates::RenderTarget;
|
||||
}
|
||||
|
||||
if (passType == RenderGraphPassType::Raster &&
|
||||
aspect == RenderGraphTextureAspect::Depth) {
|
||||
return RHI::ResourceStates::DepthRead;
|
||||
}
|
||||
|
||||
return passType == RenderGraphPassType::Compute
|
||||
? RHI::ResourceStates::GenericRead
|
||||
: RHI::ResourceStates::PixelShaderResource;
|
||||
@@ -261,8 +272,9 @@ bool RenderGraphCompiler::Compile(
|
||||
CompiledRenderGraph::CompiledTextureAccess compiledAccess = {};
|
||||
compiledAccess.texture = access.texture;
|
||||
compiledAccess.mode = access.mode;
|
||||
compiledAccess.aspect = access.aspect;
|
||||
compiledAccess.requiredState =
|
||||
ResolveRequiredState(sourcePass.type, access.mode);
|
||||
ResolveRequiredState(sourcePass.type, access.mode, access.aspect);
|
||||
compiledPass.accesses.push_back(compiledAccess);
|
||||
}
|
||||
compiledPass.executeCallback = sourcePass.executeCallback;
|
||||
@@ -280,7 +292,7 @@ bool RenderGraphCompiler::Compile(
|
||||
lifetime.lastPassIndex = compiledPassIndex;
|
||||
|
||||
const RHI::ResourceStates accessState =
|
||||
ResolveRequiredState(sourcePass.type, access.mode);
|
||||
ResolveRequiredState(sourcePass.type, access.mode, access.aspect);
|
||||
if (!transitionPlan.hasFirstAccessState) {
|
||||
transitionPlan.hasFirstAccessState = true;
|
||||
transitionPlan.firstAccessState = accessState;
|
||||
|
||||
@@ -279,6 +279,17 @@ RenderGraphTextureDesc BuildTestTextureDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
RenderGraphTextureDesc BuildTestDepthTextureDesc() {
|
||||
RenderGraphTextureDesc desc = {};
|
||||
desc.width = 1024u;
|
||||
desc.height = 1024u;
|
||||
desc.format = static_cast<XCEngine::Core::uint32>(Format::D24_UNorm_S8_UInt);
|
||||
desc.textureType = static_cast<XCEngine::Core::uint32>(TextureType::Texture2D);
|
||||
desc.sampleCount = 1u;
|
||||
desc.sampleQuality = 0u;
|
||||
return desc;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(RenderGraph_Test, CompilesDeclaredPassOrderAndTracksTextureLifetimes) {
|
||||
@@ -533,6 +544,36 @@ TEST(RenderGraph_Test, RejectsGraphOwnedImportedTextureWithoutView) {
|
||||
EXPECT_FALSE(errorMessage.Empty());
|
||||
}
|
||||
|
||||
TEST(RenderGraph_Test, TracksDepthAttachmentTransitionPlan) {
|
||||
RenderGraph graph;
|
||||
RenderGraphBuilder builder(graph);
|
||||
|
||||
const RenderGraphTextureDesc depthDesc = BuildTestDepthTextureDesc();
|
||||
const RenderGraphTextureHandle depthTexture =
|
||||
builder.CreateTransientTexture("SceneDepth", depthDesc);
|
||||
|
||||
builder.AddRasterPass(
|
||||
"DepthPrepass",
|
||||
[&](RenderGraphPassBuilder& pass) {
|
||||
pass.WriteDepthTexture(depthTexture);
|
||||
});
|
||||
|
||||
CompiledRenderGraph compiledGraph;
|
||||
XCEngine::Containers::String errorMessage;
|
||||
ASSERT_TRUE(RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage))
|
||||
<< errorMessage.CStr();
|
||||
|
||||
RenderGraphTextureTransitionPlan transitionPlan = {};
|
||||
ASSERT_TRUE(compiledGraph.TryGetTextureTransitionPlan(depthTexture, transitionPlan));
|
||||
EXPECT_TRUE(transitionPlan.graphOwnsTransitions);
|
||||
EXPECT_TRUE(transitionPlan.hasFirstAccessState);
|
||||
EXPECT_TRUE(transitionPlan.hasLastAccessState);
|
||||
EXPECT_EQ(transitionPlan.initialState, ResourceStates::Common);
|
||||
EXPECT_EQ(transitionPlan.firstAccessState, ResourceStates::DepthWrite);
|
||||
EXPECT_EQ(transitionPlan.lastAccessState, ResourceStates::DepthWrite);
|
||||
EXPECT_EQ(transitionPlan.finalState, ResourceStates::DepthWrite);
|
||||
}
|
||||
|
||||
TEST(RenderGraph_Test, ExecutesCompiledPassCallbacksInCompiledOrder) {
|
||||
RenderGraph graph;
|
||||
RenderGraphBuilder builder(graph);
|
||||
|
||||
Reference in New Issue
Block a user