duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

d3d12_texture.h (6360B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR PolyForm-Strict-1.0.0)
      3 
      4 #pragma once
      5 
      6 #include "d3d12_descriptor_heap_manager.h"
      7 #include "d3d12_stream_buffer.h"
      8 #include "gpu_device.h"
      9 #include "gpu_texture.h"
     10 
     11 #include <d3d12.h>
     12 #include <limits>
     13 #include <memory>
     14 
     15 namespace D3D12MA {
     16 class Allocation;
     17 }
     18 
     19 class D3D12Device;
     20 
     21 class D3D12Texture final : public GPUTexture
     22 {
     23   friend D3D12Device;
     24 
     25 public:
     26   template<typename T>
     27   using ComPtr = Microsoft::WRL::ComPtr<T>;
     28 
     29   ~D3D12Texture() override;
     30 
     31   void Destroy(bool defer);
     32 
     33   ALWAYS_INLINE const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
     34   ALWAYS_INLINE const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
     35   ALWAYS_INLINE const D3D12DescriptorHandle& GetUAVDescriptor() const { return m_uav_descriptor; }
     36   ALWAYS_INLINE D3D12_RESOURCE_STATES GetResourceState() const { return m_resource_state; }
     37   ALWAYS_INLINE DXGI_FORMAT GetDXGIFormat() const { return m_dxgi_format; }
     38   ALWAYS_INLINE ID3D12Resource* GetResource() const { return m_resource.Get(); }
     39 
     40   bool Update(u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch, u32 layer = 0, u32 level = 0) override;
     41   bool Map(void** map, u32* map_stride, u32 x, u32 y, u32 width, u32 height, u32 layer = 0, u32 level = 0) override;
     42   void Unmap() override;
     43   void MakeReadyForSampling() override;
     44 
     45   void SetDebugName(std::string_view name) override;
     46 
     47   void TransitionToState(D3D12_RESOURCE_STATES state);
     48   void CommitClear();
     49   void CommitClear(ID3D12GraphicsCommandList* cmdlist);
     50 
     51   static u32 CalculateSubresource(u32 layer, u32 level, u32 num_levels);
     52   u32 CalculateSubresource(u32 layer, u32 level) const;
     53 
     54   void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
     55   void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 layer, u32 level,
     56                                     D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const;
     57   void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 subresource,
     58                                     D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const;
     59   static void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, ID3D12Resource* resource,
     60                                            u32 subresource, D3D12_RESOURCE_STATES before_state,
     61                                            D3D12_RESOURCE_STATES after_state);
     62 
     63   // Call when the texture is bound to the pipeline, or read from in a copy.
     64   ALWAYS_INLINE void SetUseFenceValue(u64 counter) { m_use_fence_counter = counter; }
     65 
     66 private:
     67   enum class WriteDescriptorType : u8
     68   {
     69     None,
     70     RTV,
     71     DSV
     72   };
     73 
     74   D3D12Texture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, Format format,
     75                DXGI_FORMAT dxgi_format, ComPtr<ID3D12Resource> resource, ComPtr<D3D12MA::Allocation> allocation,
     76                const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
     77                const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype,
     78                D3D12_RESOURCE_STATES resource_state);
     79 
     80   ID3D12GraphicsCommandList4* GetCommandBufferForUpdate();
     81   ID3D12Resource* AllocateUploadStagingBuffer(const void* data, u32 pitch, u32 upload_pitch, u32 width,
     82                                               u32 height) const;
     83   void CopyTextureDataForUpload(void* dst, const void* src, u32 width, u32 height, u32 pitch, u32 upload_pitch) const;
     84   void ActuallyCommitClear(ID3D12GraphicsCommandList* cmdlist);
     85 
     86   ComPtr<ID3D12Resource> m_resource;
     87   ComPtr<D3D12MA::Allocation> m_allocation;
     88 
     89   D3D12DescriptorHandle m_srv_descriptor = {};
     90   D3D12DescriptorHandle m_write_descriptor = {};
     91   D3D12DescriptorHandle m_uav_descriptor = {};
     92 
     93   DXGI_FORMAT m_dxgi_format = DXGI_FORMAT_UNKNOWN;
     94   D3D12_RESOURCE_STATES m_resource_state = D3D12_RESOURCE_STATE_COMMON;
     95   WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
     96 
     97   // Contains the fence counter when the texture was last used.
     98   // When this matches the current fence counter, the texture was used this command buffer.
     99   u64 m_use_fence_counter = 0;
    100 
    101   u16 m_map_x = 0;
    102   u16 m_map_y = 0;
    103   u16 m_map_width = 0;
    104   u16 m_map_height = 0;
    105   u8 m_map_layer = 0;
    106   u8 m_map_level = 0;
    107 };
    108 
    109 class D3D12Sampler final : public GPUSampler
    110 {
    111   friend D3D12Device;
    112 
    113 public:
    114   ~D3D12Sampler() override;
    115 
    116   ALWAYS_INLINE const D3D12DescriptorHandle& GetDescriptor() const { return m_descriptor; }
    117 
    118   void SetDebugName(std::string_view name) override;
    119 
    120 private:
    121   D3D12Sampler(D3D12DescriptorHandle descriptor);
    122 
    123   D3D12DescriptorHandle m_descriptor;
    124 };
    125 
    126 class D3D12TextureBuffer final : public GPUTextureBuffer
    127 {
    128   friend D3D12Device;
    129 
    130 public:
    131   D3D12TextureBuffer(Format format, u32 size_in_elements);
    132   ~D3D12TextureBuffer() override;
    133 
    134   ALWAYS_INLINE const D3D12DescriptorHandle& GetDescriptor() const { return m_descriptor; }
    135 
    136   bool Create(D3D12Device& dev);
    137   void Destroy(bool defer);
    138 
    139   // Inherited via GPUTextureBuffer
    140   void* Map(u32 required_elements) override;
    141   void Unmap(u32 used_elements) override;
    142 
    143   void SetDebugName(std::string_view name) override;
    144 
    145 private:
    146   D3D12StreamBuffer m_buffer;
    147   D3D12DescriptorHandle m_descriptor;
    148 };
    149 
    150 class D3D12DownloadTexture final : public GPUDownloadTexture
    151 {
    152 public:
    153   template<typename T>
    154   using ComPtr = Microsoft::WRL::ComPtr<T>;
    155 
    156   ~D3D12DownloadTexture() override;
    157 
    158   static std::unique_ptr<D3D12DownloadTexture> Create(u32 width, u32 height, GPUTexture::Format format);
    159 
    160   void CopyFromTexture(u32 dst_x, u32 dst_y, GPUTexture* src, u32 src_x, u32 src_y, u32 width, u32 height,
    161                        u32 src_layer, u32 src_level, bool use_transfer_pitch) override;
    162 
    163   bool Map(u32 x, u32 y, u32 width, u32 height) override;
    164   void Unmap() override;
    165 
    166   void Flush() override;
    167 
    168   void SetDebugName(std::string_view name) override;
    169 
    170 private:
    171   D3D12DownloadTexture(u32 width, u32 height, GPUTexture::Format format, ComPtr<D3D12MA::Allocation> allocation,
    172                        ComPtr<ID3D12Resource> buffer, size_t buffer_size);
    173 
    174   ComPtr<D3D12MA::Allocation> m_allocation;
    175   ComPtr<ID3D12Resource> m_buffer;
    176 
    177   u64 m_copy_fence_value = 0;
    178   size_t m_buffer_size = 0;
    179 };