Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/util/d3d12_texture.h
4214 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, Format format, Flags flags,
78
DXGI_FORMAT dxgi_format, ComPtr<ID3D12Resource> resource, ComPtr<D3D12MA::Allocation> allocation,
79
const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
80
const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype,
81
D3D12_RESOURCE_STATES resource_state);
82
83
ID3D12GraphicsCommandList4* GetCommandBufferForUpdate();
84
ID3D12Resource* AllocateUploadStagingBuffer(const void* data, u32 pitch, u32 upload_pitch, u32 width,
85
u32 height, 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
private:
125
D3D12Sampler(D3D12DescriptorHandle descriptor);
126
127
D3D12DescriptorHandle m_descriptor;
128
};
129
130
class D3D12TextureBuffer final : public GPUTextureBuffer
131
{
132
friend D3D12Device;
133
134
public:
135
D3D12TextureBuffer(Format format, u32 size_in_elements);
136
~D3D12TextureBuffer() override;
137
138
ALWAYS_INLINE const D3D12DescriptorHandle& GetDescriptor() const { return m_descriptor; }
139
140
bool Create(D3D12Device& dev, Error* error);
141
void Destroy(bool defer);
142
143
// Inherited via GPUTextureBuffer
144
void* Map(u32 required_elements) override;
145
void Unmap(u32 used_elements) override;
146
147
#ifdef ENABLE_GPU_OBJECT_NAMES
148
void SetDebugName(std::string_view name) override;
149
#endif
150
151
private:
152
D3D12StreamBuffer m_buffer;
153
D3D12DescriptorHandle m_descriptor;
154
};
155
156
class D3D12DownloadTexture final : public GPUDownloadTexture
157
{
158
public:
159
template<typename T>
160
using ComPtr = Microsoft::WRL::ComPtr<T>;
161
162
~D3D12DownloadTexture() override;
163
164
static std::unique_ptr<D3D12DownloadTexture> Create(u32 width, u32 height, GPUTexture::Format format, Error* error);
165
166
void CopyFromTexture(u32 dst_x, u32 dst_y, GPUTexture* src, u32 src_x, u32 src_y, u32 width, u32 height,
167
u32 src_layer, u32 src_level, bool use_transfer_pitch) override;
168
169
bool Map(u32 x, u32 y, u32 width, u32 height) override;
170
void Unmap() override;
171
172
void Flush() override;
173
174
#ifdef ENABLE_GPU_OBJECT_NAMES
175
void SetDebugName(std::string_view name) override;
176
#endif
177
178
private:
179
D3D12DownloadTexture(u32 width, u32 height, GPUTexture::Format format, ComPtr<D3D12MA::Allocation> allocation,
180
ComPtr<ID3D12Resource> buffer, size_t buffer_size);
181
182
ComPtr<D3D12MA::Allocation> m_allocation;
183
ComPtr<ID3D12Resource> m_buffer;
184
185
u64 m_copy_fence_value = 0;
186
size_t m_buffer_size = 0;
187
};
188
189