diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp index f07f66edc..dcfaff53a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp @@ -128,25 +128,14 @@ void DescriptorHeapWithSlotsDX12::ReleaseSlot(uint32 index) value &= ~mask; } -DescriptorHeapPoolDX12::DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCount, bool shaderVisible) +DescriptorHeapPoolDX12::DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCountPerHeap, bool shaderVisible) : _device(device) , _type(type) - , _descriptorsCount(descriptorsCount) + , _descriptorsCountPerHeap(descriptorsCountPerHeap) , _shaderVisible(shaderVisible) { } -void DescriptorHeapPoolDX12::Init() -{ - // Allocate first page - auto heap = New(_device); - if (heap->Create(_type, _descriptorsCount, _shaderVisible)) - { - Platform::Fatal(TEXT("Failed to allocate descriptor heap.")); - } - _heaps.Add(heap); -} - void DescriptorHeapPoolDX12::AllocateSlot(DescriptorHeapWithSlotsDX12*& heap, uint32& slot) { for (int32 i = 0; i < _heaps.Count(); i++) @@ -159,7 +148,7 @@ void DescriptorHeapPoolDX12::AllocateSlot(DescriptorHeapWithSlotsDX12*& heap, ui } heap = New(_device); - if (heap->Create(_type, _descriptorsCount, _shaderVisible)) + if (heap->Create(_type, _descriptorsCountPerHeap, _shaderVisible)) { Platform::Fatal(TEXT("Failed to allocate descriptor heap.")); } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h index f7de6a9d6..e77893b0b 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h @@ -133,17 +133,16 @@ private: GPUDeviceDX12* _device; D3D12_DESCRIPTOR_HEAP_TYPE _type; - uint32 _descriptorsCount; + uint32 _descriptorsCountPerHeap; bool _shaderVisible; - Array _heaps; + Array> _heaps; public: - DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCount, bool shaderVisible); + DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCountPerHeap, bool shaderVisible); public: - void Init(); void AllocateSlot(DescriptorHeapWithSlotsDX12*& heap, uint32& slot); void ReleaseGPU(); }; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.cpp index 73d8111f0..9bcade16e 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.cpp @@ -9,6 +9,16 @@ #include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h" +void GPUBufferViewDX12::SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC& srvDesc) +{ + _srv.CreateSRV(_device, _owner->GetResource(), &srvDesc); +} + +void GPUBufferViewDX12::SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC& uavDesc, ID3D12Resource* counterResource) +{ + _uav.CreateUAV(_device, _owner->GetResource(), &uavDesc, counterResource); +} + uint64 GPUBufferDX12::GetSizeInBytes() const { return _memoryUsage; @@ -201,7 +211,7 @@ bool GPUBufferDX12::OnInit() } if (_desc.Flags & GPUBufferFlags::RawBuffer) srvDesc.Buffer.Flags |= D3D12_BUFFER_SRV_FLAG_RAW; - _view.SetSRV(&srvDesc); + _view.SetSRV(srvDesc); } if (useUAV) { @@ -220,7 +230,7 @@ bool GPUBufferDX12::OnInit() uavDesc.Format = DXGI_FORMAT_UNKNOWN; else uavDesc.Format = RenderToolsDX::ToDxgiFormat(PixelFormatExtensions::FindUnorderedAccessFormat(_desc.Format)); - _view.SetUAV(&uavDesc, _counter ? _counter->GetResource() : nullptr); + _view.SetUAV(uavDesc, _counter ? _counter->GetResource() : nullptr); } return false; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.h index 7c45dfe5d..48811019a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUBufferDX12.h @@ -27,6 +27,7 @@ public: /// GPUBufferViewDX12() { + SrvDimension = D3D12_SRV_DIMENSION_BUFFER; } /// @@ -65,34 +66,14 @@ public: /// Sets the shader resource view. /// /// The SRV desc. - void SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC* srvDesc) - { - if (srvDesc) - { - _srv.CreateSRV(_device, _owner->GetResource(), srvDesc); - } - else - { - _srv.Release(); - } - } + void SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC& srvDesc); /// /// Sets the unordered access view. /// /// The UAV desc. /// The counter buffer resource. - void SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC* uavDesc, ID3D12Resource* counterResource = nullptr) - { - if (uavDesc) - { - _uav.CreateUAV(_device, _owner->GetResource(), uavDesc, counterResource); - } - else - { - _uav.Release(); - } - } + void SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC& uavDesc, ID3D12Resource* counterResource = nullptr); public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index 4d1bd3e17..ed45c8768 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -136,26 +136,36 @@ void GPUContextDX12::AddTransitionBarrier(ResourceOwnerDX12* resource, const D3D void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURCE_STATES after, int32 subresourceIndex) { - // Check if resource is missing auto nativeResource = resource->GetResource(); if (nativeResource == nullptr) return; - auto& state = resource->State; - if (subresourceIndex == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES && !state.AreAllSubresourcesSame()) + if (subresourceIndex == -1) { - // Slow path because we have to transition the entire resource with multiple subresources that aren't in the same state - const uint32 subresourceCount = resource->GetSubresourcesCount(); - for (uint32 i = 0; i < subresourceCount; i++) + if (state.AreAllSubresourcesSame()) { - const D3D12_RESOURCE_STATES before = state.GetSubresourceState(i); - if (before != after) + // Transition entire resource at once + const D3D12_RESOURCE_STATES before = state.GetSubresourceState(subresourceIndex); + if (ResourceStateDX12::IsTransitionNeeded(before, after)) { - AddTransitionBarrier(resource, before, after, i); - state.SetSubresourceState(i, after); + AddTransitionBarrier(resource, before, after, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES); + state.SetSubresourceState(subresourceIndex, after); } } - ASSERT(state.CheckResourceState(after)); + else + { + // Slow path to transition each subresource + for (int32 i = 0; i < state.GetSubresourcesCount(); i++) + { + const D3D12_RESOURCE_STATES before = state.GetSubresourceState(i); + if (ResourceStateDX12::IsTransitionNeeded(before, after)) + { + AddTransitionBarrier(resource, before, after, i); + state.SetSubresourceState(i, after); + } + } + ASSERT(state.CheckResourceState(after)); + } state.SetResourceState(after); } else @@ -163,6 +173,7 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC const D3D12_RESOURCE_STATES before = state.GetSubresourceState(subresourceIndex); if (ResourceStateDX12::IsTransitionNeeded(before, after)) { + // Transition a single subresource AddTransitionBarrier(resource, before, after, subresourceIndex); state.SetSubresourceState(subresourceIndex, after); } @@ -282,23 +293,25 @@ void GPUContextDX12::flushSRVs() ASSERT(srCount <= GPU_MAX_SR_BINDED); // Fill table with source descriptors + DxShaderHeader& header = _currentCompute ? ((GPUShaderProgramCSDX12*)_currentCompute)->Header : _currentState->Header; D3D12_CPU_DESCRIPTOR_HANDLE srcDescriptorRangeStarts[GPU_MAX_SR_BINDED]; for (uint32 i = 0; i < srCount; i++) { const auto handle = _srHandles[i]; - if (handle != nullptr) + const auto dimensions = (D3D12_SRV_DIMENSION)header.SrDimensions[i]; + if (handle != nullptr && dimensions) { + ASSERT(handle->SrvDimension == dimensions); srcDescriptorRangeStarts[i] = handle->SRV(); - - D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + // TODO: for setup states based on binding mode + D3D12_RESOURCE_STATES states = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; if (handle->IsDepthStencilResource()) - state |= D3D12_RESOURCE_STATE_DEPTH_READ; - - SetResourceState(handle->GetResourceOwner(), state, handle->SubresourceIndex); + states |= D3D12_RESOURCE_STATE_DEPTH_READ; + SetResourceState(handle->GetResourceOwner(), states, handle->SubresourceIndex); } else { - srcDescriptorRangeStarts[i] = _device->NullSRV(); + srcDescriptorRangeStarts[i] = _device->NullSRV(dimensions); } } @@ -306,10 +319,7 @@ void GPUContextDX12::flushSRVs() auto allocation = _device->RingHeap_CBV_SRV_UAV.AllocateTable(srCount); // Copy descriptors - _device->GetDevice()->CopyDescriptors( - 1, &allocation.CPU, &srCount, - srCount, srcDescriptorRangeStarts, nullptr, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + _device->GetDevice()->CopyDescriptors(1, &allocation.CPU, &srCount, srCount, srcDescriptorRangeStarts, nullptr, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); // Flush SRV descriptors table if (_isCompute) @@ -400,10 +410,7 @@ void GPUContextDX12::flushUAVs() auto allocation = _device->RingHeap_CBV_SRV_UAV.AllocateTable(uaCount); // Copy descriptors - _device->GetDevice()->CopyDescriptors( - 1, &allocation.CPU, &uaCount, - uaCount, srcDescriptorRangeStarts, nullptr, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + _device->GetDevice()->CopyDescriptors(1, &allocation.CPU, &uaCount, uaCount, srcDescriptorRangeStarts, nullptr, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); // Flush UAV descriptors table if (_isCompute) @@ -444,8 +451,8 @@ void GPUContextDX12::flushRBs() if (_rbBufferSize > 0) { #if DX12_ENABLE_RESOURCE_BARRIERS_DEBUGGING - const auto info = String::Format(TEXT("[DX12 Resource Barrier]: Flush {0} barriers"), _rbBufferSize); - Log::Logger::Write(LogType::Info, info); + const auto info = String::Format(TEXT("[DX12 Resource Barrier]: Flush {0} barriers"), _rbBufferSize); + Log::Logger::Write(LogType::Info, info); #endif // Flush resource barriers @@ -490,6 +497,32 @@ void GPUContextDX12::onDrawCall() SetResourceState(_ibHandle, D3D12_RESOURCE_STATE_INDEX_BUFFER); } + // If SRV resource is not binded to RTV then transition it to the whole state (GPU-BASED VALIDATION complains about it) + for (uint32 i = 0; i < GPU_MAX_SR_BINDED; i++) + { + const auto handle = _srHandles[i]; + if (handle != nullptr && handle->GetResourceOwner()) + { + const auto resourceOwner = handle->GetResourceOwner(); + bool isRtv = false; + for (int32 j = 0; j < _rtCount; j++) + { + if (_rtHandles[j] && _rtHandles[j]->GetResourceOwner() == resourceOwner) + { + isRtv = true; + break; + } + } + if (!isRtv) + { + D3D12_RESOURCE_STATES states = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + if (handle->IsDepthStencilResource()) + states |= D3D12_RESOURCE_STATE_DEPTH_READ; + SetResourceState(handle->GetResourceOwner(), states); + } + } + } + // Flush flushSRVs(); flushRTVs(); @@ -497,6 +530,43 @@ void GPUContextDX12::onDrawCall() flushRBs(); flushPS(); flushCBs(); + +#if BUILD_DEBUG + // Additional verification of the state + for (int32 i = 0; i < _rtCount; i++) + { + const auto handle = _rtHandles[i]; + if (handle != nullptr && handle->GetResourceOwner()) + { + const auto& state = handle->GetResourceOwner()->State; + ASSERT((state.GetSubresourceState(handle->SubresourceIndex) & D3D12_RESOURCE_STATE_RENDER_TARGET) != 0); + } + } + const uint32 srMask = _currentState->GetUsedSRsMask(); + const uint32 srCount = Math::FloorLog2(srMask) + 1; + for (uint32 i = 0; i < srCount; i++) + { + const auto handle = _srHandles[i]; + if (handle != nullptr && handle->GetResourceOwner()) + { + const auto& state = handle->GetResourceOwner()->State; + bool isRtv = false; + for (int32 j = 0; j < _rtCount; j++) + { + if (_rtHandles[j] && _rtHandles[j]->GetResourceOwner() == handle->GetResourceOwner()) + { + isRtv = true; + break; + } + } + ASSERT((state.GetSubresourceState(handle->SubresourceIndex) & D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) != 0); + if (!isRtv) + { + ASSERT(state.AreAllSubresourcesSame()); + } + } + } +#endif } void GPUContextDX12::FrameBegin() @@ -722,10 +792,8 @@ void GPUContextDX12::BindCB(int32 slot, GPUConstantBuffer* cb) void GPUContextDX12::BindSR(int32 slot, GPUResourceView* view) { ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED); - auto handle = view ? (IShaderResourceDX12*)view->GetNativePtr() : nullptr; - - if (_srHandles[slot] != handle) + if (_srHandles[slot] != handle || !handle) { _srMaskDirtyGraphics |= 1 << slot; _srMaskDirtyCompute |= 1 << slot; @@ -736,10 +804,8 @@ void GPUContextDX12::BindSR(int32 slot, GPUResourceView* view) void GPUContextDX12::BindUA(int32 slot, GPUResourceView* view) { ASSERT(slot >= 0 && slot < GPU_MAX_UA_BINDED); - auto handle = view ? (IShaderResourceDX12*)view->GetNativePtr() : nullptr; - - if (_uaHandles[slot] != handle) + if (_uaHandles[slot] != handle || !handle) { _uaMaskDirtyGraphics |= 1 << slot; _uaMaskDirtyCompute |= 1 << slot; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index 944833ca3..9563c58fc 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -350,32 +350,78 @@ bool GPUDeviceDX12::Init() _device->SetStablePowerState(TRUE); #endif - // Create commands queue + // Setup resources _commandQueue = New(this, D3D12_COMMAND_LIST_TYPE_DIRECT); if (_commandQueue->Init()) return true; - - // Create rendering main context _mainContext = New(this, D3D12_COMMAND_LIST_TYPE_DIRECT); - - // Create descriptors heaps - Heap_CBV_SRV_UAV.Init(); - Heap_RTV.Init(); - Heap_DSV.Init(); if (RingHeap_CBV_SRV_UAV.Init()) return true; // Create empty views + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + for (int32 i = 0; i < ARRAY_COUNT(_nullSrv); i++) { - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; - srvDesc.Texture2D.PlaneSlice = 0; - srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; - _nullSrv.CreateSRV(this, nullptr, &srvDesc); + srvDesc.ViewDimension = (D3D12_SRV_DIMENSION)i; + switch (srvDesc.ViewDimension) + { + case D3D12_SRV_DIMENSION_BUFFER: + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.NumElements = 0; + srvDesc.Buffer.StructureByteStride = 0; + srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + break; + case D3D12_SRV_DIMENSION_TEXTURE1D: + srvDesc.Texture1D.MostDetailedMip = 0; + srvDesc.Texture1D.MipLevels = 1; + srvDesc.Texture1D.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: + srvDesc.Texture1DArray.MostDetailedMip = 0; + srvDesc.Texture1DArray.MipLevels = 1; + srvDesc.Texture1DArray.FirstArraySlice = 0; + srvDesc.Texture1DArray.ArraySize = 1; + srvDesc.Texture1DArray.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_UNKNOWN: // Map Unknown into Texture2D + case D3D12_SRV_DIMENSION_TEXTURE2D: + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.Texture2D.PlaneSlice = 0; + srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: + srvDesc.Texture2DArray.MostDetailedMip = 0; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = 0; + srvDesc.Texture2DArray.PlaneSlice = 0; + srvDesc.Texture2DArray.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_TEXTURE3D: + srvDesc.Texture3D.MostDetailedMip = 0; + srvDesc.Texture3D.MipLevels = 1; + srvDesc.Texture3D.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_TEXTURECUBE: + srvDesc.TextureCube.MostDetailedMip = 0; + srvDesc.TextureCube.MipLevels = 1; + srvDesc.TextureCube.ResourceMinLODClamp = 0.0f; + break; + case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: + srvDesc.TextureCubeArray.MostDetailedMip = 0; + srvDesc.TextureCubeArray.MipLevels = 1; + srvDesc.TextureCubeArray.First2DArrayFace = 0; + srvDesc.TextureCubeArray.NumCubes = 0; + srvDesc.TextureCubeArray.ResourceMinLODClamp = 0.0f; + break; + default: + continue; + } + _nullSrv[i].CreateSRV(this, nullptr, &srvDesc); } { D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc; @@ -574,14 +620,9 @@ bool GPUDeviceDX12::Init() void GPUDeviceDX12::DrawBegin() { - // Wait for the GPU to have at least one backbuffer to render to /*{ - PROFILE_CPU_NAMED("Wait For Fence"); - const uint64 nextFenceValue = _commandQueue->GetNextFenceValue(); - if (nextFenceValue >= DX12_BACK_BUFFER_COUNT) - { - _commandQueue->WaitForFence(nextFenceValue - DX12_BACK_BUFFER_COUNT); - } + PROFILE_CPU_NAMED("Wait For GPU"); + _commandQueue->WaitForGPU(); }*/ // Base @@ -606,9 +647,9 @@ GPUDeviceDX12::~GPUDeviceDX12() Dispose(); } -D3D12_CPU_DESCRIPTOR_HANDLE GPUDeviceDX12::NullSRV() const +D3D12_CPU_DESCRIPTOR_HANDLE GPUDeviceDX12::NullSRV(D3D12_SRV_DIMENSION dimension) const { - return _nullSrv.CPU(); + return _nullSrv[dimension].CPU(); } D3D12_CPU_DESCRIPTOR_HANDLE GPUDeviceDX12::NullUAV() const @@ -647,7 +688,8 @@ void GPUDeviceDX12::Dispose() updateRes2Dispose(); // Clear pipeline objects - _nullSrv.Release(); + for (auto& srv : _nullSrv) + srv.Release(); _nullUav.Release(); TimestampQueryHeap.Destroy(); DX_SAFE_RELEASE_CHECK(_rootSignature, 0); @@ -709,7 +751,6 @@ GPUSwapChain* GPUDeviceDX12::CreateSwapChain(Window* window) void GPUDeviceDX12::AddResourceToLateRelease(IGraphicsUnknown* resource, uint32 safeFrameCount) { - ASSERT(safeFrameCount < 32); if (resource == nullptr) return; @@ -735,7 +776,6 @@ void GPUDeviceDX12::updateRes2Dispose() for (int32 i = _res2Dispose.Count() - 1; i >= 0 && i < _res2Dispose.Count(); i--) { const DisposeResourceEntry& entry = _res2Dispose[i]; - if (entry.TargetFrame <= currentFrame) { auto refs = entry.Resource->Release(); diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h index 46dab6b57..940be58c3 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h @@ -55,7 +55,7 @@ private: GPUContextDX12* _mainContext; // Heaps - DescriptorHeapWithSlotsDX12::Slot _nullSrv; + DescriptorHeapWithSlotsDX12::Slot _nullSrv[D3D12_SRV_DIMENSION_TEXTURECUBEARRAY + 1]; DescriptorHeapWithSlotsDX12::Slot _nullUav; public: @@ -93,8 +93,7 @@ public: CommandSignatureDX12* DrawIndexedIndirectCommandSignature = nullptr; CommandSignatureDX12* DrawIndirectCommandSignature = nullptr; - D3D12_CPU_DESCRIPTOR_HANDLE NullSRV() const; - + D3D12_CPU_DESCRIPTOR_HANDLE NullSRV(D3D12_SRV_DIMENSION dimension) const; D3D12_CPU_DESCRIPTOR_HANDLE NullUAV() const; public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp index b8ac22bba..7f7119038 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUSwapChainDX12.cpp @@ -21,7 +21,7 @@ void BackBufferDX12::Setup(GPUSwapChainDX12* window, ID3D12Resource* backbuffer) rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtDesc.Texture2D.MipSlice = 0; rtDesc.Texture2D.PlaneSlice = 0; - Handle.SetRTV(&rtDesc); + Handle.SetRTV(rtDesc); } #if GPU_USE_WINDOW_SRV @@ -35,7 +35,7 @@ void BackBufferDX12::Setup(GPUSwapChainDX12* window, ID3D12Resource* backbuffer) srDesc.Texture2D.MipLevels = 1; srDesc.Texture2D.ResourceMinLODClamp = 0; srDesc.Texture2D.PlaneSlice = 0; - Handle.SetSRV(&srDesc); + Handle.SetSRV(srDesc); } #endif } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp index 03ba98eaf..265023fa8 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp @@ -237,7 +237,7 @@ void GPUTextureDX12::onResidentMipsChanged() // Change view if (_handlesPerSlice[0].GetParent() == nullptr) _handlesPerSlice[0].Init(this, _device, this, Format(), MultiSampleLevel()); - _handlesPerSlice[0].SetSRV(&srDesc); + _handlesPerSlice[0].SetSRV(srDesc); } void GPUTextureDX12::OnReleaseGPU() @@ -254,6 +254,35 @@ void GPUTextureDX12::OnReleaseGPU() GPUTexture::OnReleaseGPU(); } +void GPUTextureViewDX12::Release() +{ + _rtv.Release(); + _srv.Release(); + _dsv.Release(); + _uav.Release(); +} + +void GPUTextureViewDX12::SetRTV(D3D12_RENDER_TARGET_VIEW_DESC& rtvDesc) +{ + _rtv.CreateRTV(_device, _owner->GetResource(), &rtvDesc); +} + +void GPUTextureViewDX12::SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC& srvDesc) +{ + SrvDimension = srvDesc.ViewDimension; + _srv.CreateSRV(_device, _owner->GetResource(), &srvDesc); +} + +void GPUTextureViewDX12::SetDSV(D3D12_DEPTH_STENCIL_VIEW_DESC& dsvDesc) +{ + _dsv.CreateDSV(_device, _owner->GetResource(), &dsvDesc); +} + +void GPUTextureViewDX12::SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC& uavDesc, ID3D12Resource* counterResource) +{ + _uav.CreateUAV(_device, _owner->GetResource(), &uavDesc, counterResource); +} + void GPUTextureDX12::initHandles() { D3D12_RENDER_TARGET_VIEW_DESC rtDesc; @@ -318,7 +347,7 @@ void GPUTextureDX12::initHandles() srDesc.Texture3D.MostDetailedMip = 0; srDesc.Texture3D.MipLevels = MipLevels(); srDesc.Texture3D.ResourceMinLODClamp = 0; - _handleVolume.SetSRV(&srDesc); + _handleVolume.SetSRV(srDesc); } if (useRTV) { @@ -326,14 +355,14 @@ void GPUTextureDX12::initHandles() rtDesc.Texture3D.MipSlice = 0; rtDesc.Texture3D.FirstWSlice = 0; rtDesc.Texture3D.WSize = Depth(); - _handleVolume.SetRTV(&rtDesc); + _handleVolume.SetRTV(rtDesc); } if (useUAV) { uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; uavDesc.Texture2D.MipSlice = 0; uavDesc.Texture2D.PlaneSlice = 0; - _handleVolume.SetUAV(&uavDesc); + _handleVolume.SetUAV(uavDesc); } // Init per slice views @@ -348,7 +377,7 @@ void GPUTextureDX12::initHandles() { rtDesc.Texture3D.FirstWSlice = sliceIndex; _handlesPerSlice[sliceIndex].Init(this, _device, this, format, msaa); - _handlesPerSlice[sliceIndex].SetRTV(&rtDesc); + _handlesPerSlice[sliceIndex].SetRTV(rtDesc); } } } @@ -378,7 +407,7 @@ void GPUTextureDX12::initHandles() dsDesc.Texture2DArray.FirstArraySlice = arrayIndex; dsDesc.Texture2DArray.MipSlice = 0; } - _handlesPerSlice[arrayIndex].SetDSV(&dsDesc); + _handlesPerSlice[arrayIndex].SetDSV(dsDesc); } if (useRTV) { @@ -398,7 +427,7 @@ void GPUTextureDX12::initHandles() rtDesc.Texture2DArray.MipSlice = 0; rtDesc.Texture2DArray.PlaneSlice = 0; } - _handlesPerSlice[arrayIndex].SetRTV(&rtDesc); + _handlesPerSlice[arrayIndex].SetRTV(rtDesc); } if (useSRV) { @@ -420,7 +449,7 @@ void GPUTextureDX12::initHandles() srDesc.Texture2DArray.PlaneSlice = 0; srDesc.Texture2DArray.ResourceMinLODClamp = 0; } - _handlesPerSlice[arrayIndex].SetSRV(&srDesc); + _handlesPerSlice[arrayIndex].SetSRV(srDesc); } if (useUAV) { @@ -429,7 +458,7 @@ void GPUTextureDX12::initHandles() uavDesc.Texture2DArray.FirstArraySlice = arrayIndex; uavDesc.Texture2DArray.MipSlice = 0; uavDesc.Texture2DArray.PlaneSlice = 0; - _handlesPerSlice[arrayIndex].SetSRV(&srDesc); + _handlesPerSlice[arrayIndex].SetSRV(srDesc); } } @@ -442,7 +471,7 @@ void GPUTextureDX12::initHandles() dsDesc.Texture2DArray.ArraySize = arraySize; dsDesc.Texture2DArray.FirstArraySlice = 0; dsDesc.Texture2DArray.MipSlice = 0; - _handleArray.SetDSV(&dsDesc); + _handleArray.SetDSV(dsDesc); } if (useRTV) { @@ -451,7 +480,7 @@ void GPUTextureDX12::initHandles() rtDesc.Texture2DArray.FirstArraySlice = 0; rtDesc.Texture2DArray.MipSlice = 0; rtDesc.Texture2DArray.PlaneSlice = 0; - _handleArray.SetRTV(&rtDesc); + _handleArray.SetRTV(rtDesc); } if (useSRV) { @@ -472,7 +501,7 @@ void GPUTextureDX12::initHandles() srDesc.Texture2DArray.ResourceMinLODClamp = 0; srDesc.Texture2DArray.PlaneSlice = 0; } - _handleArray.SetSRV(&srDesc); + _handleArray.SetSRV(srDesc); } if (useUAV) { @@ -481,7 +510,7 @@ void GPUTextureDX12::initHandles() uavDesc.Texture2DArray.FirstArraySlice = 0; uavDesc.Texture2DArray.MipSlice = 0; uavDesc.Texture2DArray.PlaneSlice = 0; - _handleArray.SetUAV(&uavDesc); + _handleArray.SetUAV(uavDesc); } } } @@ -508,7 +537,7 @@ void GPUTextureDX12::initHandles() dsDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsDesc.Texture2D.MipSlice = 0; } - _handlesPerSlice[0].SetDSV(&dsDesc); + _handlesPerSlice[0].SetDSV(dsDesc); } if (useRTV) { @@ -530,7 +559,7 @@ void GPUTextureDX12::initHandles() rtDesc.Texture2D.MipSlice = 0; rtDesc.Texture2D.PlaneSlice = 0; } - _handlesPerSlice[0].SetRTV(&rtDesc); + _handlesPerSlice[0].SetRTV(rtDesc); } if (useSRV) { @@ -553,7 +582,7 @@ void GPUTextureDX12::initHandles() srDesc.Texture2D.ResourceMinLODClamp = 0; srDesc.Texture2D.PlaneSlice = 0; } - _handlesPerSlice[0].SetSRV(&srDesc); + _handlesPerSlice[0].SetSRV(srDesc); } if (useUAV) { @@ -571,7 +600,7 @@ void GPUTextureDX12::initHandles() uavDesc.Texture2D.MipSlice = 0; uavDesc.Texture2D.PlaneSlice = 0; } - _handlesPerSlice[0].SetUAV(&uavDesc); + _handlesPerSlice[0].SetUAV(uavDesc); } } @@ -593,35 +622,63 @@ void GPUTextureDX12::initHandles() // DSV if (useDSV) { - dsDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; - dsDesc.Texture2DArray.ArraySize = 1; - dsDesc.Texture2DArray.FirstArraySlice = arrayIndex; - dsDesc.Texture2DArray.MipSlice = mipIndex; - slice[mipIndex].SetDSV(&dsDesc); + if (isArray) + { + dsDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsDesc.Texture2DArray.ArraySize = 1; + dsDesc.Texture2DArray.FirstArraySlice = arrayIndex; + dsDesc.Texture2DArray.MipSlice = mipIndex; + } + else + { + dsDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsDesc.Texture2D.MipSlice = mipIndex; + } + slice[mipIndex].SetDSV(dsDesc); } // RTV if (useRTV) { - rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; - rtDesc.Texture2DArray.ArraySize = 1; - rtDesc.Texture2DArray.FirstArraySlice = arrayIndex; - rtDesc.Texture2DArray.MipSlice = mipIndex; - rtDesc.Texture2DArray.PlaneSlice = 0; - slice[mipIndex].SetRTV(&rtDesc); + if (isArray) + { + rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; + rtDesc.Texture2DArray.ArraySize = 1; + rtDesc.Texture2DArray.FirstArraySlice = arrayIndex; + rtDesc.Texture2DArray.MipSlice = mipIndex; + rtDesc.Texture2DArray.PlaneSlice = 0; + } + else + { + rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtDesc.Texture2D.MipSlice = mipIndex; + rtDesc.Texture2D.PlaneSlice = 0; + } + slice[mipIndex].SetRTV(rtDesc); } // SRV if (useSRV) { - srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; - srDesc.Texture2DArray.ArraySize = 1; - srDesc.Texture2DArray.FirstArraySlice = arrayIndex; - srDesc.Texture2DArray.MipLevels = 1; - srDesc.Texture2DArray.MostDetailedMip = mipIndex; - srDesc.Texture2DArray.ResourceMinLODClamp = 0; - srDesc.Texture2DArray.PlaneSlice = 0; - slice[mipIndex].SetSRV(&srDesc); + if (isArray) + { + srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + srDesc.Texture2DArray.ArraySize = 1; + srDesc.Texture2DArray.FirstArraySlice = arrayIndex; + srDesc.Texture2DArray.MipLevels = 1; + srDesc.Texture2DArray.MostDetailedMip = mipIndex; + srDesc.Texture2DArray.ResourceMinLODClamp = 0; + srDesc.Texture2DArray.PlaneSlice = 0; + } + else + { + srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srDesc.Texture2D.MipLevels = 1; + srDesc.Texture2D.MostDetailedMip = mipIndex; + srDesc.Texture2D.ResourceMinLODClamp = 0; + srDesc.Texture2D.PlaneSlice = 0; + } + slice[mipIndex].SetSRV(srDesc); } } } @@ -652,7 +709,7 @@ void GPUTextureDX12::initHandles() dsDesc.Flags = D3D12_DSV_FLAG_READ_ONLY_DEPTH; if (PixelFormatExtensions::HasStencil(format)) dsDesc.Flags |= D3D12_DSV_FLAG_READ_ONLY_STENCIL; - _handleReadOnlyDepth.SetDSV(&dsDesc); + _handleReadOnlyDepth.SetDSV(dsDesc); } ASSERT(!useRTV); if (useSRV) @@ -676,7 +733,7 @@ void GPUTextureDX12::initHandles() srDesc.Texture2D.ResourceMinLODClamp = 0; srDesc.Texture2D.PlaneSlice = 0; } - _handleReadOnlyDepth.SetSRV(&srDesc); + _handleReadOnlyDepth.SetSRV(srDesc); } } } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h index 01e23d08c..c13df1756 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h @@ -58,7 +58,7 @@ public: /// Parent texture format /// Parent texture multi-sample level /// Used subresource index or -1 to cover whole resource. - void Init(GPUResource* parent, GPUDeviceDX12* device, ResourceOwnerDX12* owner, PixelFormat format, MSAALevel msaa, int32 subresourceIndex = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + void Init(GPUResource* parent, GPUDeviceDX12* device, ResourceOwnerDX12* owner, PixelFormat format, MSAALevel msaa, int32 subresourceIndex = -1) { GPUTextureView::Init(parent, format, msaa); SubresourceIndex = subresourceIndex; @@ -69,80 +69,14 @@ public: /// /// Releases the view. /// - void Release() - { - _rtv.Release(); - _srv.Release(); - _dsv.Release(); - _uav.Release(); - } + void Release(); public: - /// - /// Sets the render target view. - /// - /// The RTV desc. - void SetRTV(D3D12_RENDER_TARGET_VIEW_DESC* rtvDesc) - { - if (rtvDesc) - { - _rtv.CreateRTV(_device, _owner->GetResource(), rtvDesc); - } - else - { - _rtv.Release(); - } - } - - /// - /// Sets the shader resource view. - /// - /// The SRV desc. - void SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC* srvDesc) - { - if (srvDesc) - { - _srv.CreateSRV(_device, _owner->GetResource(), srvDesc); - } - else - { - _srv.Release(); - } - } - - /// - /// Sets the depth stencil view. - /// - /// The DSV desc. - void SetDSV(D3D12_DEPTH_STENCIL_VIEW_DESC* dsvDesc) - { - if (dsvDesc) - { - _dsv.CreateDSV(_device, _owner->GetResource(), dsvDesc); - } - else - { - _dsv.Release(); - } - } - - /// - /// Sets the unordered access view. - /// - /// The UAV desc. - /// The counter buffer resource. - void SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC* uavDesc, ID3D12Resource* counterResource = nullptr) - { - if (uavDesc) - { - _uav.CreateUAV(_device, _owner->GetResource(), uavDesc, counterResource); - } - else - { - _uav.Release(); - } - } + void SetRTV(D3D12_RENDER_TARGET_VIEW_DESC& rtvDesc); + void SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC& srvDesc); + void SetDSV(D3D12_DEPTH_STENCIL_VIEW_DESC& dsvDesc); + void SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC& uavDesc, ID3D12Resource* counterResource = nullptr); public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/IShaderResourceDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/IShaderResourceDX12.h index 725f1d584..445d83f2a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/IShaderResourceDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/IShaderResourceDX12.h @@ -15,7 +15,7 @@ class IShaderResourceDX12 public: IShaderResourceDX12() - : SubresourceIndex(D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) + : SubresourceIndex(-1) { } @@ -28,8 +28,11 @@ public: /// /// Affected subresource index or -1 if use whole resource. + /// This solves only resource states tracking per single subresource, not subresources range, if need to here should be range of subresources (for texture arrays, volume textures and cubemaps). /// - int32 SubresourceIndex; // Note: this solves only resource states tracking per single subresource, not subresources range, if need to here should be range of subresources (for texture arrays, volume textures and cubemaps) + int32 SubresourceIndex; + + D3D12_SRV_DIMENSION SrvDimension = D3D12_SRV_DIMENSION_UNKNOWN; public: