Program Listing for File d3d12-resource.h

Return to documentation for file (include\d3d12-state-tracking\d3d12-resource.h)

/******************************************************************************
© Intel Corporation.

This software and the related documents are Intel copyrighted materials,
and your use of them is governed by the express license under which they
were provided to you ("License"). Unless the License provides otherwise,
you may not use, modify, copy, publish, distribute, disclose or transmit
this software or the related documents without Intel's prior written
permission.


 This software and the related documents are provided as is, with no express
or implied warranties, other than those that are expressly stated in the
License.

******************************************************************************/

#pragma once
#include "d3d12-object.h"
#include "concurrent/critical-section.h"

#include <vector>
#include <list>
#include <d3d12.h>
#include <dxgi.h>

namespace gpa {
namespace d3d12_state_tracker {

enum ResourceType : uint32_t {
    kInvalid = 0,
    kCommitted,
    kPlaced,
    kReserved,
    kMaxTypes
};

D3D12_RESOURCE_STATES constexpr kInvalidResourceState = (D3D12_RESOURCE_STATES)UINT32_MAX;

struct PlacedResourceInfo
{
    WeakPtr<ID3D12Heap> pHeap;
    UINT64 heapOffset = 0;
};

struct TileMapInfo
{
    WeakPtr<ID3D12Heap> pHeap;
    uint64_t timestamp = UINT64_MAX;
    UINT offset = 0;
#ifdef _DEBUG
    UINT tileIndexInResource = 0;
#endif
};

struct SubresourceTilingInfo
{
    D3D12_SUBRESOURCE_TILING tiling = {};
    bool isPacked = false;
    std::vector<TileMapInfo> tileMappings;
};

struct MapInfo
{
    D3D12_RANGE pReadRange;
    void* pData;
};

struct SubresourceState
{
    uint32_t index;
    D3D12_RESOURCE_STATES state;
    SubresourceTilingInfo tilingInfo;
    std::list<MapInfo> mapStack;
};

struct ResourceTilingInfo
{
    UINT numTilesForEntireResource;
    D3D12_PACKED_MIP_INFO packedMipDesc;
    D3D12_TILE_SHAPE standardTileShapeForNonPackedMips;
    std::vector<TileMapInfo> packedMipsTileMappings;
};

class D3D12ResourceState : public D3D12ObjectState
{
public:
    static constexpr GUID sGUID = {0x12d26255, 0x5da6, 0x4795, {0x96, 0xbe, 0xc0, 0xad, 0x2b, 0x5d, 0xe4, 0x80}};

private:
    ResourceType mType = kInvalid;
    union
    {
        PlacedResourceInfo mPlacedResourceInfo;
        ResourceTilingInfo mTiledResourceInfo;
    };
    std::vector<SubresourceState> mSubresources;
    bool mIsBackBuffer = false;
    uint32_t mBackBufferIndex = 0;
    IDXGISwapChain* mParentSwapChain = nullptr;
    bool mIsDirty = true;
    uint32_t mResidencyRefCount = 1;

    D3D12_GPU_VIRTUAL_ADDRESS mGPUVirtualAddress{};
    bool mGPUVirtualAddressObtained = false;

    D3D12_RESOURCE_STATES mInitialResourceState;
    bool mHasOptimizedClearValue = false;
    D3D12_CLEAR_VALUE const mOptimizedClearValue;

    // enhanced barrier support
    D3D12_BARRIER_LAYOUT mInitialLayout = D3D12_BARRIER_LAYOUT_UNDEFINED;
    ID3D12ProtectedResourceSession* mProtectedSession = nullptr;
    UINT32 mNumCastableFormats = 0;
    std::vector<DXGI_FORMAT> mCastableFormats;
    bool mHasEnhancedBarriers = false;

    std::vector<std::function<void(ID3D12Resource*)>> mDirtyCallbacks;
    gpa::concurrent::CriticalSection mCriticalSection;

public:
    D3D12ResourceState(ID3D12Resource* pResource, ID3D12Heap* pHeap, UINT64 HeapOffset, D3D12_RESOURCE_DESC const* pDesc, D3D12_RESOURCE_STATES initialResourceState, D3D12_CLEAR_VALUE const* pOptimizedClearValue, ResourceType type);
    D3D12ResourceState(ID3D12Resource* pResource, D3D12_RESOURCE_DESC const* pDesc, D3D12_RESOURCE_STATES initialResourceState, D3D12_CLEAR_VALUE const* pOptimizedClearValue, ResourceType type, IDXGISwapChain* parentSwapChain = nullptr, uint32_t backBufferIndex = UINT32_MAX);
#if defined(NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB)
    D3D12ResourceState(ID3D12Resource* pResource, ID3D12Heap* pHeap, UINT64 HeapOffset, D3D12_RESOURCE_DESC1 const* pDesc, D3D12_RESOURCE_STATES initialResourceState, D3D12_CLEAR_VALUE const* pOptimizedClearValue, ResourceType type);
    D3D12ResourceState(ID3D12Resource* pResource, D3D12_RESOURCE_DESC1 const* pDesc, D3D12_RESOURCE_STATES initialResourceState, D3D12_CLEAR_VALUE const* pOptimizedClearValue, ResourceType type, IDXGISwapChain* parentSwapChain = nullptr, uint32_t backBufferIndex = UINT32_MAX);
#endif  // NTDDI_WIN10_VB

#if defined(__ID3D12Device10_INTERFACE_DEFINED__)
    // CreateCommittedResource3 support for enhanced barriers
    D3D12ResourceState(ID3D12Resource* pResource, const D3D12_HEAP_PROPERTIES* pheapproperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT const* pCastableFormats);
    // CreatePlacedResource2 support for enhanced barriers
    D3D12ResourceState(ID3D12Resource* pResource, ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, UINT32 NumCastableFormats, DXGI_FORMAT const* pCastableFormats);
    // CreateReservedResource2 support for enhanced barriers
    D3D12ResourceState(ID3D12Resource* pResource, const D3D12_RESOURCE_DESC* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT const* pCastableFormats);
#endif  // __ID3D12Device10_INTERFACE_DEFINED__

    ~D3D12ResourceState();

    GUID GetGUID() override;

    void OnStateTransition(uint32_t subresource, D3D12_RESOURCE_STATES stateAfter);
    void OnMap(uint32_t subresource, D3D12_RANGE const* pReadRange, void** ppData);
    void OnUnmap(uint32_t subresource, D3D12_RANGE const* pWrittenRange);
    void OnEvict();
    void OnMakeResident();
    void OnUpdateTileMappings(UINT NumResourceRegions, D3D12_TILED_RESOURCE_COORDINATE const* pResourceRegionStartCoordinates, D3D12_TILE_REGION_SIZE const* pResourceRegionSizes, ID3D12Heap* pHeap, UINT NumRanges, D3D12_TILE_RANGE_FLAGS const* pRangeFlags, UINT const* pHeapRangeStartOffsets, UINT const* pRangeTileCounts, D3D12_TILE_MAPPING_FLAGS Flags);
    void OnCopyTileMappings(D3D12_TILED_RESOURCE_COORDINATE const* pDstRegionStartCoordinate, ID3D12Resource* pSrcResource, D3D12_TILED_RESOURCE_COORDINATE const* pSrcRegionStartCoordinate, D3D12_TILE_REGION_SIZE const* pRegionSize, D3D12_TILE_MAPPING_FLAGS Flags);

    D3D12_RESOURCE_STATES GetSubresourceState(uint32_t index) const;

    std::vector<D3D12_RESOURCE_STATES> GetStateOfAllSubresources(bool* allSubresourcesStateEqual) const;

    std::vector<D3D12_RESOURCE_BARRIER> PrepareSetOfBarriersForWholeResource();

    ResourceType GetType() const;

    PlacedResourceInfo GetHeapPlacementInfo() const;

    ResourceTilingInfo GetTilingInfo() const;

    std::vector<SubresourceState> const& GetSubresources() const;

    uint32_t GetSubresourceCount() const;

    bool IsBackbuffer() const;

    bool IsAccelerationStructure() const;

    uint32_t GetBackbufferIndex() const;

    IDXGISwapChain* GetParentSwapChain() const;

    void SetDirty(bool value);
    bool IsDirty();
    void RegisterDirtyCallback(std::function<void(ID3D12Resource* dirtyResource)> callback);
    void UnregisterAllDirtyCallbacks();

    bool IsMapped();

    bool IsResident();

    bool IsTexture() const;

    bool IsCompressed() const;

    D3D12_RESOURCE_STATES GetInitialResourceState();

    D3D12_CLEAR_VALUE const* GetOptimizedClearValue();

    D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress();

    bool GPUVirtualAddressObtained() const;
    void GPUVirtualAddressObtained(bool val);

    bool HasEnhancedBarriers() const;
    D3D12_BARRIER_LAYOUT GetInitialBarrierLayout() const;
    UINT32 GetCastableFormatCount() const;
    DXGI_FORMAT* GetCastableFormats();
    ID3D12ProtectedResourceSession* GetProtectedResourceSession() const;
};

}  // namespace d3d12_state_tracker
}  // namespace gpa