Support graph-owned imported texture transitions
This commit is contained in:
@@ -9,9 +9,11 @@ namespace Rendering {
|
||||
namespace {
|
||||
|
||||
bool IsGraphManagedTransientState(RHI::ResourceStates state) {
|
||||
return state == RHI::ResourceStates::RenderTarget ||
|
||||
return state == RHI::ResourceStates::Common ||
|
||||
state == RHI::ResourceStates::RenderTarget ||
|
||||
state == RHI::ResourceStates::PixelShaderResource ||
|
||||
state == RHI::ResourceStates::GenericRead;
|
||||
state == RHI::ResourceStates::GenericRead ||
|
||||
state == RHI::ResourceStates::Present;
|
||||
}
|
||||
|
||||
RenderGraphTextureViewType ResolveBarrierViewType(RHI::ResourceStates state) {
|
||||
@@ -42,6 +44,10 @@ public:
|
||||
for (size_t textureIndex = 0u; textureIndex < m_graph.m_textures.size(); ++textureIndex) {
|
||||
const CompiledRenderGraph::CompiledTexture& texture = m_graph.m_textures[textureIndex];
|
||||
const RenderGraphTextureLifetime& lifetime = m_graph.m_textureLifetimes[textureIndex];
|
||||
if (texture.kind == RenderGraphTextureKind::Imported) {
|
||||
m_textureStates[textureIndex] = texture.importedOptions.initialState;
|
||||
}
|
||||
|
||||
if (texture.kind != RenderGraphTextureKind::Transient || !lifetime.used) {
|
||||
continue;
|
||||
}
|
||||
@@ -110,6 +116,32 @@ public:
|
||||
m_graph.m_textures[handle.index].kind == RenderGraphTextureKind::Transient;
|
||||
}
|
||||
|
||||
bool TransitionGraphOwnedImportsToFinalStates(
|
||||
const RenderContext& renderContext,
|
||||
Containers::String* outErrorMessage) {
|
||||
for (size_t textureIndex = 0u; textureIndex < m_graph.m_textures.size(); ++textureIndex) {
|
||||
const CompiledRenderGraph::CompiledTexture& texture = m_graph.m_textures[textureIndex];
|
||||
if (texture.kind != RenderGraphTextureKind::Imported ||
|
||||
!texture.importedOptions.graphOwnsTransitions ||
|
||||
texture.importedView == nullptr ||
|
||||
textureIndex >= m_graph.m_textureLifetimes.size() ||
|
||||
!m_graph.m_textureLifetimes[textureIndex].used ||
|
||||
!IsGraphManagedTransientState(texture.importedOptions.finalState)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TransitionTexture(
|
||||
{ static_cast<Core::uint32>(textureIndex) },
|
||||
texture.importedOptions.finalState,
|
||||
renderContext,
|
||||
outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TransitionPassResources(
|
||||
const CompiledRenderGraph::CompiledPass& pass,
|
||||
const RenderContext& renderContext,
|
||||
@@ -117,41 +149,18 @@ public:
|
||||
for (const CompiledRenderGraph::CompiledTextureAccess& access : pass.accesses) {
|
||||
if (!access.texture.IsValid() ||
|
||||
access.texture.index >= m_graph.m_textures.size() ||
|
||||
!IsTransientTexture(access.texture) ||
|
||||
!ShouldGraphManageTransitions(access.texture) ||
|
||||
!IsGraphManagedTransientState(access.requiredState)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (renderContext.commandList == nullptr) {
|
||||
if (outErrorMessage != nullptr) {
|
||||
*outErrorMessage =
|
||||
Containers::String("RenderGraph cannot transition transient texture without a valid command list: ") +
|
||||
m_graph.m_textures[access.texture.index].name;
|
||||
}
|
||||
if (!TransitionTexture(
|
||||
access.texture,
|
||||
access.requiredState,
|
||||
renderContext,
|
||||
outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RHI::ResourceStates& currentState = m_textureStates[access.texture.index];
|
||||
if (currentState == access.requiredState) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RHI::RHIResourceView* resourceView =
|
||||
ResolveTextureView(access.texture, ResolveBarrierViewType(access.requiredState));
|
||||
if (resourceView == nullptr) {
|
||||
if (outErrorMessage != nullptr) {
|
||||
*outErrorMessage =
|
||||
Containers::String("RenderGraph cannot resolve transient texture view for state transition: ") +
|
||||
m_graph.m_textures[access.texture.index].name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
renderContext.commandList->TransitionBarrier(
|
||||
resourceView,
|
||||
currentState,
|
||||
access.requiredState);
|
||||
currentState = access.requiredState;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -164,6 +173,55 @@ private:
|
||||
RHI::RHIResourceView* shaderResourceView = nullptr;
|
||||
};
|
||||
|
||||
bool ShouldGraphManageTransitions(RenderGraphTextureHandle handle) const {
|
||||
if (!handle.IsValid() || handle.index >= m_graph.m_textures.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CompiledRenderGraph::CompiledTexture& texture = m_graph.m_textures[handle.index];
|
||||
return texture.kind == RenderGraphTextureKind::Transient ||
|
||||
(texture.kind == RenderGraphTextureKind::Imported &&
|
||||
texture.importedOptions.graphOwnsTransitions);
|
||||
}
|
||||
|
||||
bool TransitionTexture(
|
||||
RenderGraphTextureHandle handle,
|
||||
RHI::ResourceStates targetState,
|
||||
const RenderContext& renderContext,
|
||||
Containers::String* outErrorMessage) {
|
||||
if (renderContext.commandList == nullptr) {
|
||||
if (outErrorMessage != nullptr) {
|
||||
*outErrorMessage =
|
||||
Containers::String("RenderGraph cannot transition texture without a valid command list: ") +
|
||||
m_graph.m_textures[handle.index].name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RHI::ResourceStates& currentState = m_textureStates[handle.index];
|
||||
if (currentState == targetState) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RHI::RHIResourceView* resourceView =
|
||||
ResolveTextureView(handle, ResolveBarrierViewType(targetState));
|
||||
if (resourceView == nullptr) {
|
||||
if (outErrorMessage != nullptr) {
|
||||
*outErrorMessage =
|
||||
Containers::String("RenderGraph cannot resolve texture view for state transition: ") +
|
||||
m_graph.m_textures[handle.index].name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
renderContext.commandList->TransitionBarrier(
|
||||
resourceView,
|
||||
currentState,
|
||||
targetState);
|
||||
currentState = targetState;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DestroyTextureAllocation(TextureAllocation& allocation) {
|
||||
if (allocation.renderTargetView != nullptr) {
|
||||
allocation.renderTargetView->Shutdown();
|
||||
@@ -286,6 +344,12 @@ bool RenderGraphExecutor::Execute(
|
||||
}
|
||||
}
|
||||
|
||||
if (!runtimeResources.TransitionGraphOwnedImportsToFinalStates(
|
||||
renderContext,
|
||||
outErrorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user