diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 37c79f6a2..28fd00cd0 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -606,7 +606,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ResourceBarrier( if(pBarriers[i].Type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION || pBarriers[i].Transition.pResource) { - m_Cmd->m_BakedCmdListInfo[cmd].barriers.push_back(pBarriers[i]); + m_Cmd->m_BakedCmdListInfo[cmd].barriers.barriers.push_back(pBarriers[i]); } } } @@ -649,7 +649,7 @@ void WrappedID3D12GraphicsCommandList::ResourceBarrier(UINT NumBarriers, m_ListRecord->AddChunk(scope.Get(m_ListRecord->cmdInfo->alloc)); - m_ListRecord->cmdInfo->barriers.append(pBarriers, NumBarriers); + m_ListRecord->cmdInfo->barriers.barriers.append(pBarriers, NumBarriers); } } @@ -4456,10 +4456,42 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( UINT barrierCount = 2; - if(m_pDevice->GetSubresourceStates(GetResID(pArgumentBuffer))[0] & - D3D12_RESOURCE_STATE_COPY_SOURCE) + D3D12ResourceLayout layout = m_pDevice->GetSubresourceStates(GetResID(pArgumentBuffer))[0]; + // with new barriers (layouts) we don't need a layout change but we do need a new-style + // barrier + if(layout.IsLayout()) + { barrierCount = 1; + ID3D12GraphicsCommandList7 *list7 = GetCrackedList7(); + + if(list7) + { + D3D12_BUFFER_BARRIER buf; + buf.pResource = Unwrap(pArgumentBuffer); + buf.Offset = 0; + buf.Size = UINT64_MAX; + buf.SyncBefore = D3D12_BARRIER_SYNC_ALL; + buf.SyncAfter = D3D12_BARRIER_SYNC_COPY; + buf.AccessBefore = D3D12_BARRIER_ACCESS_COMMON; + buf.AccessAfter = D3D12_BARRIER_ACCESS_COPY_SOURCE; + + D3D12_BARRIER_GROUP group; + group.NumBarriers = 1; + group.Type = D3D12_BARRIER_TYPE_BUFFER; + group.pBufferBarriers = &buf; + list7->Barrier(1, &group); + } + else + { + RDCERR("Encountered new layout at ExecuteIndirect time but couldn't get cracked list 7"); + } + } + else if(layout.ToStates() & D3D12_RESOURCE_STATE_COPY_SOURCE) + { + barrierCount = 1; + } + cracked->ResourceBarrier(barrierCount, barriers); cracked->CopyBufferRegion(Unwrap(exec.argBuf), exec.argOffs, Unwrap(pArgumentBuffer), @@ -4469,6 +4501,29 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( std::swap(barriers[1].Transition.StateBefore, barriers[1].Transition.StateAfter); cracked->ResourceBarrier(barrierCount, barriers); + if(layout.IsLayout()) + { + ID3D12GraphicsCommandList7 *list7 = GetCrackedList7(); + + if(list7) + { + D3D12_BUFFER_BARRIER buf; + buf.pResource = Unwrap(pArgumentBuffer); + buf.Offset = 0; + buf.Size = UINT64_MAX; + buf.SyncBefore = D3D12_BARRIER_SYNC_COPY; + buf.SyncAfter = D3D12_BARRIER_SYNC_ALL; + buf.AccessBefore = D3D12_BARRIER_ACCESS_COPY_SOURCE; + buf.AccessAfter = D3D12_BARRIER_ACCESS_COMMON; + + D3D12_BARRIER_GROUP group; + group.NumBarriers = 1; + group.Type = D3D12_BARRIER_TYPE_BUFFER; + group.pBufferBarriers = &buf; + list7->Barrier(1, &group); + } + } + cracked->Close(); // open new cracked list and re-apply the current state @@ -5014,7 +5069,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_DiscardResource(SerialiserType m_pDevice->GetDebugManager()->FillWithDiscardPattern( m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID), m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state, DiscardType::DiscardCall, - pResource, pRegion); + pResource, pRegion, D3D12_BARRIER_LAYOUT_UNDEFINED); } } } diff --git a/renderdoc/driver/d3d12/d3d12_commands.h b/renderdoc/driver/d3d12/d3d12_commands.h index afd9ee446..581184dd2 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.h +++ b/renderdoc/driver/d3d12/d3d12_commands.h @@ -206,7 +206,7 @@ struct BakedCmdListInfo UINT nodeMask; D3D12RenderState state; - rdcarray barriers; + BarrierSet barriers; ResourceId parentList; diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index dbc759057..a32f87ba1 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -105,6 +105,153 @@ void D3D12MarkerRegion::End(ID3D12CommandQueue *queue) queue->EndEvent(); } +void BarrierSet::Configure(ID3D12Resource *res, const SubresourceStateVector &states, + AccessType access) +{ + bool allowCommon = false; + D3D12_RESOURCE_STATES resourceState; + D3D12_BARRIER_LAYOUT resourceLayout; + D3D12_BARRIER_ACCESS resourceAccess; + D3D12_BARRIER_SYNC resourceSync; + + // we assume wrapped resources + RDCASSERT(WrappedID3D12Resource::IsAlloc(res)); + + const bool isBuffer = (res->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER); + + switch(access) + { + case SRVAccess: + resourceState = D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE; + resourceLayout = D3D12_BARRIER_LAYOUT_SHADER_RESOURCE; + resourceAccess = D3D12_BARRIER_ACCESS_SHADER_RESOURCE; + resourceSync = D3D12_BARRIER_SYNC_ALL_SHADING; + // common layouts allow shader resource access with no layout change + allowCommon = true; + break; + case ResolveSourceAccess: + resourceState = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + resourceLayout = D3D12_BARRIER_LAYOUT_RESOLVE_SOURCE; + resourceAccess = D3D12_BARRIER_ACCESS_RESOLVE_SOURCE; + resourceSync = D3D12_BARRIER_SYNC_RESOLVE; + break; + default: + // should not happen but is the neatest solution to uninitialised variable warnings + case CopySourceAccess: + resourceState = D3D12_RESOURCE_STATE_COPY_SOURCE; + resourceLayout = D3D12_BARRIER_LAYOUT_COPY_SOURCE; + resourceAccess = D3D12_BARRIER_ACCESS_COPY_SOURCE; + resourceSync = D3D12_BARRIER_SYNC_COPY; + // common layouts allow shader resource access with no layout change + allowCommon = true; + break; + case CopyDestAccess: + resourceState = D3D12_RESOURCE_STATE_COPY_DEST; + resourceLayout = D3D12_BARRIER_LAYOUT_COPY_DEST; + resourceAccess = D3D12_BARRIER_ACCESS_COPY_DEST; + resourceSync = D3D12_BARRIER_SYNC_COPY; + // common layouts allow shader resource access with no layout change + allowCommon = true; + break; + } + + barriers.reserve(states.size()); + newBarriers.reserve(states.size()); + for(size_t i = 0; i < states.size(); i++) + { + if(states[i].IsStates()) + { + D3D12_RESOURCE_BARRIER b; + + b.Transition.StateBefore = states[i].ToStates(); + + // skip unneeded barriers + if((resourceState != D3D12_RESOURCE_STATE_COMMON && + (b.Transition.StateBefore & resourceState) == resourceState) || + b.Transition.StateBefore == resourceState) + continue; + + b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + b.Transition.pResource = res; + b.Transition.Subresource = (UINT)i; + b.Transition.StateAfter = resourceState; + + barriers.push_back(b); + } + // buffers don't need any transitions with the new layouts + else if(!isBuffer) + { + D3D12_TEXTURE_BARRIER b = {}; + + b.LayoutBefore = states[i].ToLayout(); + + // as long as the layout matches we don't need any extra access/sync since we're in a + // different command buffer. + if(b.LayoutBefore == resourceLayout || + (allowCommon && (b.LayoutBefore == D3D12_BARRIER_LAYOUT_COMMON || + b.LayoutBefore == D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON || + b.LayoutBefore == D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON))) + continue; + + b.AccessBefore = D3D12_BARRIER_ACCESS_COMMON; + b.SyncBefore = D3D12_BARRIER_SYNC_ALL; + b.AccessAfter = resourceAccess; + b.SyncAfter = resourceSync; + b.LayoutAfter = resourceLayout; + b.Flags = D3D12_TEXTURE_BARRIER_FLAG_NONE; + b.Subresources.IndexOrFirstMipLevel = (UINT)i; + b.pResource = res; + + newBarriers.push_back(b); + } + } +} + +void BarrierSet::Apply(ID3D12GraphicsCommandListX *list) +{ + D3D12_BARRIER_GROUP group; + group.NumBarriers = (UINT)newBarriers.size(); + group.Type = D3D12_BARRIER_TYPE_TEXTURE; + group.pTextureBarriers = newBarriers.data(); + + if(!barriers.empty()) + list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + // we unconditionally call new barriers, because they can only appear if a new layout was + // previously used (otherwise we stick to old states). This will only break if we're replaying + // a capture that used new layouts but new barrier support isn't present. + if(!newBarriers.empty()) + list->Barrier(1, &group); + if(!newToOldBarriers.empty()) + list->ResourceBarrier((UINT)newToOldBarriers.size(), &newToOldBarriers[0]); +} + +void BarrierSet::Unapply(ID3D12GraphicsCommandListX *list) +{ + D3D12_BARRIER_GROUP group; + group.NumBarriers = (UINT)newBarriers.size(); + group.Type = D3D12_BARRIER_TYPE_TEXTURE; + group.pTextureBarriers = newBarriers.data(); + + // real resource back to itself + for(size_t i = 0; i < barriers.size(); i++) + std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); + for(size_t i = 0; i < newBarriers.size(); i++) + { + std::swap(newBarriers[i].AccessBefore, newBarriers[i].AccessAfter); + std::swap(newBarriers[i].SyncBefore, newBarriers[i].SyncAfter); + std::swap(newBarriers[i].LayoutBefore, newBarriers[i].LayoutAfter); + } + + if(!barriers.empty()) + list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + if(!newBarriers.empty()) + list->Barrier(1, &group); + // if we had new-to-old barriers we should not ever be unapplying that barrier set as it's + // one-way. + RDCASSERT(newToOldBarriers.empty()); +} + bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface) { if(!getDebugInterface) diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index e0b8dca23..232e12dcc 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -125,6 +125,87 @@ BlendMultiplier MakeBlendMultiplier(D3D12_BLEND blend, bool alpha); BlendOperation MakeBlendOp(D3D12_BLEND_OP op); StencilOperation MakeStencilOp(D3D12_STENCIL_OP op); +// wrapper around D3D12_RESOURCE_STATES and D3D12_BARRIER_LAYOUT to handle resources that could be +// in either and varying support +struct D3D12ResourceLayout +{ + D3D12ResourceLayout() : value(0) + { + RDCCOMPILE_ASSERT(sizeof(*this) == sizeof(D3D12_BARRIER_LAYOUT), + "Layout/state wrapper is wrongly sized"); + RDCCOMPILE_ASSERT(sizeof(*this) == sizeof(D3D12_RESOURCE_STATES), + "Layout/state wrapper is wrongly sized"); + } + static D3D12ResourceLayout FromStates(D3D12_RESOURCE_STATES s) + { + return D3D12ResourceLayout((uint32_t)s); + } + static D3D12ResourceLayout FromLayout(D3D12_BARRIER_LAYOUT s) + { + return D3D12ResourceLayout(uint32_t(s) | LayoutBit); + } + bool IsLayout() const { return (value & LayoutBit) != 0; } + bool IsStates() const { return (value & LayoutBit) == 0; } + D3D12_RESOURCE_STATES ToStates() const { return D3D12_RESOURCE_STATES(value & ~LayoutBit); } + D3D12_BARRIER_LAYOUT ToLayout() const { return D3D12_BARRIER_LAYOUT(value & ~LayoutBit); } + bool operator==(const D3D12ResourceLayout &o) const { return value == o.value; } + bool operator!=(const D3D12ResourceLayout &o) const { return !(*this == o); } +private: + explicit D3D12ResourceLayout(uint32_t v) : value(v) {} + // layouts are an enum so this bit should hopefully never be used. Note that LAYOUT_UNDEFINED is + // ~0U but that's not valid except as a previous state for discards, it's not a layout anything + // can be put into so stored here. + // states are a bitmask but they only use just over 6 hex digits so far, and we assume they won't + // be extended (or not by much). + // We set the bit for layouts and not for states so that we can serialise this + // backwards-compatibly and replace any serialised D3D12_RESOURCE_STATES and have them appear as + // the correct enum. + static constexpr uint32_t LayoutBit = 0x80000000U; + uint32_t value; +}; + +typedef rdcarray SubresourceStateVector; + +struct BarrierSet +{ + enum AccessType + { + SRVAccess, + CopySourceAccess, + CopyDestAccess, + ResolveSourceAccess, + }; + + // set up the barriers to barrier this resource a given type of access + void Configure(ID3D12Resource *res, const SubresourceStateVector &states, AccessType access); + + // apply the barrier set onto this list + void Apply(ID3D12GraphicsCommandListX *list); + + // unapply the barrier set - used for when we are barrier'ing a resource, doing some work, then + // barrier'ing it back to the original state + void Unapply(ID3D12GraphicsCommandListX *list); + + void clear() + { + barriers.clear(); + newBarriers.clear(); + newToOldBarriers.clear(); + } + bool empty() const { return barriers.empty() && newBarriers.empty(); } + void swap(BarrierSet &other) + { + barriers.swap(other.barriers); + newBarriers.swap(other.newBarriers); + } + + rdcarray barriers; + rdcarray newBarriers; + // these are used specifically when we need to record a transition from a new layout to an old + // state. Because we execute barriers before newBarriers we can do the other way without this + rdcarray newToOldBarriers; +}; + // similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the // debugbreak. #define D3D12NOTIMP(...) \ @@ -689,6 +770,11 @@ DECLARE_REFLECTION_ENUM(D3D12_DESCRIPTOR_RANGE_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_TILE_COPY_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_TILE_RANGE_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_TILE_MAPPING_FLAGS); +DECLARE_REFLECTION_ENUM(D3D12_BARRIER_ACCESS); +DECLARE_REFLECTION_ENUM(D3D12_BARRIER_SYNC); +DECLARE_REFLECTION_ENUM(D3D12_BARRIER_LAYOUT); +DECLARE_REFLECTION_ENUM(D3D12_BARRIER_TYPE); +DECLARE_REFLECTION_ENUM(D3D12_TEXTURE_BARRIER_FLAGS); DECLARE_REFLECTION_STRUCT(D3D12_RESOURCE_DESC); DECLARE_REFLECTION_STRUCT(D3D12_COMMAND_QUEUE_DESC); @@ -799,6 +885,12 @@ DECLARE_REFLECTION_STRUCT(D3D12_ROOT_CONSTANTS); DECLARE_REFLECTION_STRUCT(D3D12_ROOT_DESCRIPTOR1); DECLARE_REFLECTION_STRUCT(D3D12_RESOURCE_DESC1); DECLARE_REFLECTION_STRUCT(D3D12_MIP_REGION); +DECLARE_REFLECTION_STRUCT(D3D12_BARRIER_SUBRESOURCE_RANGE); +DECLARE_REFLECTION_STRUCT(D3D12_BUFFER_BARRIER); +DECLARE_REFLECTION_STRUCT(D3D12_TEXTURE_BARRIER); +DECLARE_REFLECTION_STRUCT(D3D12_GLOBAL_BARRIER); +DECLARE_REFLECTION_STRUCT(D3D12_BARRIER_GROUP); +DECLARE_REFLECTION_STRUCT(D3D12ResourceLayout); DECLARE_DESERIALISE_TYPE(D3D12_DISCARD_REGION); DECLARE_DESERIALISE_TYPE(D3D12_GRAPHICS_PIPELINE_STATE_DESC); @@ -807,6 +899,7 @@ DECLARE_DESERIALISE_TYPE(D3D12_COMMAND_SIGNATURE_DESC); DECLARE_DESERIALISE_TYPE(D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC); DECLARE_DESERIALISE_TYPE(D3D12_RENDER_PASS_RENDER_TARGET_DESC); DECLARE_DESERIALISE_TYPE(D3D12_RENDER_PASS_DEPTH_STENCIL_DESC); +DECLARE_DESERIALISE_TYPE(D3D12_BARRIER_GROUP); enum class D3D12Chunk : uint32_t { diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index d049e92dc..678c5878e 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -391,9 +391,18 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) fmt.compType = CompType::UInt; pattern.append(GetDiscardPattern(DiscardType::DiscardCall, fmt)); - m_DiscardConstants = MakeCBuffer(pattern.size()); + m_DiscardConstantsDiscard = MakeCBuffer(pattern.size()); m_pDevice->InternalRef(); - FillBuffer(m_DiscardConstants, 0, pattern.data(), pattern.size()); + FillBuffer(m_DiscardConstantsDiscard, 0, pattern.data(), pattern.size()); + + fmt.compType = CompType::Float; + pattern = GetDiscardPattern(DiscardType::UndefinedTransition, fmt); + fmt.compType = CompType::UInt; + pattern.append(GetDiscardPattern(DiscardType::UndefinedTransition, fmt)); + + m_DiscardConstantsUndefined = MakeCBuffer(pattern.size()); + m_pDevice->InternalRef(); + FillBuffer(m_DiscardConstantsUndefined, 0, pattern.data(), pattern.size()); ID3DBlob *root = shaderCache->MakeRootSig({ cbvParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 0), @@ -457,7 +466,8 @@ D3D12DebugManager::~D3D12DebugManager() SAFE_RELEASE(m_TexResource); - SAFE_RELEASE(m_DiscardConstants); + SAFE_RELEASE(m_DiscardConstantsDiscard); + SAFE_RELEASE(m_DiscardConstantsUndefined); SAFE_RELEASE(m_DiscardRootSig); SAFE_RELEASE(m_DiscardFloatPS); SAFE_RELEASE(m_DiscardIntPS); @@ -854,9 +864,10 @@ void D3D12DebugManager::ResetDebugAlloc() void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, const D3D12RenderState &state, DiscardType type, ID3D12Resource *res, - const D3D12_DISCARD_REGION *region) + const D3D12_DISCARD_REGION *region, + D3D12_BARRIER_LAYOUT LayoutAfter) { - RDCASSERT(type == DiscardType::DiscardCall); + RDCASSERT(type == DiscardType::DiscardCall || type == DiscardType::UndefinedTransition); D3D12MarkerRegion marker( cmd, StringFormat::Fmt("FillWithDiscardPattern %s", ToStr(GetResID(res)).c_str())); @@ -1032,7 +1043,9 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); cmd->SetPipelineState(pipe); cmd->SetGraphicsRootSignature(m_DiscardRootSig); - cmd->SetGraphicsRootConstantBufferView(0, m_DiscardConstants->GetGPUVirtualAddress()); + cmd->SetGraphicsRootConstantBufferView( + 0, type == DiscardType::DiscardCall ? m_DiscardConstantsDiscard->GetGPUVirtualAddress() + : m_DiscardConstantsUndefined->GetGPUVirtualAddress()); D3D12_VIEWPORT viewport = {0, 0, (float)desc.Width, (float)desc.Height, 0.0f, 1.0f}; cmd->RSSetViewports(1, &viewport); @@ -1116,7 +1129,7 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, static const uint32_t PatternBatchHeight = 256; // see if we already have a buffer with texels in the desired format, if not then create it - ID3D12Resource *buf = m_DiscardPatterns[desc.Format]; + ID3D12Resource *buf = m_DiscardPatterns[{type, desc.Format}]; if(buf == NULL) { @@ -1180,7 +1193,7 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, buf->Unmap(0, NULL); } - m_DiscardPatterns[desc.Format] = buf; + m_DiscardPatterns[{type, desc.Format}] = buf; } for(UINT sub = firstSub; sub < firstSub + numSubs; sub++) @@ -1198,7 +1211,36 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, b.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; b.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - cmd->ResourceBarrier(1, &b); + + D3D12_TEXTURE_BARRIER tex = {}; + D3D12_BARRIER_GROUP group = {}; + + if(m_pDevice->GetOpts12().EnhancedBarriersSupported) + { + // with new barriers we can explicitly discard here instead of guessing StateBefore, though we + // still need to guess a LayoutAfter once we're done for DiscardResource() calls + + tex.LayoutBefore = D3D12_BARRIER_LAYOUT_UNDEFINED; + tex.AccessBefore = D3D12_BARRIER_ACCESS_NO_ACCESS; + tex.SyncBefore = D3D12_BARRIER_SYNC_ALL; + tex.LayoutAfter = D3D12_BARRIER_LAYOUT_COPY_DEST; + tex.AccessAfter = D3D12_BARRIER_ACCESS_COPY_DEST; + tex.SyncAfter = D3D12_BARRIER_SYNC_COPY; + + tex.Flags = D3D12_TEXTURE_BARRIER_FLAG_DISCARD; + tex.Subresources.IndexOrFirstMipLevel = (UINT)sub; + tex.pResource = res; + + group.NumBarriers = 1; + group.Type = D3D12_BARRIER_TYPE_TEXTURE; + group.pTextureBarriers = &tex; + + cmd->Barrier(1, &group); + } + else + { + cmd->ResourceBarrier(1, &b); + } D3D12_TEXTURE_COPY_LOCATION dst, src; @@ -1260,9 +1302,36 @@ void D3D12DebugManager::FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, } } - std::swap(b.Transition.StateBefore, b.Transition.StateAfter); + if(group.NumBarriers > 0) + { + tex.LayoutBefore = D3D12_BARRIER_LAYOUT_COPY_DEST; + tex.AccessBefore = D3D12_BARRIER_ACCESS_COPY_DEST; + tex.SyncBefore = D3D12_BARRIER_SYNC_COPY; + tex.LayoutAfter = LayoutAfter; + tex.AccessAfter = D3D12_BARRIER_ACCESS_COMMON; + tex.SyncAfter = D3D12_BARRIER_SYNC_ALL; + tex.Flags = D3D12_TEXTURE_BARRIER_FLAG_NONE; - cmd->ResourceBarrier(1, &b); + if(LayoutAfter == D3D12_BARRIER_LAYOUT_UNDEFINED) + { + // still need to guess, oops. + // since we don't know if the user will use old or new barriers we transition to common so + // that it's hopefully as suitable as possible for possible interactions. There is no single + // legal layout we can transition to, but we err on the side of assuming that calls to + // DiscardResource (where an undefined LayoutAfter would happen) will be used with old + // states, since new layouts have a built-in discard function with undefined transitions. So + // transitioning to common makes it more compatible with an old barrier after that + tex.LayoutAfter = D3D12_BARRIER_LAYOUT_COMMON; + } + + cmd->Barrier(1, &group); + } + else + { + std::swap(b.Transition.StateBefore, b.Transition.StateAfter); + + cmd->ResourceBarrier(1, &b); + } // workaround possible nvidia driver bug? without this depth-stencil discards of only one region // (smaller than 256x256) will get corrupted if both depth and stencil are copied to. @@ -1526,11 +1595,15 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u D3D12_RESOURCE_BARRIER barrier = {}; + D3D12ResourceLayout layout = m_pDevice->GetSubresourceStates(GetResID(buffer))[0]; + barrier.Transition.pResource = buffer; - barrier.Transition.StateBefore = m_pDevice->GetSubresourceStates(GetResID(buffer))[0]; + barrier.Transition.StateBefore = layout.ToStates(); barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - if(barrier.Transition.StateBefore != D3D12_RESOURCE_STATE_COPY_SOURCE) + // new layouts guarantee that buffers are safe to use in a new list like this with no barrier, so + // only barrier for old states + if(layout.IsStates() && (barrier.Transition.StateBefore & D3D12_RESOURCE_STATE_COPY_SOURCE) == 0) m_DebugList->ResourceBarrier(1, &barrier); while(length > 0) @@ -1572,7 +1645,7 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u m_DebugList->Reset(m_DebugAlloc, NULL); } - if(barrier.Transition.StateBefore != D3D12_RESOURCE_STATE_COPY_SOURCE) + if(layout.IsStates() && (barrier.Transition.StateBefore & D3D12_RESOURCE_STATE_COPY_SOURCE) == 0) { std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter); diff --git a/renderdoc/driver/d3d12/d3d12_debug.h b/renderdoc/driver/d3d12/d3d12_debug.h index 81b551725..7668e1896 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.h +++ b/renderdoc/driver/d3d12/d3d12_debug.h @@ -153,7 +153,7 @@ public: void FillWithDiscardPattern(ID3D12GraphicsCommandListX *cmd, const D3D12RenderState &state, DiscardType type, ID3D12Resource *res, - const D3D12_DISCARD_REGION *region); + const D3D12_DISCARD_REGION *region, D3D12_BARRIER_LAYOUT LayoutAfter); D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle(CBVUAVSRVSlot slot); D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle(RTVSlot slot); @@ -173,7 +173,7 @@ public: D3D12_CPU_DESCRIPTOR_HANDLE GetUAVClearHandle(CBVUAVSRVSlot slot); void PrepareTextureSampling(ID3D12Resource *resource, CompType typeCast, int &resType, - rdcarray &barriers); + BarrierSet &barrierSet); MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary); @@ -245,11 +245,12 @@ private: // Discard pattern rendering ID3DBlob *m_DiscardFloatPS = NULL; ID3DBlob *m_DiscardIntPS = NULL; - ID3D12Resource *m_DiscardConstants = NULL; + ID3D12Resource *m_DiscardConstantsDiscard = NULL; + ID3D12Resource *m_DiscardConstantsUndefined = NULL; ID3D12RootSignature *m_DiscardRootSig = NULL; std::map, ID3D12PipelineState *> m_DiscardPipes; - std::map m_DiscardPatterns; + std::map, ID3D12Resource *> m_DiscardPatterns; rdcarray m_DiscardBuffers; }; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 5b5da28d1..cb7663da9 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -526,6 +526,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara RDCEraseEl(m_D3D12Opts2); RDCEraseEl(m_D3D12Opts3); RDCEraseEl(m_D3D12Opts6); + RDCEraseEl(m_D3D12Opts12); RDCEraseEl(m_D3D12Opts14); RDCEraseEl(m_D3D12Opts15); RDCEraseEl(m_D3D12Opts16); @@ -595,6 +596,10 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara sizeof(m_D3D12Opts6)); if(hr != S_OK) RDCEraseEl(m_D3D12Opts6); + hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &m_D3D12Opts12, + sizeof(m_D3D12Opts12)); + if(hr != S_OK) + RDCEraseEl(m_D3D12Opts12); hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &m_D3D12Opts14, sizeof(m_D3D12Opts14)); if(hr != S_OK) @@ -1551,7 +1556,7 @@ void WrappedID3D12Device::FirstFrame(IDXGISwapper *swapper) } } -void WrappedID3D12Device::ApplyBarriers(rdcarray &barriers) +void WrappedID3D12Device::ApplyBarriers(BarrierSet &barriers) { SCOPED_LOCK(m_ResourceStatesLock); GetResourceManager()->ApplyBarriers(barriers, m_ResourceStates); @@ -1662,7 +1667,7 @@ bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser, IDX SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states = {D3D12_RESOURCE_STATE_PRESENT}; + states = {D3D12ResourceLayout::FromStates(D3D12_RESOURCE_STATE_PRESENT)}; } } @@ -1724,7 +1729,7 @@ IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_F SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[id]; - states = {D3D12_RESOURCE_STATE_PRESENT}; + states = {D3D12ResourceLayout::FromStates(D3D12_RESOURCE_STATE_PRESENT)}; } } else @@ -2422,7 +2427,7 @@ bool WrappedID3D12Device::Serialise_CaptureScope(SerialiserType &ser) template bool WrappedID3D12Device::Serialise_BeginCaptureFrame(SerialiserType &ser) { - rdcarray barriers; + BarrierSet barriers; if(IsReplayingAndReading() && IsLoading(m_State)) { @@ -2442,11 +2447,11 @@ bool WrappedID3D12Device::Serialise_BeginCaptureFrame(SerialiserType &ser) if(IsReplayingAndReading() && !barriers.empty()) { // apply initial resource states - ID3D12GraphicsCommandList *list = GetNewList(); + ID3D12GraphicsCommandListX *list = GetNewList(); if(!list) return false; - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->Close(); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index f0759c071..59cbd52f5 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -785,6 +785,7 @@ private: D3D12_FEATURE_DATA_D3D12_OPTIONS2 m_D3D12Opts2; D3D12_FEATURE_DATA_D3D12_OPTIONS3 m_D3D12Opts3; D3D12_FEATURE_DATA_D3D12_OPTIONS6 m_D3D12Opts6; + D3D12_FEATURE_DATA_D3D12_OPTIONS12 m_D3D12Opts12; D3D12_FEATURE_DATA_D3D12_OPTIONS14 m_D3D12Opts14; D3D12_FEATURE_DATA_D3D12_OPTIONS15 m_D3D12Opts15; D3D12_FEATURE_DATA_D3D12_OPTIONS16 m_D3D12Opts16; @@ -819,6 +820,7 @@ public: const D3D12_FEATURE_DATA_D3D12_OPTIONS2 &GetOpts2() { return m_D3D12Opts2; } const D3D12_FEATURE_DATA_D3D12_OPTIONS3 &GetOpts3() { return m_D3D12Opts3; } const D3D12_FEATURE_DATA_D3D12_OPTIONS6 &GetOpts6() { return m_D3D12Opts6; } + const D3D12_FEATURE_DATA_D3D12_OPTIONS12 &GetOpts12() { return m_D3D12Opts12; } const D3D12_FEATURE_DATA_D3D12_OPTIONS14 &GetOpts14() { return m_D3D12Opts14; } const D3D12_FEATURE_DATA_D3D12_OPTIONS15 &GetOpts15() { return m_D3D12Opts15; } const D3D12_FEATURE_DATA_D3D12_OPTIONS16 &GetOpts16() { return m_D3D12Opts16; } @@ -873,10 +875,7 @@ public: void AddResourceCurChunk(ResourceId id); bool UsedDXIL() { return m_UsedDXIL; } - rdcarray &GetSubresourceStates(ResourceId id) - { - return m_ResourceStates[id]; - } + SubresourceStateVector &GetSubresourceStates(ResourceId id) { return m_ResourceStates[id]; } const std::map &GetSubresourceStates() { return m_ResourceStates; @@ -901,7 +900,7 @@ public: const rdcarray &GetQueues() { return m_Queues; } ID3D12CommandAllocator *GetAlloc() { return m_Alloc; } ID3D12InfoQueue *GetInfoQueue() { return m_pInfoQueue; } - void ApplyBarriers(rdcarray &barriers); + void ApplyBarriers(BarrierSet &barriers); void GetDynamicDescriptorReferences(rdcarray &refs) { diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 1c1ffcfff..eee8aa2ac 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -1517,7 +1517,8 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource( m_ModResources.insert(GetResID(ret)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc), + D3D12ResourceLayout::FromStates(InitialResourceState)); ResourceType type = ResourceType::Texture; const char *prefix = "Texture"; @@ -1638,7 +1639,8 @@ HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states.fill(GetNumSubresources(m_pDevice, pDesc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, pDesc), + D3D12ResourceLayout::FromStates(InitialResourceState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } @@ -1847,7 +1849,8 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource( m_ModResources.insert(GetResID(ret)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &Descriptor), InitialState); + states.fill(GetNumSubresources(m_pDevice, &Descriptor), + D3D12ResourceLayout::FromStates(InitialState)); } ResourceType type = ResourceType::Texture; @@ -1962,7 +1965,8 @@ HRESULT WrappedID3D12Device::CreatePlacedResource(ID3D12Heap *pHeap, UINT64 Heap SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states.fill(GetNumSubresources(m_pDevice, pDesc), InitialState); + states.fill(GetNumSubresources(m_pDevice, pDesc), + D3D12ResourceLayout::FromStates(InitialState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } @@ -2058,7 +2062,8 @@ bool WrappedID3D12Device::Serialise_CreateReservedResource( m_ModResources.insert(GetResID(ret)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &Descriptor), InitialState); + states.fill(GetNumSubresources(m_pDevice, &Descriptor), + D3D12ResourceLayout::FromStates(InitialState)); } m_SparseResources.insert(GetResID(ret)); @@ -2205,7 +2210,8 @@ HRESULT WrappedID3D12Device::CreateReservedResource(const D3D12_RESOURCE_DESC *p SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states.fill(GetNumSubresources(m_pDevice, pDesc), InitialState); + states.fill(GetNumSubresources(m_pDevice, pDesc), + D3D12ResourceLayout::FromStates(InitialState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } @@ -2891,7 +2897,8 @@ bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE m_ModResources.insert(GetResID(ret)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc), + D3D12ResourceLayout::FromStates(InitialResourceState)); ResourceType type = ResourceType::Texture; const char *prefix = "Texture"; @@ -3162,7 +3169,8 @@ HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states.fill(GetNumSubresources(m_pDevice, &desc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc), + D3D12ResourceLayout::FromStates(InitialResourceState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp index b59ffd0e4..9d45af50d 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp @@ -316,7 +316,8 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource1( m_ModResources.insert(GetResID(ret)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc), + D3D12ResourceLayout::FromStates(InitialResourceState)); ResourceType type = ResourceType::Texture; const char *prefix = "Texture"; @@ -435,7 +436,8 @@ HRESULT WrappedID3D12Device::CreateCommittedResource1( SCOPED_LOCK(m_ResourceStatesLock); SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - states.fill(GetNumSubresources(m_pDevice, pDesc), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, pDesc), + D3D12ResourceLayout::FromStates(InitialResourceState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp index 1b56d7297..1b006cb9b 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp @@ -126,7 +126,8 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource2( // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 D3D12_RESOURCE_DESC desc0; memcpy(&desc0, &desc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc0), + D3D12ResourceLayout::FromStates(InitialResourceState)); ResourceType type = ResourceType::Texture; const char *prefix = "Texture"; @@ -251,7 +252,8 @@ HRESULT WrappedID3D12Device::CreateCommittedResource2( // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 D3D12_RESOURCE_DESC desc0; memcpy(&desc0, pDesc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), InitialResourceState); + states.fill(GetNumSubresources(m_pDevice, &desc0), + D3D12ResourceLayout::FromStates(InitialResourceState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } @@ -370,7 +372,8 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource1( D3D12_RESOURCE_DESC desc0; memcpy(&desc0, &Descriptor, sizeof(desc0)); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc0), InitialState); + states.fill(GetNumSubresources(m_pDevice, &desc0), + D3D12ResourceLayout::FromStates(InitialState)); } ResourceType type = ResourceType::Texture; @@ -490,7 +493,8 @@ HRESULT WrappedID3D12Device::CreatePlacedResource1(ID3D12Heap *pHeap, UINT64 Hea // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 D3D12_RESOURCE_DESC desc0; memcpy(&desc0, pDesc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), InitialState); + states.fill(GetNumSubresources(m_pDevice, &desc0), + D3D12ResourceLayout::FromStates(InitialState)); m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); } diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index d1b989f27..86ab35eb9 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -113,12 +113,14 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) if(nonresident) m_Device->GetReal()->MakeResident(1, &unwrappedPageable); - const rdcarray &states = m_Device->GetSubresourceStates(GetResID(res)); + const SubresourceStateVector &states = m_Device->GetSubresourceStates(GetResID(res)); RDCASSERT(states.size() == 1); D3D12_RESOURCE_BARRIER barrier; - const bool needsTransition = - !isUploadHeap && ((states[0] & D3D12_RESOURCE_STATE_COPY_SOURCE) == 0); + // upload heap resources can't be transitioned, and any resources in the new layouts don't + // need to either since each submit does a big flush + const bool needsTransition = !isUploadHeap && states[0].IsStates() && + (states[0].ToStates() & D3D12_RESOURCE_STATE_COPY_SOURCE) == 0; if(needsTransition) { @@ -126,7 +128,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; barrier.Transition.pResource = r->GetReal(); barrier.Transition.Subresource = (UINT)0; - barrier.Transition.StateBefore = states[0]; + barrier.Transition.StateBefore = states[0].ToStates(); barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; } @@ -176,7 +178,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) m_Device->GetReal()->MakeResident(1, &unwrappedPageable); ID3D12Resource *arrayTexture = NULL; - D3D12_RESOURCE_STATES destState = D3D12_RESOURCE_STATE_COPY_SOURCE; + BarrierSet::AccessType accessType = BarrierSet::CopySourceAccess; ID3D12Resource *unwrappedCopySource = r->GetReal(); bool isDepth = @@ -210,39 +212,16 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) __uuidof(ID3D12Resource), (void **)&arrayTexture); RDCASSERTEQUAL(hr, S_OK); - destState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + accessType = BarrierSet::SRVAccess; isMSAA = true; } - ID3D12GraphicsCommandList *list = Unwrap(m_Device->GetInitialStateList()); + ID3D12GraphicsCommandListX *list = m_Device->GetInitialStateList(); - rdcarray barriers; + BarrierSet barriers; - { - const rdcarray &states = m_Device->GetSubresourceStates(GetResID(r)); - - barriers.reserve(states.size()); - - for(size_t i = 0; i < states.size(); i++) - { - if(states[i] & destState) - continue; - - D3D12_RESOURCE_BARRIER barrier; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = r->GetReal(); - barrier.Transition.Subresource = (UINT)i; - barrier.Transition.StateBefore = states[i]; - barrier.Transition.StateAfter = destState; - - barriers.push_back(barrier); - } - - // transition to copy dest - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); - } + barriers.Configure(r, m_Device->GetSubresourceStates(GetResID(r)), accessType); + barriers.Apply(list); if(arrayTexture) { @@ -256,7 +235,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) m_Device->GetDebugManager()->CopyTex2DMSToArray(NULL, arrayTexture, r->GetReal()); // open the initial state list again for the remainder of the work - list = Unwrap(m_Device->GetInitialStateList()); + list = m_Device->GetInitialStateList(); D3D12_RESOURCE_BARRIER b = {}; b.Transition.pResource = arrayTexture; @@ -264,7 +243,8 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) b.Transition.StateBefore = isDepth ? D3D12_RESOURCE_STATE_DEPTH_WRITE : D3D12_RESOURCE_STATE_RENDER_TARGET; b.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - list->ResourceBarrier(1, &b); + // arrayTexture is not wrapped so we need to call the unwrapped command directly + Unwrap(list)->ResourceBarrier(1, &b); unwrappedCopySource = arrayTexture; } @@ -338,7 +318,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) dst.pResource = copyDst; dst.PlacedFootprint = copyLayouts[i]; - list->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL); + Unwrap(list)->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL); } } else @@ -353,11 +333,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) subresources = {~0U}; // transition back - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); if(nonresident || arrayTexture) { @@ -1093,7 +1069,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, } else if(data.tag == D3D12InitialContents::Copy || data.tag == D3D12InitialContents::ForceCopy) { - ID3D12Resource *copyDst = Unwrap((ID3D12Resource *)live); + ID3D12Resource *copyDst = (ID3D12Resource *)live; if(!copyDst) { @@ -1138,7 +1114,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, if(copyDst->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { - hr = copyDst->Map(0, NULL, (void **)&dst); + hr = Unwrap(copyDst)->Map(0, NULL, (void **)&dst); m_Device->CheckHRESULT(hr); if(FAILED(hr)) @@ -1151,7 +1127,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, memcpy(dst, src, (size_t)copyDst->GetDesc().Width); if(dst) - copyDst->Unmap(0, NULL); + Unwrap(copyDst)->Unmap(0, NULL); } else { @@ -1171,7 +1147,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, for(UINT i = 0; i < numSubresources; i++) { - hr = copyDst->Map(i, NULL, (void **)&dst); + hr = Unwrap(copyDst)->Map(i, NULL, (void **)&dst); m_Device->CheckHRESULT(hr); if(FAILED(hr)) @@ -1198,7 +1174,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, } if(dst) - copyDst->Unmap(i, NULL); + Unwrap(copyDst)->Unmap(i, NULL); } delete[] layouts; @@ -1216,51 +1192,29 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, return; } - ID3D12GraphicsCommandList *list = Unwrap(m_Device->GetInitialStateList()); + ID3D12GraphicsCommandListX *list = m_Device->GetInitialStateList(); if(!list) return; - rdcarray barriers; + BarrierSet barriers; - const rdcarray &states = - m_Device->GetSubresourceStates(GetResID(live)); - - barriers.reserve(states.size()); - - for(size_t i = 0; i < states.size(); i++) - { - if(states[i] & D3D12_RESOURCE_STATE_COPY_DEST) - continue; - - D3D12_RESOURCE_BARRIER barrier; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = copyDst; - barrier.Transition.Subresource = (UINT)i; - barrier.Transition.StateBefore = states[i]; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - - barriers.push_back(barrier); - } - - // transition to copy dest - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Configure(copyDst, m_Device->GetSubresourceStates(GetResID(live)), + BarrierSet::CopyDestAccess); + barriers.Apply(list); if(copyDst->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { D3D12_RESOURCE_DESC srcDesc = copySrc->GetDesc(); D3D12_RESOURCE_DESC dstDesc = copyDst->GetDesc(); - list->CopyBufferRegion(copyDst, 0, Unwrap(copySrc), 0, - RDCMIN(srcDesc.Width, dstDesc.Width)); + list->CopyBufferRegion(copyDst, 0, copySrc, 0, RDCMIN(srcDesc.Width, dstDesc.Width)); } else if(copyDst->GetDesc().SampleDesc.Count > 1 || data.tag == D3D12InitialContents::ForceCopy) { // MSAA texture was pre-uploaded and decoded, just copy the texture. // Similarly for created initial states - list->CopyResource(copyDst, Unwrap(copySrc)); + list->CopyResource(copyDst, copySrc); } else { @@ -1307,7 +1261,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, dst.SubresourceIndex = i; src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - src.pResource = Unwrap(copySrc); + src.pResource = copySrc; m_Device->GetCopyableFootprints(&desc, i, 1, offset, &src.PlacedFootprint, NULL, NULL, &subSize); @@ -1327,12 +1281,7 @@ void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, } } - // transition back to whatever it was before - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); if(D3D12_Debug_SingleSubmitFlushing()) { diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 16e3c6cc2..a07a98465 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -682,42 +682,198 @@ D3D12Descriptor *DescriptorFromPortableHandle(D3D12ResourceManager *manager, Por #define BARRIER_ASSERT(...) #endif -void D3D12ResourceManager::ApplyBarriers(rdcarray &barriers, +void D3D12ResourceManager::ApplyBarriers(BarrierSet &barriers, std::map &states) { - for(size_t b = 0; b < barriers.size(); b++) + for(size_t b = 0; b < barriers.barriers.size(); b++) { - D3D12_RESOURCE_TRANSITION_BARRIER &trans = barriers[b].Transition; + const D3D12_RESOURCE_TRANSITION_BARRIER &trans = barriers.barriers[b].Transition; ResourceId id = GetResID(trans.pResource); SubresourceStateVector &st = states[id]; // skip non-transitions, or begin-halves of transitions - if(barriers[b].Type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION || - (barriers[b].Flags & D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY)) + if(barriers.barriers[b].Type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION || + (barriers.barriers[b].Flags & D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY)) continue; + size_t first = trans.Subresource; if(trans.Subresource == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + first = 0; + + for(size_t i = first; i < st.size(); i++) { - for(size_t i = 0; i < st.size(); i++) + // layout must either match StateBefore or else be in the common layout + BARRIER_ASSERT("Mismatching before state", + (st[i].IsStates() && st[i].ToStates() == trans.StateBefore) || + (st[i].IsLayout() && st[i].ToLayout() == D3D12_BARRIER_LAYOUT_COMMON), + st[i], trans.StateBefore, i); + st[i] = D3D12ResourceLayout::FromStates(trans.StateAfter); + + if(trans.Subresource != D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + break; + } + } + + for(size_t b = 0; b < barriers.newBarriers.size(); b++) + { + const D3D12_TEXTURE_BARRIER &trans = barriers.newBarriers[b]; + ResourceId id = GetResID(trans.pResource); + SubresourceStateVector &st = states[id]; + + // skip begin-halves of split transitions + if(trans.SyncBefore == D3D12_BARRIER_SYNC_SPLIT) + continue; + + if(trans.Subresources.NumMipLevels == 0) + { + size_t first = 0; + if(trans.Subresources.IndexOrFirstMipLevel == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + first = 0; + + for(size_t sub = first; sub < st.size(); sub++) { - BARRIER_ASSERT("Mismatching before state", st[i] == trans.StateBefore, st[i], - trans.StateBefore, i); - st[i] = trans.StateAfter; + // layout must either match StateBefore, be undefined, or else be in the common state + BARRIER_ASSERT("Mismatching before state", + (st[sub].IsLayout() && st[sub].ToLayout() == trans.LayoutBefore) || + trans.LayoutBefore == D3D12_BARRIER_LAYOUT_UNDEFINED || + (st[sub].IsStates() && st[sub].ToStates() == D3D12_RESOURCE_STATE_COMMON), + st[sub], trans.LayoutBefore, sub); + st[sub] = D3D12ResourceLayout::FromLayout(trans.LayoutAfter); + + if(trans.Subresources.IndexOrFirstMipLevel != D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + break; + } + } + + D3D12_RESOURCE_DESC desc = trans.pResource->GetDesc(); + + UINT arrays = RDCMAX((UINT16)1, desc.DepthOrArraySize); + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + arrays = 1; + UINT mips = RDCMAX((UINT16)1, desc.MipLevels); + + for(UINT p = trans.Subresources.FirstPlane; p < trans.Subresources.NumPlanes; p++) + { + for(UINT a = trans.Subresources.FirstArraySlice; a < trans.Subresources.NumArraySlices; a++) + { + for(UINT m = trans.Subresources.IndexOrFirstMipLevel; m < trans.Subresources.NumMipLevels; m++) + { + UINT sub = ((p * arrays) + a) * mips + m; + + // layout must either match StateBefore, be undefined, or else be in the common state + BARRIER_ASSERT( + "Mismatching before state", + (st[sub].IsLayout() && st[sub].ToLayout() == trans.LayoutBefore) || + trans.LayoutBefore == D3D12_BARRIER_LAYOUT_UNDEFINED || + (st[sub].IsStates() && st[sub].ToStates() == D3D12_RESOURCE_STATE_COMMON), + st[sub], trans.LayoutBefore, sub); + st[sub] = D3D12ResourceLayout::FromLayout(trans.LayoutAfter); + } + } + } + } +} + +void AddStateResetBarrier(D3D12ResourceLayout srcState, D3D12ResourceLayout dstState, + ID3D12Resource *res, UINT subresource, BarrierSet &barriers) +{ + if(srcState.IsStates() && dstState.IsStates()) + { + D3D12_RESOURCE_BARRIER b; + b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + b.Transition.pResource = res; + b.Transition.Subresource = (UINT)subresource; + b.Transition.StateBefore = srcState.ToStates(); + b.Transition.StateAfter = dstState.ToStates(); + + barriers.barriers.push_back(b); + } + else if(srcState.IsLayout() && dstState.IsLayout()) + { + D3D12_TEXTURE_BARRIER b = {}; + + b.LayoutBefore = srcState.ToLayout(); + b.AccessBefore = D3D12_BARRIER_ACCESS_COMMON; + b.SyncBefore = D3D12_BARRIER_SYNC_ALL; + b.AccessAfter = D3D12_BARRIER_ACCESS_COMMON; + b.SyncAfter = D3D12_BARRIER_SYNC_ALL; + b.LayoutAfter = dstState.ToLayout(); + b.Subresources.IndexOrFirstMipLevel = (UINT)subresource; + b.pResource = res; + + barriers.newBarriers.push_back(b); + } + else + { + // difficult case, moving between barrier types and need to go to common in between + + if(srcState.IsStates()) + { + if(srcState.ToStates() != D3D12_RESOURCE_STATE_COMMON) + { + D3D12_RESOURCE_BARRIER b; + b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + b.Transition.pResource = res; + b.Transition.Subresource = (UINT)subresource; + b.Transition.StateBefore = srcState.ToStates(); + b.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; + + barriers.barriers.push_back(b); + } + + { + D3D12_TEXTURE_BARRIER b = {}; + + b.LayoutBefore = D3D12_BARRIER_LAYOUT_COMMON; + b.AccessBefore = D3D12_BARRIER_ACCESS_COMMON; + b.SyncBefore = D3D12_BARRIER_SYNC_ALL; + b.AccessAfter = D3D12_BARRIER_ACCESS_COMMON; + b.SyncAfter = D3D12_BARRIER_SYNC_ALL; + b.LayoutAfter = dstState.ToLayout(); + b.Subresources.IndexOrFirstMipLevel = (UINT)subresource; + b.pResource = res; + + barriers.newBarriers.push_back(b); } } else { - BARRIER_ASSERT("Mismatching before state", st[trans.Subresource] == trans.StateBefore, - st[trans.Subresource], trans.StateBefore, trans.Subresource); - st[trans.Subresource] = trans.StateAfter; + { + D3D12_TEXTURE_BARRIER b = {}; + + b.LayoutBefore = srcState.ToLayout(); + b.AccessBefore = D3D12_BARRIER_ACCESS_COMMON; + b.SyncBefore = D3D12_BARRIER_SYNC_ALL; + b.AccessAfter = D3D12_BARRIER_ACCESS_COMMON; + b.SyncAfter = D3D12_BARRIER_SYNC_ALL; + b.LayoutAfter = D3D12_BARRIER_LAYOUT_COMMON; + b.Subresources.IndexOrFirstMipLevel = (UINT)subresource; + b.pResource = res; + + barriers.newBarriers.push_back(b); + } + + if(dstState.ToStates() != D3D12_RESOURCE_STATE_COMMON) + { + D3D12_RESOURCE_BARRIER b; + b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + b.Transition.pResource = res; + b.Transition.Subresource = (UINT)subresource; + b.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; + b.Transition.StateAfter = dstState.ToStates(); + + barriers.newToOldBarriers.push_back(b); + } } } } template void D3D12ResourceManager::SerialiseResourceStates( - SerialiserType &ser, rdcarray &barriers, - std::map &states, + SerialiserType &ser, BarrierSet &barriers, std::map &states, const std::map &initialStates) { SERIALISE_ELEMENT_LOCAL(NumMems, (uint32_t)states.size()); @@ -741,18 +897,11 @@ void D3D12ResourceManager::SerialiseResourceStates( for(size_t m = 0; m < States.size(); m++) { - if(states[liveid][m] != States[m]) - { - D3D12_RESOURCE_BARRIER b; - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = (ID3D12Resource *)GetCurrentResource(liveid); - b.Transition.Subresource = (UINT)m; - b.Transition.StateBefore = states[liveid][m]; - b.Transition.StateAfter = States[m]; - - barriers.push_back(b); - } + const D3D12ResourceLayout srcState = states[liveid][m]; + const D3D12ResourceLayout dstState = States[m]; + if(srcState != dstState) + AddStateResetBarrier(srcState, dstState, (ID3D12Resource *)GetCurrentResource(liveid), + (UINT)m, barriers); } } @@ -774,18 +923,11 @@ void D3D12ResourceManager::SerialiseResourceStates( { for(size_t m = 0; m < it->second.size(); m++) { - if(states[it->first][m] != it->second[m]) - { - D3D12_RESOURCE_BARRIER b; - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = (ID3D12Resource *)GetCurrentResource(it->first); - b.Transition.Subresource = (UINT)m; - b.Transition.StateBefore = states[it->first][m]; - b.Transition.StateAfter = it->second[m]; - - barriers.push_back(b); - } + const D3D12ResourceLayout srcState = states[it->first][m]; + const D3D12ResourceLayout dstState = it->second[m]; + if(srcState != dstState) + AddStateResetBarrier(srcState, dstState, + (ID3D12Resource *)GetCurrentResource(it->first), (UINT)m, barriers); } } } @@ -795,12 +937,10 @@ void D3D12ResourceManager::SerialiseResourceStates( } template void D3D12ResourceManager::SerialiseResourceStates( - ReadSerialiser &ser, rdcarray &barriers, - std::map &states, + ReadSerialiser &ser, BarrierSet &barriers, std::map &states, const std::map &initialStates); template void D3D12ResourceManager::SerialiseResourceStates( - WriteSerialiser &ser, rdcarray &barriers, - std::map &states, + WriteSerialiser &ser, BarrierSet &barriers, std::map &states, const std::map &initialStates); void D3D12ResourceManager::SetInternalResource(ID3D12DeviceChild *res) diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 173e5e7d5..8853c2ab2 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -479,7 +479,7 @@ struct CmdListRecordingInfo D3D12ResourceRecord *allocRecord = NULL; - rdcarray barriers; + BarrierSet barriers; // a list of all resources dirtied by this command list std::set dirtied; @@ -600,8 +600,6 @@ struct D3D12ResourceRecord : public ResourceRecord Threading::CriticalSection m_MapLock; }; -typedef rdcarray SubresourceStateVector; - struct SparseBinds { SparseBinds(const Sparse::PageTable &table); @@ -760,11 +758,10 @@ public: return (T *)GetCurrentResource(id); } - void ApplyBarriers(rdcarray &barriers, - std::map &states); + void ApplyBarriers(BarrierSet &barriers, std::map &states); template - void SerialiseResourceStates(SerialiserType &ser, rdcarray &barriers, + void SerialiseResourceStates(SerialiserType &ser, BarrierSet &barriers, std::map &states, const std::map &initialStates); diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index b207c0cca..c6e1cdadf 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -992,10 +992,6 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De D3D12_RESOURCE_DESC resourceDesc = resource->GetDesc(); - rdcarray barriers; - int resType = 0; - GetDebugManager()->PrepareTextureSampling(resource, CompType::Float, resType, barriers); - D3D12_RESOURCE_DESC overlayTexDesc; overlayTexDesc.Alignment = 0; overlayTexDesc.DepthOrArraySize = resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D @@ -1085,43 +1081,19 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De renderDepth->SetName(L"Overlay renderDepth"); - ID3D12GraphicsCommandList *list = m_pDevice->GetNewList(); + ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList(); if(!list) return ResourceId(); - const rdcarray &states = - m_pDevice->GetSubresourceStates(GetResID(realDepth)); + BarrierSet barriers; + barriers.Configure(realDepth, m_pDevice->GetSubresourceStates(GetResID(realDepth)), + BarrierSet::CopySourceAccess); - rdcarray depthBarriers; - depthBarriers.reserve(states.size()); - for(size_t i = 0; i < states.size(); i++) - { - D3D12_RESOURCE_BARRIER b; - - // skip unneeded barriers - if(states[i] & D3D12_RESOURCE_STATE_COPY_SOURCE) - continue; - - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = realDepth; - b.Transition.Subresource = (UINT)i; - b.Transition.StateBefore = states[i]; - b.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - - depthBarriers.push_back(b); - } - - if(!depthBarriers.empty()) - list->ResourceBarrier((UINT)depthBarriers.size(), &depthBarriers[0]); + barriers.Apply(list); list->CopyResource(renderDepth, realDepth); - for(size_t i = 0; i < depthBarriers.size(); i++) - std::swap(depthBarriers[i].Transition.StateBefore, depthBarriers[i].Transition.StateAfter); - - if(!depthBarriers.empty()) - list->ResourceBarrier((UINT)depthBarriers.size(), &depthBarriers[0]); + barriers.Unapply(list); D3D12_RESOURCE_BARRIER b = {}; diff --git a/renderdoc/driver/d3d12/d3d12_rendertexture.cpp b/renderdoc/driver/d3d12/d3d12_rendertexture.cpp index cac2f14e3..c4a2a94e8 100644 --- a/renderdoc/driver/d3d12/d3d12_rendertexture.cpp +++ b/renderdoc/driver/d3d12/d3d12_rendertexture.cpp @@ -34,8 +34,7 @@ #include "data/hlsl/hlsl_cbuffers.h" void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompType typeCast, - int &resType, - rdcarray &barriers) + int &resType, BarrierSet &barrierSet) { int srvOffset = 0; @@ -93,8 +92,6 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompTyp if(IsIntFormat(srvDesc.Format)) srvOffset += 20; - D3D12_RESOURCE_STATES realResourceState = - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; bool copy = false; D3D12_SHADER_RESOURCE_VIEW_DESC altSRVDesc = {}; @@ -102,7 +99,6 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompTyp // for non-typeless depth formats, we need to copy to a typeless resource for read if(IsDepthFormat(srvDesc.Format) && GetTypelessFormat(srvDesc.Format) != srvDesc.Format) { - realResourceState = D3D12_RESOURCE_STATE_COPY_SOURCE; copy = true; switch(GetTypelessFormat(srvDesc.Format)) @@ -168,27 +164,8 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompTyp altSRVDesc.Texture2DArray.PlaneSlice = 1; } - // transition resource to D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE - const rdcarray &states = m_pDevice->GetSubresourceStates(GetResID(resource)); - - barriers.reserve(states.size()); - for(size_t i = 0; i < states.size(); i++) - { - D3D12_RESOURCE_BARRIER b; - - // skip unneeded barriers - if((states[i] & realResourceState) == realResourceState) - continue; - - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = resource; - b.Transition.Subresource = (UINT)i; - b.Transition.StateBefore = states[i]; - b.Transition.StateAfter = realResourceState; - - barriers.push_back(b); - } + barrierSet.Configure(resource, m_pDevice->GetSubresourceStates(GetResID(resource)), + copy ? BarrierSet::CopySourceAccess : BarrierSet::SRVAccess); if(copy) { @@ -250,13 +227,12 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompTyp m_TexResource->SetName(L"m_TexResource"); } - ID3D12GraphicsCommandList *list = m_pDevice->GetNewList(); + ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList(); if(!list) return; // prepare real resource for copying - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barrierSet.Apply(list); D3D12_RESOURCE_BARRIER texResourceBarrier; D3D12_RESOURCE_BARRIER &b = texResourceBarrier; @@ -278,15 +254,10 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource, CompTyp std::swap(texResourceBarrier.Transition.StateBefore, texResourceBarrier.Transition.StateAfter); list->ResourceBarrier(1, &texResourceBarrier); - // real resource back to itself - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barrierSet.Unapply(list); // don't do any barriers outside in the source function - barriers.clear(); + barrierSet.clear(); list->Close(); @@ -486,7 +457,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture RDCCLAMP(cfg.subresource.slice, 0U, uint32_t(resourceDesc.DepthOrArraySize - 1)) + 0.001f); } - rdcarray barriers; + BarrierSet barriers; int resType = 0; GetDebugManager()->PrepareTextureSampling(resource, cfg.typeCast, resType, barriers); @@ -724,12 +695,11 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture } { - ID3D12GraphicsCommandList *list = m_pDevice->GetNewList(); + ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList(); if(!list) return false; - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->OMSetRenderTargets(1, &rtv, TRUE, NULL); @@ -796,12 +766,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture list->DrawInstanced(4, 1, 0, 0); - // transition back to where they were - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); list->Close(); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 38d9d8e7f..148efc0d7 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -2855,17 +2855,16 @@ bool D3D12Replay::GetMinMax(ResourceId texid, const Subresource &sub, CompType t int blocksY = (int)ceil(cdata.HistogramTextureResolution.y / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - rdcarray barriers; + BarrierSet barriers; int resType = 0; GetDebugManager()->PrepareTextureSampling(resource, typeCast, resType, barriers); { - ID3D12GraphicsCommandList *list = m_pDevice->GetNewList(); + ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList(); if(!list) return false; - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->SetPipelineState(m_Histogram.TileMinMaxPipe[resType][intIdx]); @@ -2933,12 +2932,7 @@ bool D3D12Replay::GetMinMax(ResourceId texid, const Subresource &sub, CompType t list->ResourceBarrier(1, &tileBarriers[1]); - // transition image back to where it was - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); list->Close(); @@ -3060,17 +3054,16 @@ bool D3D12Replay::GetHistogram(ResourceId texid, const Subresource &sub, CompTyp int tilesY = (int)ceil(cdata.HistogramTextureResolution.y / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - rdcarray barriers; + BarrierSet barriers; int resType = 0; GetDebugManager()->PrepareTextureSampling(resource, typeCast, resType, barriers); { - ID3D12GraphicsCommandList *list = m_pDevice->GetNewList(); + ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList(); if(!list) return false; - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->SetPipelineState(m_Histogram.HistogramPipe[resType][intIdx]); @@ -3113,12 +3106,7 @@ bool D3D12Replay::GetHistogram(ResourceId texid, const Subresource &sub, CompTyp list->ResourceBarrier(1, &tileBarriers[1]); - // transition image back to where it was - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); list->Close(); @@ -3655,7 +3643,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, ID3D12Resource *srcTexture = resource; ID3D12Resource *tmpTexture = NULL; - ID3D12GraphicsCommandList *list = NULL; + ID3D12GraphicsCommandListX *list = NULL; if(params.remap != RemapTexture::NoRemap) { @@ -3817,40 +3805,16 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, return; // put source texture into resolve source state - const rdcarray &states = m_pDevice->GetSubresourceStates(tex); + BarrierSet barriers; + barriers.Configure(resource, m_pDevice->GetSubresourceStates(tex), + BarrierSet::ResolveSourceAccess); - rdcarray barriers; - barriers.reserve(states.size()); - for(size_t i = 0; i < states.size(); i++) - { - D3D12_RESOURCE_BARRIER b; - - // skip unneeded barriers - if(states[i] & D3D12_RESOURCE_STATE_RESOLVE_SOURCE) - continue; - - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = resource; - b.Transition.Subresource = (UINT)i; - b.Transition.StateBefore = states[i]; - b.Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; - - barriers.push_back(b); - } - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->ResolveSubresource(resolveTexture, 0, srcTexture, s.slice * resDesc.DepthOrArraySize + s.mip, resDesc.Format); - // real resource back to normal - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); D3D12_RESOURCE_BARRIER b = {}; b.Transition.pResource = resolveTexture; @@ -3891,30 +3855,10 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, return; // put source texture into shader read state - const rdcarray &states = m_pDevice->GetSubresourceStates(tex); + BarrierSet barriers; + barriers.Configure(resource, m_pDevice->GetSubresourceStates(tex), BarrierSet::SRVAccess); - rdcarray barriers; - barriers.reserve(states.size()); - for(size_t i = 0; i < states.size(); i++) - { - D3D12_RESOURCE_BARRIER b; - - // skip unneeded barriers - if(states[i] & D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) - continue; - - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = resource; - b.Transition.Subresource = (UINT)i; - b.Transition.StateBefore = states[i]; - b.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - - barriers.push_back(b); - } - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); list->Close(); list = NULL; @@ -3931,12 +3875,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, if(!list) return; - // real resource back to normal - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Unapply(list); D3D12_RESOURCE_BARRIER b = {}; b.Transition.pResource = arrayTexture; @@ -3955,33 +3894,14 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, if(!list) return; - rdcarray barriers; + BarrierSet barriers; // if we have no tmpImage, we're copying directly from the real image if(tmpTexture == NULL) { - const rdcarray &states = m_pDevice->GetSubresourceStates(tex); - barriers.reserve(states.size()); - for(size_t i = 0; i < states.size(); i++) - { - D3D12_RESOURCE_BARRIER b; + barriers.Configure(resource, m_pDevice->GetSubresourceStates(tex), BarrierSet::CopySourceAccess); - // skip unneeded barriers - if(states[i] & D3D12_RESOURCE_STATE_COPY_SOURCE) - continue; - - b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - b.Transition.pResource = resource; - b.Transition.Subresource = (UINT)i; - b.Transition.StateBefore = states[i]; - b.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - - barriers.push_back(b); - } - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); + barriers.Apply(list); } D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {}; @@ -4063,14 +3983,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, // if we have no tmpImage, we're copying directly from the real image if(tmpTexture == NULL) - { - // real resource back to normal - for(size_t i = 0; i < barriers.size(); i++) - std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter); - - if(!barriers.empty()) - list->ResourceBarrier((UINT)barriers.size(), &barriers[0]); - } + barriers.Unapply(list); list->Close(); diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index 628c17723..ebc54a646 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -1718,6 +1718,110 @@ void DoSerialise(SerialiserType &ser, D3D12_DISPATCH_ARGUMENTS &el) SERIALISE_MEMBER(ThreadGroupCountZ).Important(); } +template +void DoSerialise(SerialiserType &ser, D3D12ResourceLayout &el) +{ + RDCCOMPILE_ASSERT(sizeof(el) == sizeof(uint32_t), + "D3D12ResourceLayout is expected to be a 32-bit value"); + ser.SerialiseValue(SDBasic::Enum, 4, (uint32_t &)el); + ser.SerialiseStringify(el); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_GLOBAL_BARRIER &el) +{ + SERIALISE_MEMBER(SyncBefore); + SERIALISE_MEMBER(SyncAfter); + SERIALISE_MEMBER(AccessBefore); + SERIALISE_MEMBER(AccessAfter); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_BARRIER_SUBRESOURCE_RANGE &el) +{ + SERIALISE_MEMBER(IndexOrFirstMipLevel); + SERIALISE_MEMBER(NumMipLevels); + SERIALISE_MEMBER(FirstArraySlice); + SERIALISE_MEMBER(NumArraySlices); + SERIALISE_MEMBER(FirstPlane); + SERIALISE_MEMBER(NumPlanes); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_TEXTURE_BARRIER &el) +{ + SERIALISE_MEMBER(SyncBefore); + SERIALISE_MEMBER(SyncAfter); + SERIALISE_MEMBER(AccessBefore); + SERIALISE_MEMBER(AccessAfter); + SERIALISE_MEMBER(LayoutBefore); + SERIALISE_MEMBER(LayoutAfter); + SERIALISE_MEMBER(pResource); + SERIALISE_MEMBER(Subresources); + SERIALISE_MEMBER(Flags); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_BUFFER_BARRIER &el) +{ + SERIALISE_MEMBER(SyncBefore); + SERIALISE_MEMBER(SyncAfter); + SERIALISE_MEMBER(AccessBefore); + SERIALISE_MEMBER(AccessAfter); + SERIALISE_MEMBER(pResource); + SERIALISE_MEMBER(Offset); + SERIALISE_MEMBER(Size); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_BARRIER_GROUP &el) +{ + SERIALISE_MEMBER(Type).Important(); + SERIALISE_MEMBER(NumBarriers).Important(); + + switch(el.Type) + { + case D3D12_BARRIER_TYPE_GLOBAL: + { + SERIALISE_MEMBER_ARRAY(pGlobalBarriers, NumBarriers); + break; + } + case D3D12_BARRIER_TYPE_TEXTURE: + { + SERIALISE_MEMBER_ARRAY(pTextureBarriers, NumBarriers); + break; + } + case D3D12_BARRIER_TYPE_BUFFER: + { + SERIALISE_MEMBER_ARRAY(pBufferBarriers, NumBarriers); + break; + } + } +} + +template <> +void Deserialise(const D3D12_BARRIER_GROUP &el) +{ + switch(el.Type) + { + case D3D12_BARRIER_TYPE_GLOBAL: + { + delete[] el.pGlobalBarriers; + break; + } + case D3D12_BARRIER_TYPE_TEXTURE: + { + delete[] el.pTextureBarriers; + break; + } + case D3D12_BARRIER_TYPE_BUFFER: + { + delete[] el.pBufferBarriers; + break; + } + } +} + INSTANTIATE_SERIALISE_TYPE(D3D12RootSignature); INSTANTIATE_SERIALISE_TYPE(PortableHandle); INSTANTIATE_SERIALISE_TYPE(D3D12_CPU_DESCRIPTOR_HANDLE); @@ -1772,6 +1876,8 @@ INSTANTIATE_SERIALISE_TYPE(D3D12_SUBRESOURCE_RANGE_UINT64); INSTANTIATE_SERIALISE_TYPE(D3D12_WRITEBUFFERIMMEDIATE_PARAMETER); INSTANTIATE_SERIALISE_TYPE(D3D12_RENDER_PASS_RENDER_TARGET_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_RENDER_PASS_DEPTH_STENCIL_DESC); +INSTANTIATE_SERIALISE_TYPE(D3D12_BARRIER_GROUP); +INSTANTIATE_SERIALISE_TYPE(D3D12ResourceLayout); INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_ARGUMENTS); INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_INDEXED_ARGUMENTS); INSTANTIATE_SERIALISE_TYPE(D3D12_DISPATCH_ARGUMENTS); diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index 3287624c3..7d771a78a 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -951,6 +951,59 @@ rdcstr DoStringise(const D3D12_LINE_RASTERIZATION_MODE &el) END_ENUM_STRINGISE(); } +template <> +rdcstr DoStringise(const D3D12_BARRIER_TYPE &el) +{ + BEGIN_ENUM_STRINGISE(D3D12_BARRIER_TYPE); + { + STRINGISE_ENUM(D3D12_BARRIER_TYPE_GLOBAL) + STRINGISE_ENUM(D3D12_BARRIER_TYPE_TEXTURE) + STRINGISE_ENUM(D3D12_BARRIER_TYPE_BUFFER) + } + END_ENUM_STRINGISE(); +} + +template <> +rdcstr DoStringise(const D3D12_BARRIER_LAYOUT &el) +{ + BEGIN_ENUM_STRINGISE(D3D12_BARRIER_LAYOUT); + { + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_UNDEFINED) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMMON) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_GENERIC_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_RENDER_TARGET) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_SHADER_RESOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COPY_SOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COPY_DEST) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_RESOLVE_SOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_RESOLVE_DEST) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_SHADING_RATE_SOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_DECODE_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_DECODE_WRITE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_WRITE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_WRITE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST) + STRINGISE_ENUM(D3D12_BARRIER_LAYOUT_VIDEO_QUEUE_COMMON) + } + END_ENUM_STRINGISE(); +} + template <> rdcstr DoStringise(const D3D12_CLEAR_FLAGS &el) { @@ -1295,3 +1348,96 @@ rdcstr DoStringise(const D3D12_SAMPLER_FLAGS &el) } END_BITFIELD_STRINGISE(); } + +template <> +rdcstr DoStringise(const D3D12_TEXTURE_BARRIER_FLAGS &el) +{ + BEGIN_BITFIELD_STRINGISE(D3D12_TEXTURE_BARRIER_FLAGS); + { + STRINGISE_BITFIELD_VALUE(D3D12_TEXTURE_BARRIER_FLAG_NONE) + + STRINGISE_BITFIELD_BIT(D3D12_TEXTURE_BARRIER_FLAG_DISCARD) + } + END_BITFIELD_STRINGISE(); +} + +template <> +rdcstr DoStringise(const D3D12_BARRIER_SYNC &el) +{ + BEGIN_BITFIELD_STRINGISE(D3D12_BARRIER_SYNC); + { + STRINGISE_BITFIELD_VALUE(D3D12_BARRIER_SYNC_NONE) + + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_ALL) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_DRAW) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_INDEX_INPUT) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_VERTEX_SHADING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_PIXEL_SHADING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_DEPTH_STENCIL) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_RENDER_TARGET) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_COMPUTE_SHADING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_RAYTRACING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_COPY) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_RESOLVE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_EXECUTE_INDIRECT) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_PREDICATION) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_ALL_SHADING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_NON_PIXEL_SHADING) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_EMIT_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_CLEAR_UNORDERED_ACCESS_VIEW) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_VIDEO_DECODE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_VIDEO_PROCESS) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_VIDEO_ENCODE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_BUILD_RAYTRACING_ACCELERATION_STRUCTURE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_COPY_RAYTRACING_ACCELERATION_STRUCTURE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_SYNC_SPLIT) + } + END_BITFIELD_STRINGISE(); +} + +template <> +rdcstr DoStringise(const D3D12_BARRIER_ACCESS &el) +{ + BEGIN_BITFIELD_STRINGISE(D3D12_BARRIER_ACCESS); + { + STRINGISE_BITFIELD_VALUE(D3D12_BARRIER_ACCESS_COMMON) + STRINGISE_BITFIELD_VALUE(D3D12_BARRIER_ACCESS_NO_ACCESS) + + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_COMMON) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VERTEX_BUFFER) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_CONSTANT_BUFFER) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_INDEX_BUFFER) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_RENDER_TARGET) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_UNORDERED_ACCESS) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_DEPTH_STENCIL_READ) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_SHADER_RESOURCE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_STREAM_OUTPUT) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_INDIRECT_ARGUMENT) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_PREDICATION) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_COPY_DEST) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_COPY_SOURCE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_RESOLVE_DEST) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_RESOLVE_SOURCE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_RAYTRACING_ACCELERATION_STRUCTURE_READ) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_RAYTRACING_ACCELERATION_STRUCTURE_WRITE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_SHADING_RATE_SOURCE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_DECODE_READ) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_DECODE_WRITE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_PROCESS_READ) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_PROCESS_WRITE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_ENCODE_READ) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_VIDEO_ENCODE_WRITE) + STRINGISE_BITFIELD_BIT(D3D12_BARRIER_ACCESS_NO_ACCESS) + } + END_BITFIELD_STRINGISE(); +} + +template <> +rdcstr DoStringise(const D3D12ResourceLayout &el) +{ + if(el.IsLayout()) + return DoStringise(el.ToLayout()); + else + return DoStringise(el.ToStates()); +} diff --git a/renderdoc/renderdoc.natvis b/renderdoc/renderdoc.natvis index 7da0a0423..760484687 100644 --- a/renderdoc/renderdoc.natvis +++ b/renderdoc/renderdoc.natvis @@ -115,4 +115,8 @@ + + {D3D12_BARRIER_LAYOUT(value & 0x7fffffffU)} + {D3D12_RESOURCE_STATES(value)} + \ No newline at end of file