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 };