Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/util/d3d12_texture.h
7447 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.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 GenerateMipmaps() override;
44
void MakeReadyForSampling() override;
45
46
#ifdef ENABLE_GPU_OBJECT_NAMES
47
void SetDebugName(std::string_view name) override;
48
#endif
49
50
void TransitionToState(D3D12_RESOURCE_STATES state);
51
void CommitClear();
52
void CommitClear(ID3D12GraphicsCommandList* cmdlist);
53
54
static u32 CalculateSubresource(u32 layer, u32 level, u32 num_levels);
55
u32 CalculateSubresource(u32 layer, u32 level) const;
56
57
void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
58
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 layer, u32 level,
59
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const;
60
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 subresource,
61
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const;
62
static void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, ID3D12Resource* resource,
63
u32 subresource, D3D12_RESOURCE_STATES before_state,
64
D3D12_RESOURCE_STATES after_state);
65
66
// Call when the texture is bound to the pipeline, or read from in a copy.
67
ALWAYS_INLINE void SetUseFenceValue(u64 counter) { m_use_fence_counter = counter; }
68
69
private:
70
enum class WriteDescriptorType : u8
71
{
72
None,
73
RTV,
74
DSV
75
};
76
77
D3D12Texture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type, GPUTextureFormat format,
78
Flags flags, DXGI_FORMAT dxgi_format, ComPtr<ID3D12Resource> resource,
79
ComPtr<D3D12MA::Allocation> allocation, const D3D12DescriptorHandle& srv_descriptor,
80
const D3D12DescriptorHandle& write_descriptor, const D3D12DescriptorHandle& uav_descriptor,
81
WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state);
82
83
ID3D12GraphicsCommandList4* GetCommandBufferForUpdate();
84
ID3D12Resource* AllocateUploadStagingBuffer(const void* data, u32 pitch, u32 upload_pitch, u32 width, u32 height,
85
u32 buffer_size) const;
86
void ActuallyCommitClear(ID3D12GraphicsCommandList* cmdlist);
87
88
ComPtr<ID3D12Resource> m_resource;
89
ComPtr<D3D12MA::Allocation> m_allocation;
90
91
D3D12DescriptorHandle m_srv_descriptor = {};
92
D3D12DescriptorHandle m_write_descriptor = {};
93
D3D12DescriptorHandle m_uav_descriptor = {};
94
95
DXGI_FORMAT m_dxgi_format = DXGI_FORMAT_UNKNOWN;
96
D3D12_RESOURCE_STATES m_resource_state = D3D12_RESOURCE_STATE_COMMON;
97
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
98
99
// Contains the fence counter when the texture was last used.
100
// When this matches the current fence counter, the texture was used this command buffer.
101
u64 m_use_fence_counter = 0;
102
103
u16 m_map_x = 0;
104
u16 m_map_y = 0;
105
u16 m_map_width = 0;
106
u16 m_map_height = 0;
107
u8 m_map_layer = 0;
108
u8 m_map_level = 0;
109
};
110
111
class D3D12Sampler final : public GPUSampler
112
{
113
friend D3D12Device;
114
115
public:
116
~D3D12Sampler() override;
117
118
ALWAYS_INLINE const D3D12DescriptorHandle& GetDescriptor() const { return m_descriptor; }
119
120
#ifdef ENABLE_GPU_OBJECT_NAMES
121
void SetDebugName(std::string_view name) override;
122
#endif
123
124
static D3D12_SAMPLER_DESC GetD3DSamplerDesc(const GPUSampler::Config& config);
125
126
private:
127
D3D12Sampler(D3D12DescriptorHandle descriptor);
128
129
D3D12DescriptorHandle m_descriptor;
130
};
131
132
class D3D12TextureBuffer final : public GPUTextureBuffer
133
{
134
friend D3D12Device;
135
136
public:
137
D3D12TextureBuffer(Format format, u32 size_in_elements);
138
~D3D12TextureBuffer() override;
139
140
ALWAYS_INLINE const D3D12DescriptorHandle& GetDescriptor() const { return m_descriptor; }
141
142
bool Create(D3D12Device& dev, Error* error);
143
void Destroy(bool defer);
144
145
// Inherited via GPUTextureBuffer
146
void* Map(u32 required_elements) override;
147
void Unmap(u32 used_elements) override;
148
149
#ifdef ENABLE_GPU_OBJECT_NAMES
150
void SetDebugName(std::string_view name) override;
151
#endif
152
153
private:
154
D3D12StreamBuffer m_buffer;
155
D3D12DescriptorHandle m_descriptor;
156
};
157
158
class D3D12DownloadTexture final : public GPUDownloadTexture
159
{
160
public:
161
template<typename T>
162
using ComPtr = Microsoft::WRL::ComPtr<T>;
163
164
~D3D12DownloadTexture() override;
165
166
static std::unique_ptr<D3D12DownloadTexture> Create(u32 width, u32 height, GPUTextureFormat format, Error* error);
167
168
void CopyFromTexture(u32 dst_x, u32 dst_y, GPUTexture* src, u32 src_x, u32 src_y, u32 width, u32 height,
169
u32 src_layer, u32 src_level, bool use_transfer_pitch) override;
170
171
bool Map(u32 x, u32 y, u32 width, u32 height) override;
172
void Unmap() override;
173
174
void Flush() override;
175
176
#ifdef ENABLE_GPU_OBJECT_NAMES
177
void SetDebugName(std::string_view name) override;
178
#endif
179
180
private:
181
D3D12DownloadTexture(u32 width, u32 height, GPUTextureFormat format, ComPtr<D3D12MA::Allocation> allocation,
182
ComPtr<ID3D12Resource> buffer);
183
184
ComPtr<D3D12MA::Allocation> m_allocation;
185
ComPtr<ID3D12Resource> m_buffer;
186
187
u64 m_copy_fence_value = 0;
188
};
189
190