22
#include "SDL_internal.h"
26
#include "../../video/directx/SDL_d3d12.h"
27
#include "../SDL_sysgpu.h"
28
#include "SDL_hashtable.h"
32
#define g_FullscreenVert D3D12_FullscreenVert
33
#define g_BlitFrom2D D3D12_BlitFrom2D
34
#define g_BlitFrom2DArray D3D12_BlitFrom2DArray
35
#define g_BlitFrom3D D3D12_BlitFrom3D
36
#define g_BlitFromCube D3D12_BlitFromCube
37
#if defined(SDL_PLATFORM_XBOXSERIES)
38
#include "D3D12_Blit_Series.h"
39
#elif defined(SDL_PLATFORM_XBOXONE)
40
#include "D3D12_Blit_One.h"
42
#include "D3D12_Blit.h"
44
#undef g_FullscreenVert
46
#undef g_BlitFrom2DArray
52
#define ERROR_CHECK(msg) \
54
D3D12_INTERNAL_LogError(renderer->device, msg, res); \
57
#define ERROR_CHECK_RETURN(msg, ret) \
59
D3D12_INTERNAL_LogError(renderer->device, msg, res); \
65
#if defined(SDL_PLATFORM_XBOXSERIES)
66
#define D3D12_DLL "d3d12_xs.dll"
67
#elif defined(SDL_PLATFORM_XBOXONE)
68
#define D3D12_DLL "d3d12_x.dll"
70
#define D3D12_DLL "d3d12.dll"
72
#define DXGI_DLL "dxgi.dll"
73
#define DXGIDEBUG_DLL "dxgidebug.dll"
74
#elif defined(__APPLE__)
75
#define D3D12_DLL "libdxvk_d3d12.dylib"
76
#define DXGI_DLL "libdxvk_dxgi.dylib"
77
#define DXGIDEBUG_DLL "libdxvk_dxgidebug.dylib"
79
#define D3D12_DLL "libdxvk_d3d12.so"
80
#define DXGI_DLL "libdxvk_dxgi.so"
81
#define DXGIDEBUG_DLL "libdxvk_dxgidebug.so"
84
#define D3D12_CREATE_DEVICE_FUNC "D3D12CreateDevice"
85
#define D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC "D3D12SerializeRootSignature"
86
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
87
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
88
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
89
#define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData"
90
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_1
91
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_1"
93
#define MAX_ROOT_SIGNATURE_PARAMETERS 64
94
#define VIEW_GPU_DESCRIPTOR_COUNT 65536
95
#define SAMPLER_GPU_DESCRIPTOR_COUNT 2048
96
#define VIEW_SAMPLER_STAGING_DESCRIPTOR_COUNT 1000000
97
#define TARGET_STAGING_DESCRIPTOR_COUNT 1000000
98
#define D3D12_FENCE_UNSIGNALED_VALUE 0
99
#define D3D12_FENCE_SIGNAL_VALUE 1
101
#define SDL_GPU_SHADERSTAGE_COMPUTE (SDL_GPUShaderStage)2
103
#define EXPAND_ELEMENTS_IF_NEEDED(arr, initialValue, type) \
104
if (arr->count == arr->capacity) { \
105
if (arr->capacity == 0) { \
106
arr->capacity = initialValue; \
108
arr->capacity *= 2; \
110
arr->elements = (type *)SDL_realloc( \
112
arr->capacity * sizeof(type)); \
116
#define HRESULT_FMT "(0x%08lX)"
118
#define HRESULT_FMT "(0x%08X)"
122
typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY1)(const GUID *riid, void **ppFactory);
123
typedef HRESULT(WINAPI *PFN_DXGI_GET_DEBUG_INTERFACE)(const GUID *riid, void **ppDebug);
126
static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78, 0xf26f, 0x4dba, { 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87 } };
127
static const IID D3D_IID_IDXGIFactory4 = { 0x1bc6ea02, 0xef36, 0x464f, { 0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a } };
128
static const IID D3D_IID_IDXGIFactory5 = { 0x7632e1f5, 0xee65, 0x4dca, { 0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d } };
129
static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f, 0xff09, 0x44a9, { 0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17 } };
130
static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61, 0x3839, 0x4626, { 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05 } };
131
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
132
static const IID D3D_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
134
static const IID D3D_IID_IDXGISwapChain3 = { 0x94d99bdb, 0xf1f8, 0x4ab0, { 0xb2, 0x36, 0x7d, 0xa0, 0x17, 0x0e, 0xda, 0xb1 } };
135
static const IID D3D_IID_IDXGIDebug = { 0x119e7452, 0xde9e, 0x40fe, { 0x88, 0x06, 0x88, 0xf9, 0x0c, 0x12, 0xb4, 0x41 } };
136
static const IID D3D_IID_IDXGIInfoQueue = { 0xd67441c7, 0x672a, 0x476f, { 0x9e, 0x82, 0xcd, 0x55, 0xb4, 0x49, 0x49, 0xce } };
137
static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x08 } };
138
static const GUID D3D_IID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, { 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 } };
140
static const IID D3D_IID_ID3D12Device = { 0x189819f1, 0x1db6, 0x4b57, { 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7 } };
141
static const IID D3D_IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } };
142
static const IID D3D_IID_ID3D12DescriptorHeap = { 0x8efb471d, 0x616c, 0x4f49, { 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51 } };
143
static const IID D3D_IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } };
144
static const IID D3D_IID_ID3D12CommandAllocator = { 0x6102dee4, 0xaf59, 0x4b09, { 0xb9, 0x99, 0xb4, 0x4d, 0x73, 0xf0, 0x9b, 0x24 } };
145
static const IID D3D_IID_ID3D12CommandList = { 0x7116d91c, 0xe7e4, 0x47ce, { 0xb8, 0xc6, 0xec, 0x81, 0x68, 0xf4, 0x37, 0xe5 } };
146
static const IID D3D_IID_ID3D12GraphicsCommandList = { 0x5b160d0f, 0xac1b, 0x4185, { 0x8b, 0xa8, 0xb3, 0xae, 0x42, 0xa5, 0xa4, 0x55 } };
147
static const IID D3D_IID_ID3D12Fence = { 0x0a753dcf, 0xc4d8, 0x4b91, { 0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76 } };
148
static const IID D3D_IID_ID3D12RootSignature = { 0xc54a6b66, 0x72df, 0x4ee8, { 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14 } };
149
static const IID D3D_IID_ID3D12CommandSignature = { 0xc36a797c, 0xec80, 0x4f0a, { 0x89, 0x85, 0xa7, 0xb2, 0x47, 0x50, 0x82, 0xd1 } };
150
static const IID D3D_IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } };
151
static const IID D3D_IID_ID3D12Debug = { 0x344488b7, 0x6846, 0x474b, { 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0 } };
152
static const IID D3D_IID_ID3D12InfoQueue = { 0x0742a90b, 0xc387, 0x483f, { 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58 } };
156
typedef enum D3D12BufferType
158
D3D12_BUFFER_TYPE_GPU,
159
D3D12_BUFFER_TYPE_UNIFORM,
160
D3D12_BUFFER_TYPE_UPLOAD,
161
D3D12_BUFFER_TYPE_DOWNLOAD
166
static SDL_GPUTextureFormat SwapchainCompositionToSDLTextureFormat[] = {
167
SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM,
168
SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB,
169
SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT,
170
SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM,
173
static DXGI_FORMAT SwapchainCompositionToTextureFormat[] = {
174
DXGI_FORMAT_B8G8R8A8_UNORM,
175
DXGI_FORMAT_B8G8R8A8_UNORM,
176
DXGI_FORMAT_R16G16B16A16_FLOAT,
177
DXGI_FORMAT_R10G10B10A2_UNORM,
180
static DXGI_COLOR_SPACE_TYPE SwapchainCompositionToColorSpace[] = {
181
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
182
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
183
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709,
184
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
187
static D3D12_BLEND SDLToD3D12_BlendFactor[] = {
190
D3D12_BLEND_SRC_COLOR,
191
D3D12_BLEND_INV_SRC_COLOR,
192
D3D12_BLEND_DEST_COLOR,
193
D3D12_BLEND_INV_DEST_COLOR,
194
D3D12_BLEND_SRC_ALPHA,
195
D3D12_BLEND_INV_SRC_ALPHA,
196
D3D12_BLEND_DEST_ALPHA,
197
D3D12_BLEND_INV_DEST_ALPHA,
198
D3D12_BLEND_BLEND_FACTOR,
199
D3D12_BLEND_INV_BLEND_FACTOR,
200
D3D12_BLEND_SRC_ALPHA_SAT,
203
static D3D12_BLEND SDLToD3D12_BlendFactorAlpha[] = {
206
D3D12_BLEND_SRC_ALPHA,
207
D3D12_BLEND_INV_SRC_ALPHA,
208
D3D12_BLEND_DEST_ALPHA,
209
D3D12_BLEND_INV_DEST_ALPHA,
210
D3D12_BLEND_SRC_ALPHA,
211
D3D12_BLEND_INV_SRC_ALPHA,
212
D3D12_BLEND_DEST_ALPHA,
213
D3D12_BLEND_INV_DEST_ALPHA,
214
D3D12_BLEND_BLEND_FACTOR,
215
D3D12_BLEND_INV_BLEND_FACTOR,
216
D3D12_BLEND_SRC_ALPHA_SAT,
219
static D3D12_BLEND_OP SDLToD3D12_BlendOp[] = {
221
D3D12_BLEND_OP_SUBTRACT,
222
D3D12_BLEND_OP_REV_SUBTRACT,
227
static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
228
DXGI_FORMAT_R8G8B8A8_UNORM,
229
DXGI_FORMAT_B8G8R8A8_UNORM,
230
DXGI_FORMAT_B5G6R5_UNORM,
231
DXGI_FORMAT_B5G5R5A1_UNORM,
232
DXGI_FORMAT_B4G4R4A4_UNORM,
233
DXGI_FORMAT_R10G10B10A2_UNORM,
234
DXGI_FORMAT_R16G16_UNORM,
235
DXGI_FORMAT_R16G16B16A16_UNORM,
236
DXGI_FORMAT_R8_UNORM,
237
DXGI_FORMAT_A8_UNORM,
238
DXGI_FORMAT_BC1_UNORM,
239
DXGI_FORMAT_BC2_UNORM,
240
DXGI_FORMAT_BC3_UNORM,
241
DXGI_FORMAT_BC7_UNORM,
242
DXGI_FORMAT_R8G8_SNORM,
243
DXGI_FORMAT_R8G8B8A8_SNORM,
244
DXGI_FORMAT_R16_FLOAT,
245
DXGI_FORMAT_R16G16_FLOAT,
246
DXGI_FORMAT_R16G16B16A16_FLOAT,
247
DXGI_FORMAT_R32_FLOAT,
248
DXGI_FORMAT_R32G32_FLOAT,
249
DXGI_FORMAT_R32G32B32A32_FLOAT,
251
DXGI_FORMAT_R8G8_UINT,
252
DXGI_FORMAT_R8G8B8A8_UINT,
253
DXGI_FORMAT_R16_UINT,
254
DXGI_FORMAT_R16G16_UINT,
255
DXGI_FORMAT_R16G16B16A16_UINT,
256
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
257
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
258
DXGI_FORMAT_BC3_UNORM_SRGB,
259
DXGI_FORMAT_BC7_UNORM_SRGB,
260
DXGI_FORMAT_D16_UNORM,
261
DXGI_FORMAT_D24_UNORM_S8_UINT,
262
DXGI_FORMAT_D32_FLOAT,
263
DXGI_FORMAT_D24_UNORM_S8_UINT,
264
DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
266
SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TextureFormat, SDL_arraysize(SDLToD3D12_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX);
268
static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = {
269
D3D12_COMPARISON_FUNC_NEVER,
270
D3D12_COMPARISON_FUNC_LESS,
271
D3D12_COMPARISON_FUNC_EQUAL,
272
D3D12_COMPARISON_FUNC_LESS_EQUAL,
273
D3D12_COMPARISON_FUNC_GREATER,
274
D3D12_COMPARISON_FUNC_NOT_EQUAL,
275
D3D12_COMPARISON_FUNC_GREATER_EQUAL,
276
D3D12_COMPARISON_FUNC_ALWAYS
279
static D3D12_STENCIL_OP SDLToD3D12_StencilOp[] = {
280
D3D12_STENCIL_OP_KEEP,
281
D3D12_STENCIL_OP_ZERO,
282
D3D12_STENCIL_OP_REPLACE,
283
D3D12_STENCIL_OP_INCR_SAT,
284
D3D12_STENCIL_OP_DECR_SAT,
285
D3D12_STENCIL_OP_INVERT,
286
D3D12_STENCIL_OP_INCR,
287
D3D12_STENCIL_OP_DECR
290
static D3D12_CULL_MODE SDLToD3D12_CullMode[] = {
291
D3D12_CULL_MODE_NONE,
292
D3D12_CULL_MODE_FRONT,
296
static D3D12_FILL_MODE SDLToD3D12_FillMode[] = {
297
D3D12_FILL_MODE_SOLID,
298
D3D12_FILL_MODE_WIREFRAME
301
static D3D12_INPUT_CLASSIFICATION SDLToD3D12_InputRate[] = {
302
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
303
D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA
306
static DXGI_FORMAT SDLToD3D12_VertexFormat[] = {
307
DXGI_FORMAT_R32_SINT,
308
DXGI_FORMAT_R32G32_SINT,
309
DXGI_FORMAT_R32G32B32_SINT,
310
DXGI_FORMAT_R32G32B32A32_SINT,
311
DXGI_FORMAT_R32_UINT,
312
DXGI_FORMAT_R32G32_UINT,
313
DXGI_FORMAT_R32G32B32_UINT,
314
DXGI_FORMAT_R32G32B32A32_UINT,
315
DXGI_FORMAT_R32_FLOAT,
316
DXGI_FORMAT_R32G32_FLOAT,
317
DXGI_FORMAT_R32G32B32_FLOAT,
318
DXGI_FORMAT_R32G32B32A32_FLOAT,
319
DXGI_FORMAT_R8G8_SINT,
320
DXGI_FORMAT_R8G8B8A8_SINT,
321
DXGI_FORMAT_R8G8_UINT,
322
DXGI_FORMAT_R8G8B8A8_UINT,
323
DXGI_FORMAT_R8G8_SNORM,
324
DXGI_FORMAT_R8G8B8A8_SNORM,
325
DXGI_FORMAT_R8G8_UNORM,
326
DXGI_FORMAT_R8G8B8A8_UNORM,
327
DXGI_FORMAT_R16G16_SINT,
328
DXGI_FORMAT_R16G16B16A16_SINT,
329
DXGI_FORMAT_R16G16_UINT,
330
DXGI_FORMAT_R16G16B16A16_UINT,
331
DXGI_FORMAT_R16G16_SNORM,
332
DXGI_FORMAT_R16G16B16A16_SNORM,
333
DXGI_FORMAT_R16G16_UNORM,
334
DXGI_FORMAT_R16G16B16A16_UNORM,
335
DXGI_FORMAT_R16G16_FLOAT,
336
DXGI_FORMAT_R16G16B16A16_FLOAT
339
static Uint32 SDLToD3D12_SampleCount[] = {
346
static D3D12_PRIMITIVE_TOPOLOGY SDLToD3D12_PrimitiveType[] = {
347
D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
348
D3D_PRIMITIVE_TOPOLOGY_LINELIST,
349
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
350
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
351
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
354
static D3D12_TEXTURE_ADDRESS_MODE SDLToD3D12_SamplerAddressMode[] = {
355
D3D12_TEXTURE_ADDRESS_MODE_WRAP,
356
D3D12_TEXTURE_ADDRESS_MODE_MIRROR,
357
D3D12_TEXTURE_ADDRESS_MODE_CLAMP
360
static D3D12_FILTER SDLToD3D12_Filter(
361
SDL_GPUFilter minFilter,
362
SDL_GPUFilter magFilter,
363
SDL_GPUSamplerMipmapMode mipmapMode,
364
bool comparisonEnabled,
365
bool anisotropyEnabled)
367
D3D12_FILTER result = D3D12_ENCODE_BASIC_FILTER(
368
(minFilter == SDL_GPU_FILTER_LINEAR) ? 1 : 0,
369
(magFilter == SDL_GPU_FILTER_LINEAR) ? 1 : 0,
370
(mipmapMode == SDL_GPU_SAMPLERMIPMAPMODE_LINEAR) ? 1 : 0,
371
comparisonEnabled ? 1 : 0);
373
if (anisotropyEnabled) {
374
result = (D3D12_FILTER)(result | D3D12_ANISOTROPIC_FILTERING_BIT);
381
typedef struct D3D12Renderer D3D12Renderer;
382
typedef struct D3D12CommandBufferPool D3D12CommandBufferPool;
383
typedef struct D3D12CommandBuffer D3D12CommandBuffer;
384
typedef struct D3D12Texture D3D12Texture;
385
typedef struct D3D12Shader D3D12Shader;
386
typedef struct D3D12GraphicsPipeline D3D12GraphicsPipeline;
387
typedef struct D3D12ComputePipeline D3D12ComputePipeline;
388
typedef struct D3D12Buffer D3D12Buffer;
389
typedef struct D3D12BufferContainer D3D12BufferContainer;
390
typedef struct D3D12UniformBuffer D3D12UniformBuffer;
391
typedef struct D3D12DescriptorHeap D3D12DescriptorHeap;
392
typedef struct D3D12TextureDownload D3D12TextureDownload;
394
typedef struct D3D12Fence
398
SDL_AtomicInt referenceCount;
401
struct D3D12DescriptorHeap
403
ID3D12DescriptorHeap *handle;
404
D3D12_DESCRIPTOR_HEAP_TYPE heapType;
405
D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapCPUStart;
406
D3D12_GPU_DESCRIPTOR_HANDLE descriptorHeapGPUStart;
407
Uint32 maxDescriptors;
408
Uint32 descriptorSize;
411
Uint32 currentDescriptorIndex;
413
Uint32 *inactiveDescriptorIndices;
414
Uint32 inactiveDescriptorCount;
417
typedef struct D3D12DescriptorHeapPool
421
D3D12DescriptorHeap **heaps;
423
} D3D12DescriptorHeapPool;
425
typedef struct D3D12CPUDescriptor
427
D3D12DescriptorHeap *heap;
428
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
429
Uint32 cpuHandleIndex;
432
typedef struct D3D12TextureContainer
434
TextureCommonHeader header;
436
D3D12Texture *activeTexture;
438
D3D12Texture **textures;
439
Uint32 textureCapacity;
446
} D3D12TextureContainer;
449
typedef struct D3D12TextureSubresource
451
D3D12Texture *parent;
458
D3D12CPUDescriptor *rtvHandles;
460
D3D12CPUDescriptor uavHandle;
461
D3D12CPUDescriptor dsvHandle;
462
} D3D12TextureSubresource;
466
D3D12TextureContainer *container;
467
Uint32 containerIndex;
469
D3D12TextureSubresource *subresources;
470
Uint32 subresourceCount;
472
ID3D12Resource *resource;
473
D3D12CPUDescriptor srvHandle;
475
SDL_AtomicInt referenceCount;
478
typedef struct D3D12Sampler
480
SDL_GPUSamplerCreateInfo createInfo;
481
D3D12CPUDescriptor handle;
482
SDL_AtomicInt referenceCount;
485
typedef struct D3D12WindowData
488
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
489
D3D12XBOX_FRAME_PIPELINE_TOKEN frameToken;
490
Uint32 swapchainWidth, swapchainHeight;
492
IDXGISwapChain3 *swapchain;
494
SDL_GPUPresentMode presentMode;
495
SDL_GPUSwapchainComposition swapchainComposition;
496
DXGI_COLOR_SPACE_TYPE swapchainColorSpace;
499
D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT];
500
D3D12Fence *inFlightFences[MAX_FRAMES_IN_FLIGHT];
503
typedef struct D3D12PresentData
505
D3D12WindowData *windowData;
506
Uint32 swapchainImageIndex;
512
SDL_GPUDevice *sdlGPUDevice;
514
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
515
IDXGIDebug *dxgiDebug;
516
IDXGIFactory4 *factory;
517
IDXGIInfoQueue *dxgiInfoQueue;
518
IDXGIAdapter1 *adapter;
522
ID3D12Debug *d3d12Debug;
523
bool supportsTearing;
525
ID3D12Device *device;
526
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature_func;
527
const char *semantic;
530
ID3D12CommandQueue *commandQueue;
533
bool GPUUploadHeapSupported;
536
bool UMACacheCoherent;
539
ID3D12CommandSignature *indirectDrawCommandSignature;
540
ID3D12CommandSignature *indirectIndexedDrawCommandSignature;
541
ID3D12CommandSignature *indirectDispatchCommandSignature;
544
SDL_GPUShader *blitVertexShader;
545
SDL_GPUShader *blitFrom2DShader;
546
SDL_GPUShader *blitFrom2DArrayShader;
547
SDL_GPUShader *blitFrom3DShader;
548
SDL_GPUShader *blitFromCubeShader;
550
SDL_GPUSampler *blitNearestSampler;
551
SDL_GPUSampler *blitLinearSampler;
553
BlitPipelineCacheEntry *blitPipelines;
554
Uint32 blitPipelineCount;
555
Uint32 blitPipelineCapacity;
559
D3D12CommandBuffer **availableCommandBuffers;
560
Uint32 availableCommandBufferCount;
561
Uint32 availableCommandBufferCapacity;
563
D3D12CommandBuffer **submittedCommandBuffers;
564
Uint32 submittedCommandBufferCount;
565
Uint32 submittedCommandBufferCapacity;
567
D3D12UniformBuffer **uniformBufferPool;
568
Uint32 uniformBufferPoolCount;
569
Uint32 uniformBufferPoolCapacity;
571
D3D12WindowData **claimedWindows;
572
Uint32 claimedWindowCount;
573
Uint32 claimedWindowCapacity;
575
D3D12Fence **availableFences;
576
Uint32 availableFenceCount;
577
Uint32 availableFenceCapacity;
579
D3D12DescriptorHeap *stagingDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
580
D3D12DescriptorHeapPool descriptorHeapPools[2];
584
D3D12Buffer **buffersToDestroy;
585
Uint32 buffersToDestroyCount;
586
Uint32 buffersToDestroyCapacity;
588
D3D12Texture **texturesToDestroy;
589
Uint32 texturesToDestroyCount;
590
Uint32 texturesToDestroyCapacity;
592
D3D12Sampler **samplersToDestroy;
593
Uint32 samplersToDestroyCount;
594
Uint32 samplersToDestroyCapacity;
596
D3D12GraphicsPipeline **graphicsPipelinesToDestroy;
597
Uint32 graphicsPipelinesToDestroyCount;
598
Uint32 graphicsPipelinesToDestroyCapacity;
600
D3D12ComputePipeline **computePipelinesToDestroy;
601
Uint32 computePipelinesToDestroyCount;
602
Uint32 computePipelinesToDestroyCapacity;
605
SDL_Mutex *stagingDescriptorHeapLock;
606
SDL_Mutex *acquireCommandBufferLock;
607
SDL_Mutex *acquireUniformBufferLock;
608
SDL_Mutex *submitLock;
609
SDL_Mutex *windowLock;
610
SDL_Mutex *fenceLock;
611
SDL_Mutex *disposeLock;
614
struct D3D12CommandBuffer
617
CommandBufferCommonHeader common;
620
D3D12Renderer *renderer;
622
ID3D12CommandAllocator *commandAllocator;
623
ID3D12GraphicsCommandList *graphicsCommandList;
624
D3D12Fence *inFlightFence;
625
bool autoReleaseFence;
628
D3D12PresentData *presentDatas;
629
Uint32 presentDataCount;
630
Uint32 presentDataCapacity;
632
Uint32 colorAttachmentTextureSubresourceCount;
633
D3D12TextureSubresource *colorAttachmentTextureSubresources[MAX_COLOR_TARGET_BINDINGS];
634
D3D12TextureSubresource *depthStencilTextureSubresource;
635
D3D12GraphicsPipeline *currentGraphicsPipeline;
636
D3D12ComputePipeline *currentComputePipeline;
639
D3D12DescriptorHeap *gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1];
641
D3D12UniformBuffer **usedUniformBuffers;
642
Uint32 usedUniformBufferCount;
643
Uint32 usedUniformBufferCapacity;
646
bool needVertexBufferBind;
647
bool needVertexSamplerBind;
648
bool needVertexStorageTextureBind;
649
bool needVertexStorageBufferBind;
650
bool needVertexUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
651
bool needFragmentSamplerBind;
652
bool needFragmentStorageTextureBind;
653
bool needFragmentStorageBufferBind;
654
bool needFragmentUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
656
bool needComputeReadOnlyStorageTextureBind;
657
bool needComputeReadOnlyStorageBufferBind;
658
bool needComputeUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
660
D3D12Buffer *vertexBuffers[MAX_BUFFER_BINDINGS];
661
Uint32 vertexBufferOffsets[MAX_BUFFER_BINDINGS];
662
Uint32 vertexBufferCount;
664
D3D12Texture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
665
D3D12Sampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
666
D3D12Texture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
667
D3D12Buffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
668
D3D12UniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
670
D3D12Texture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
671
D3D12Sampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
672
D3D12Texture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
673
D3D12Buffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
674
D3D12UniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
676
D3D12Texture *computeReadOnlyStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
677
D3D12Buffer *computeReadOnlyStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
678
D3D12TextureSubresource *computeWriteOnlyStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES];
679
Uint32 computeWriteOnlyStorageTextureSubresourceCount;
680
D3D12Buffer *computeWriteOnlyStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS];
681
Uint32 computeWriteOnlyStorageBufferCount;
682
D3D12UniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
685
D3D12Texture **usedTextures;
686
Uint32 usedTextureCount;
687
Uint32 usedTextureCapacity;
689
D3D12Buffer **usedBuffers;
690
Uint32 usedBufferCount;
691
Uint32 usedBufferCapacity;
693
D3D12Sampler **usedSamplers;
694
Uint32 usedSamplerCount;
695
Uint32 usedSamplerCapacity;
697
D3D12GraphicsPipeline **usedGraphicsPipelines;
698
Uint32 usedGraphicsPipelineCount;
699
Uint32 usedGraphicsPipelineCapacity;
701
D3D12ComputePipeline **usedComputePipelines;
702
Uint32 usedComputePipelineCount;
703
Uint32 usedComputePipelineCapacity;
706
D3D12TextureDownload **textureDownloads;
707
Uint32 textureDownloadCount;
708
Uint32 textureDownloadCapacity;
718
Uint32 uniformBufferCount;
719
Uint32 storageBufferCount;
720
Uint32 storageTextureCount;
723
typedef struct D3D12GraphicsRootSignature
725
ID3D12RootSignature *handle;
727
Sint32 vertexSamplerRootIndex;
728
Sint32 vertexSamplerTextureRootIndex;
729
Sint32 vertexStorageTextureRootIndex;
730
Sint32 vertexStorageBufferRootIndex;
732
Sint32 vertexUniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
734
Sint32 fragmentSamplerRootIndex;
735
Sint32 fragmentSamplerTextureRootIndex;
736
Sint32 fragmentStorageTextureRootIndex;
737
Sint32 fragmentStorageBufferRootIndex;
739
Sint32 fragmentUniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
740
} D3D12GraphicsRootSignature;
742
struct D3D12GraphicsPipeline
744
ID3D12PipelineState *pipelineState;
745
D3D12GraphicsRootSignature *rootSignature;
746
SDL_GPUPrimitiveType primitiveType;
748
Uint32 vertexStrides[MAX_BUFFER_BINDINGS];
750
float blendConstants[4];
753
Uint32 vertexSamplerCount;
754
Uint32 vertexUniformBufferCount;
755
Uint32 vertexStorageBufferCount;
756
Uint32 vertexStorageTextureCount;
758
Uint32 fragmentSamplerCount;
759
Uint32 fragmentUniformBufferCount;
760
Uint32 fragmentStorageBufferCount;
761
Uint32 fragmentStorageTextureCount;
763
SDL_AtomicInt referenceCount;
766
typedef struct D3D12ComputeRootSignature
768
ID3D12RootSignature *handle;
770
Uint32 readOnlyStorageTextureRootIndex;
771
Uint32 readOnlyStorageBufferRootIndex;
772
Uint32 writeOnlyStorageTextureRootIndex;
773
Uint32 writeOnlyStorageBufferRootIndex;
774
Uint32 uniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
775
} D3D12ComputeRootSignature;
777
struct D3D12ComputePipeline
779
ID3D12PipelineState *pipelineState;
780
D3D12ComputeRootSignature *rootSignature;
782
Uint32 readOnlyStorageTextureCount;
783
Uint32 readOnlyStorageBufferCount;
784
Uint32 writeOnlyStorageTextureCount;
785
Uint32 writeOnlyStorageBufferCount;
786
Uint32 uniformBufferCount;
788
SDL_AtomicInt referenceCount;
791
struct D3D12TextureDownload
793
D3D12Buffer *destinationBuffer;
794
D3D12Buffer *temporaryBuffer;
800
Uint32 bytesPerDepthSlice;
801
Uint32 alignedBytesPerRow;
806
D3D12BufferContainer *container;
807
Uint32 containerIndex;
809
ID3D12Resource *handle;
810
D3D12CPUDescriptor uavDescriptor;
811
D3D12CPUDescriptor srvDescriptor;
812
D3D12CPUDescriptor cbvDescriptor;
813
D3D12_GPU_VIRTUAL_ADDRESS virtualAddress;
815
SDL_AtomicInt referenceCount;
819
struct D3D12BufferContainer
821
SDL_GPUBufferUsageFlags usageFlags;
823
D3D12BufferType type;
825
D3D12Buffer *activeBuffer;
827
D3D12Buffer **buffers;
828
Uint32 bufferCapacity;
831
D3D12_RESOURCE_DESC bufferDesc;
836
struct D3D12UniformBuffer
841
Uint32 currentBlockSize;
846
static void D3D12_ReleaseWindow(SDL_GPURenderer *driverData, SDL_Window *window);
847
static void D3D12_Wait(SDL_GPURenderer *driverData);
848
static void D3D12_WaitForFences(SDL_GPURenderer *driverData, bool waitAll, SDL_GPUFence **pFences, Uint32 fenceCount);
849
static void D3D12_INTERNAL_ReleaseBlitPipelines(SDL_GPURenderer *driverData);
853
static Uint32 D3D12_INTERNAL_Align(Uint32 location, Uint32 alignment)
855
return (location + (alignment - 1)) & ~(alignment - 1);
860
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
862
static ID3D12Device *s_Device;
863
static ID3D12CommandQueue *s_CommandQueue;
869
D3D12_INTERNAL_LogError(
870
ID3D12Device *device,
874
#define MAX_ERROR_LEN 1024
877
char wszMsgBuff[MAX_ERROR_LEN + 1];
880
if (res == DXGI_ERROR_DEVICE_REMOVED) {
882
res = ID3D12Device_GetDeviceRemovedReason(device);
887
dwChars = FormatMessageA(
888
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
898
SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s! Error Code: " HRESULT_FMT, msg, res);
903
dwChars = SDL_min(dwChars, MAX_ERROR_LEN);
906
while (dwChars > 0) {
907
if (wszMsgBuff[dwChars - 1] <= ' ') {
915
wszMsgBuff[dwChars] = '\0';
917
SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
922
static void D3D12_INTERNAL_SetResourceName(
923
D3D12Renderer *renderer,
924
ID3D12Resource *resource,
927
if (renderer->debugMode) {
928
ID3D12DeviceChild_SetPrivateData(
930
D3D_GUID(D3D_IID_D3DDebugObjectName),
931
(UINT)SDL_strlen(text),
939
static void D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
940
D3D12Renderer *renderer,
941
D3D12CPUDescriptor *cpuDescriptor)
943
D3D12DescriptorHeap *heap = cpuDescriptor->heap;
946
SDL_LockMutex(renderer->stagingDescriptorHeapLock);
947
heap->inactiveDescriptorIndices[heap->inactiveDescriptorCount] = cpuDescriptor->cpuHandleIndex;
948
heap->inactiveDescriptorCount += 1;
949
SDL_UnlockMutex(renderer->stagingDescriptorHeapLock);
952
cpuDescriptor->heap = NULL;
953
cpuDescriptor->cpuHandle.ptr = 0;
954
cpuDescriptor->cpuHandleIndex = SDL_MAX_UINT32;
957
static void D3D12_INTERNAL_DestroyBuffer(
958
D3D12Renderer *renderer,
965
if (buffer->mapPointer != NULL) {
966
ID3D12Resource_Unmap(
971
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
973
&buffer->srvDescriptor);
974
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
976
&buffer->uavDescriptor);
977
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
979
&buffer->cbvDescriptor);
981
if (buffer->handle) {
982
ID3D12Resource_Release(buffer->handle);
987
static void D3D12_INTERNAL_ReleaseBuffer(
988
D3D12Renderer *renderer,
991
SDL_LockMutex(renderer->disposeLock);
993
EXPAND_ARRAY_IF_NEEDED(
994
renderer->buffersToDestroy,
996
renderer->buffersToDestroyCount + 1,
997
renderer->buffersToDestroyCapacity,
998
renderer->buffersToDestroyCapacity * 2)
1000
renderer->buffersToDestroy[renderer->buffersToDestroyCount] = buffer;
1001
renderer->buffersToDestroyCount += 1;
1003
SDL_UnlockMutex(renderer->disposeLock);
1006
static void D3D12_INTERNAL_ReleaseBufferContainer(
1007
D3D12Renderer *renderer,
1008
D3D12BufferContainer *container)
1010
SDL_LockMutex(renderer->disposeLock);
1012
for (Uint32 i = 0; i < container->bufferCount; i += 1) {
1013
D3D12_INTERNAL_ReleaseBuffer(
1015
container->buffers[i]);
1019
if (container->debugName) {
1020
SDL_free(container->debugName);
1022
SDL_free(container->buffers);
1023
SDL_free(container);
1025
SDL_UnlockMutex(renderer->disposeLock);
1028
static void D3D12_INTERNAL_DestroyTexture(
1029
D3D12Renderer *renderer,
1030
D3D12Texture *texture)
1035
for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1036
D3D12TextureSubresource *subresource = &texture->subresources[i];
1037
if (subresource->rtvHandles) {
1038
for (Uint32 depthIndex = 0; depthIndex < subresource->depth; depthIndex += 1) {
1039
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
1041
&subresource->rtvHandles[depthIndex]);
1043
SDL_free(subresource->rtvHandles);
1046
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
1048
&subresource->uavHandle);
1050
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
1052
&subresource->dsvHandle);
1054
SDL_free(texture->subresources);
1056
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
1058
&texture->srvHandle);
1060
if (texture->resource) {
1061
ID3D12Resource_Release(texture->resource);
1067
static void D3D12_INTERNAL_ReleaseTexture(
1068
D3D12Renderer *renderer,
1069
D3D12Texture *texture)
1071
SDL_LockMutex(renderer->disposeLock);
1073
EXPAND_ARRAY_IF_NEEDED(
1074
renderer->texturesToDestroy,
1076
renderer->texturesToDestroyCount + 1,
1077
renderer->texturesToDestroyCapacity,
1078
renderer->texturesToDestroyCapacity * 2)
1080
renderer->texturesToDestroy[renderer->texturesToDestroyCount] = texture;
1081
renderer->texturesToDestroyCount += 1;
1083
SDL_UnlockMutex(renderer->disposeLock);
1086
static void D3D12_INTERNAL_ReleaseTextureContainer(
1087
D3D12Renderer *renderer,
1088
D3D12TextureContainer *container)
1090
SDL_LockMutex(renderer->disposeLock);
1092
for (Uint32 i = 0; i < container->textureCount; i += 1) {
1093
D3D12_INTERNAL_ReleaseTexture(
1095
container->textures[i]);
1099
if (container->debugName) {
1100
SDL_free(container->debugName);
1102
SDL_free(container->textures);
1103
SDL_free(container);
1105
SDL_UnlockMutex(renderer->disposeLock);
1108
static void D3D12_INTERNAL_DestroySampler(
1109
D3D12Renderer *renderer,
1110
D3D12Sampler *sampler)
1112
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
1119
static void D3D12_INTERNAL_DestroyGraphicsRootSignature(
1120
D3D12GraphicsRootSignature *rootSignature)
1122
if (!rootSignature) {
1125
if (rootSignature->handle) {
1126
ID3D12RootSignature_Release(rootSignature->handle);
1128
SDL_free(rootSignature);
1131
static void D3D12_INTERNAL_DestroyGraphicsPipeline(
1132
D3D12GraphicsPipeline *graphicsPipeline)
1134
if (graphicsPipeline->pipelineState) {
1135
ID3D12PipelineState_Release(graphicsPipeline->pipelineState);
1137
D3D12_INTERNAL_DestroyGraphicsRootSignature(graphicsPipeline->rootSignature);
1138
SDL_free(graphicsPipeline);
1141
static void D3D12_INTERNAL_DestroyComputeRootSignature(
1142
D3D12ComputeRootSignature *rootSignature)
1144
if (!rootSignature) {
1147
if (rootSignature->handle) {
1148
ID3D12RootSignature_Release(rootSignature->handle);
1150
SDL_free(rootSignature);
1153
static void D3D12_INTERNAL_DestroyComputePipeline(
1154
D3D12ComputePipeline *computePipeline)
1156
if (computePipeline->pipelineState) {
1157
ID3D12PipelineState_Release(computePipeline->pipelineState);
1159
D3D12_INTERNAL_DestroyComputeRootSignature(computePipeline->rootSignature);
1160
SDL_free(computePipeline);
1163
static void D3D12_INTERNAL_ReleaseFenceToPool(
1164
D3D12Renderer *renderer,
1167
SDL_LockMutex(renderer->fenceLock);
1169
EXPAND_ARRAY_IF_NEEDED(
1170
renderer->availableFences,
1172
renderer->availableFenceCount + 1,
1173
renderer->availableFenceCapacity,
1174
renderer->availableFenceCapacity * 2);
1176
renderer->availableFences[renderer->availableFenceCount] = fence;
1177
renderer->availableFenceCount += 1;
1179
SDL_UnlockMutex(renderer->fenceLock);
1182
static void D3D12_ReleaseFence(
1183
SDL_GPURenderer *driverData,
1184
SDL_GPUFence *fence)
1186
D3D12Fence *d3d12Fence = (D3D12Fence *)fence;
1188
if (SDL_AtomicDecRef(&d3d12Fence->referenceCount)) {
1189
D3D12_INTERNAL_ReleaseFenceToPool(
1190
(D3D12Renderer *)driverData,
1195
static bool D3D12_QueryFence(
1196
SDL_GPURenderer *driverData,
1197
SDL_GPUFence *fence)
1199
D3D12Fence *d3d12Fence = (D3D12Fence *)fence;
1200
return ID3D12Fence_GetCompletedValue(d3d12Fence->handle) == D3D12_FENCE_SIGNAL_VALUE;
1203
static void D3D12_INTERNAL_DestroyDescriptorHeap(D3D12DescriptorHeap *descriptorHeap)
1205
if (!descriptorHeap) {
1208
SDL_free(descriptorHeap->inactiveDescriptorIndices);
1209
if (descriptorHeap->handle) {
1210
ID3D12DescriptorHeap_Release(descriptorHeap->handle);
1212
SDL_free(descriptorHeap);
1215
static void D3D12_INTERNAL_DestroyCommandBuffer(D3D12CommandBuffer *commandBuffer)
1217
if (!commandBuffer) {
1220
if (commandBuffer->graphicsCommandList) {
1221
ID3D12GraphicsCommandList_Release(commandBuffer->graphicsCommandList);
1223
if (commandBuffer->commandAllocator) {
1224
ID3D12CommandAllocator_Release(commandBuffer->commandAllocator);
1226
SDL_free(commandBuffer->presentDatas);
1227
SDL_free(commandBuffer->usedTextures);
1228
SDL_free(commandBuffer->usedBuffers);
1229
SDL_free(commandBuffer->usedSamplers);
1230
SDL_free(commandBuffer->usedGraphicsPipelines);
1231
SDL_free(commandBuffer->usedComputePipelines);
1232
SDL_free(commandBuffer->usedUniformBuffers);
1233
SDL_free(commandBuffer->textureDownloads);
1234
SDL_free(commandBuffer);
1237
static void D3D12_INTERNAL_DestroyFence(D3D12Fence *fence)
1242
if (fence->handle) {
1243
ID3D12Fence_Release(fence->handle);
1246
CloseHandle(fence->event);
1251
static void D3D12_INTERNAL_DestroyRenderer(D3D12Renderer *renderer)
1254
for (Uint32 i = 0; i < renderer->uniformBufferPoolCount; i += 1) {
1255
D3D12_INTERNAL_DestroyBuffer(
1257
renderer->uniformBufferPool[i]->buffer);
1258
SDL_free(renderer->uniformBufferPool[i]);
1262
for (Uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1) {
1263
if (renderer->stagingDescriptorHeaps[i]) {
1264
D3D12_INTERNAL_DestroyDescriptorHeap(renderer->stagingDescriptorHeaps[i]);
1265
renderer->stagingDescriptorHeaps[i] = NULL;
1269
for (Uint32 i = 0; i < 2; i += 1) {
1270
if (renderer->descriptorHeapPools[i].heaps) {
1271
for (Uint32 j = 0; j < renderer->descriptorHeapPools[i].count; j += 1) {
1272
if (renderer->descriptorHeapPools[i].heaps[j]) {
1273
D3D12_INTERNAL_DestroyDescriptorHeap(renderer->descriptorHeapPools[i].heaps[j]);
1274
renderer->descriptorHeapPools[i].heaps[j] = NULL;
1277
SDL_free(renderer->descriptorHeapPools[i].heaps);
1279
if (renderer->descriptorHeapPools[i].lock) {
1280
SDL_DestroyMutex(renderer->descriptorHeapPools[i].lock);
1281
renderer->descriptorHeapPools[i].lock = NULL;
1286
for (Uint32 i = 0; i < renderer->availableCommandBufferCount; i += 1) {
1287
if (renderer->availableCommandBuffers[i]) {
1288
D3D12_INTERNAL_DestroyCommandBuffer(renderer->availableCommandBuffers[i]);
1289
renderer->availableCommandBuffers[i] = NULL;
1294
for (Uint32 i = 0; i < renderer->availableFenceCount; i += 1) {
1295
if (renderer->availableFences[i]) {
1296
D3D12_INTERNAL_DestroyFence(renderer->availableFences[i]);
1297
renderer->availableFences[i] = NULL;
1302
SDL_free(renderer->availableCommandBuffers);
1303
SDL_free(renderer->submittedCommandBuffers);
1304
SDL_free(renderer->uniformBufferPool);
1305
SDL_free(renderer->claimedWindows);
1306
SDL_free(renderer->availableFences);
1307
SDL_free(renderer->buffersToDestroy);
1308
SDL_free(renderer->texturesToDestroy);
1309
SDL_free(renderer->samplersToDestroy);
1310
SDL_free(renderer->graphicsPipelinesToDestroy);
1311
SDL_free(renderer->computePipelinesToDestroy);
1314
if (renderer->indirectDrawCommandSignature) {
1315
ID3D12CommandSignature_Release(renderer->indirectDrawCommandSignature);
1316
renderer->indirectDrawCommandSignature = NULL;
1318
if (renderer->indirectIndexedDrawCommandSignature) {
1319
ID3D12CommandSignature_Release(renderer->indirectIndexedDrawCommandSignature);
1320
renderer->indirectIndexedDrawCommandSignature = NULL;
1322
if (renderer->indirectDispatchCommandSignature) {
1323
ID3D12CommandSignature_Release(renderer->indirectDispatchCommandSignature);
1324
renderer->indirectDispatchCommandSignature = NULL;
1326
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
1327
if (renderer->commandQueue) {
1328
ID3D12CommandQueue_Release(renderer->commandQueue);
1329
renderer->commandQueue = NULL;
1331
if (renderer->device) {
1332
ID3D12Device_Release(renderer->device);
1333
renderer->device = NULL;
1335
if (renderer->adapter) {
1336
IDXGIAdapter1_Release(renderer->adapter);
1337
renderer->adapter = NULL;
1339
if (renderer->factory) {
1340
IDXGIFactory4_Release(renderer->factory);
1341
renderer->factory = NULL;
1343
if (renderer->dxgiDebug) {
1344
IDXGIDebug_ReportLiveObjects(
1345
renderer->dxgiDebug,
1346
D3D_IID_DXGI_DEBUG_ALL,
1347
(DXGI_DEBUG_RLO_FLAGS)(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
1348
IDXGIDebug_Release(renderer->dxgiDebug);
1349
renderer->dxgiDebug = NULL;
1352
if (renderer->d3d12_dll) {
1353
SDL_UnloadObject(renderer->d3d12_dll);
1354
renderer->d3d12_dll = NULL;
1356
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
1357
if (renderer->dxgi_dll) {
1358
SDL_UnloadObject(renderer->dxgi_dll);
1359
renderer->dxgi_dll = NULL;
1361
if (renderer->dxgidebug_dll) {
1362
SDL_UnloadObject(renderer->dxgidebug_dll);
1363
renderer->dxgidebug_dll = NULL;
1366
renderer->D3D12SerializeRootSignature_func = NULL;
1368
if (renderer->iconv) {
1369
SDL_iconv_close(renderer->iconv);
1372
SDL_DestroyMutex(renderer->stagingDescriptorHeapLock);
1373
SDL_DestroyMutex(renderer->acquireCommandBufferLock);
1374
SDL_DestroyMutex(renderer->acquireUniformBufferLock);
1375
SDL_DestroyMutex(renderer->submitLock);
1376
SDL_DestroyMutex(renderer->windowLock);
1377
SDL_DestroyMutex(renderer->fenceLock);
1378
SDL_DestroyMutex(renderer->disposeLock);
1382
static void D3D12_DestroyDevice(SDL_GPUDevice *device)
1384
D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
1387
D3D12_INTERNAL_ReleaseBlitPipelines((SDL_GPURenderer *)renderer);
1390
D3D12_Wait((SDL_GPURenderer *)renderer);
1393
for (Sint32 i = renderer->claimedWindowCount - 1; i >= 0; i -= 1) {
1394
D3D12_ReleaseWindow((SDL_GPURenderer *)renderer, renderer->claimedWindows[i]->window);
1397
D3D12_INTERNAL_DestroyRenderer(renderer);
1403
static inline Uint32 D3D12_INTERNAL_CalcSubresource(
1408
return mipLevel + (layer * numLevels);
1411
static void D3D12_INTERNAL_ResourceBarrier(
1412
D3D12CommandBuffer *commandBuffer,
1413
D3D12_RESOURCE_STATES sourceState,
1414
D3D12_RESOURCE_STATES destinationState,
1415
ID3D12Resource *resource,
1416
Uint32 subresourceIndex,
1417
bool needsUavBarrier)
1419
D3D12_RESOURCE_BARRIER barrierDesc[2];
1420
Uint32 numBarriers = 0;
1423
if (sourceState != destinationState) {
1424
barrierDesc[numBarriers].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
1425
barrierDesc[numBarriers].Flags = (D3D12_RESOURCE_BARRIER_FLAGS)0;
1426
barrierDesc[numBarriers].Transition.StateBefore = sourceState;
1427
barrierDesc[numBarriers].Transition.StateAfter = destinationState;
1428
barrierDesc[numBarriers].Transition.pResource = resource;
1429
barrierDesc[numBarriers].Transition.Subresource = subresourceIndex;
1434
if (needsUavBarrier) {
1435
barrierDesc[numBarriers].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
1436
barrierDesc[numBarriers].Flags = (D3D12_RESOURCE_BARRIER_FLAGS)0;
1437
barrierDesc[numBarriers].UAV.pResource = resource;
1442
if (numBarriers > 0) {
1443
ID3D12GraphicsCommandList_ResourceBarrier(
1444
commandBuffer->graphicsCommandList,
1450
static void D3D12_INTERNAL_TextureSubresourceBarrier(
1451
D3D12CommandBuffer *commandBuffer,
1452
D3D12_RESOURCE_STATES sourceState,
1453
D3D12_RESOURCE_STATES destinationState,
1454
D3D12TextureSubresource *textureSubresource)
1456
D3D12_INTERNAL_ResourceBarrier(
1460
textureSubresource->parent->resource,
1461
textureSubresource->index,
1462
textureSubresource->parent->container->header.info.usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE);
1465
static D3D12_RESOURCE_STATES D3D12_INTERNAL_DefaultTextureResourceState(
1466
SDL_GPUTextureUsageFlags usageFlags)
1470
if (usageFlags & SDL_GPU_TEXTUREUSAGE_SAMPLER) {
1471
return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1472
} else if (usageFlags & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) {
1473
return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1474
} else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
1475
return D3D12_RESOURCE_STATE_RENDER_TARGET;
1476
} else if (usageFlags & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
1477
return D3D12_RESOURCE_STATE_DEPTH_WRITE;
1478
} else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ) {
1479
return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1480
} else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) {
1481
return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1483
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Texture has no default usage mode!");
1484
return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1488
static void D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
1489
D3D12CommandBuffer *commandBuffer,
1490
D3D12_RESOURCE_STATES destinationUsageMode,
1491
D3D12TextureSubresource *textureSubresource)
1493
D3D12_INTERNAL_TextureSubresourceBarrier(
1495
D3D12_INTERNAL_DefaultTextureResourceState(textureSubresource->parent->container->header.info.usageFlags),
1496
destinationUsageMode,
1497
textureSubresource);
1500
static void D3D12_INTERNAL_TextureTransitionFromDefaultUsage(
1501
D3D12CommandBuffer *commandBuffer,
1502
D3D12_RESOURCE_STATES destinationUsageMode,
1503
D3D12Texture *texture)
1505
for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1506
D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
1508
destinationUsageMode,
1509
&texture->subresources[i]);
1513
static void D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
1514
D3D12CommandBuffer *commandBuffer,
1515
D3D12_RESOURCE_STATES sourceUsageMode,
1516
D3D12TextureSubresource *textureSubresource)
1518
D3D12_INTERNAL_TextureSubresourceBarrier(
1521
D3D12_INTERNAL_DefaultTextureResourceState(textureSubresource->parent->container->header.info.usageFlags),
1522
textureSubresource);
1525
static void D3D12_INTERNAL_TextureTransitionToDefaultUsage(
1526
D3D12CommandBuffer *commandBuffer,
1527
D3D12_RESOURCE_STATES sourceUsageMode,
1528
D3D12Texture *texture)
1530
for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1531
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
1534
&texture->subresources[i]);
1538
static D3D12_RESOURCE_STATES D3D12_INTERNAL_DefaultBufferResourceState(
1539
D3D12Buffer *buffer)
1541
if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_VERTEX) {
1542
return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
1543
} else if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_INDEX) {
1544
return D3D12_RESOURCE_STATE_INDEX_BUFFER;
1545
} else if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_INDIRECT) {
1546
return D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT;
1547
} else if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ) {
1548
return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1549
} else if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ) {
1550
return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1551
} else if (buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
1552
return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1554
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Buffer has no default usage mode!");
1555
return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
1559
static void D3D12_INTERNAL_BufferBarrier(
1560
D3D12CommandBuffer *commandBuffer,
1561
D3D12_RESOURCE_STATES sourceState,
1562
D3D12_RESOURCE_STATES destinationState,
1563
D3D12Buffer *buffer)
1565
D3D12_INTERNAL_ResourceBarrier(
1567
buffer->transitioned ? sourceState : D3D12_RESOURCE_STATE_COMMON,
1571
buffer->container->usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE);
1573
buffer->transitioned = true;
1576
static void D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
1577
D3D12CommandBuffer *commandBuffer,
1578
D3D12_RESOURCE_STATES destinationState,
1579
D3D12Buffer *buffer)
1581
D3D12_INTERNAL_BufferBarrier(
1583
D3D12_INTERNAL_DefaultBufferResourceState(buffer),
1588
static void D3D12_INTERNAL_BufferTransitionToDefaultUsage(
1589
D3D12CommandBuffer *commandBuffer,
1590
D3D12_RESOURCE_STATES sourceState,
1591
D3D12Buffer *buffer)
1593
D3D12_INTERNAL_BufferBarrier(
1596
D3D12_INTERNAL_DefaultBufferResourceState(buffer),
1602
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
1605
for (i = 0; i < commandBuffer->count; i += 1) { \
1606
if (commandBuffer->array[i] == resource) { \
1611
if (commandBuffer->count == commandBuffer->capacity) { \
1612
commandBuffer->capacity += 1; \
1613
commandBuffer->array = (type *)SDL_realloc( \
1614
commandBuffer->array, \
1615
commandBuffer->capacity * sizeof(type)); \
1617
commandBuffer->array[commandBuffer->count] = resource; \
1618
commandBuffer->count += 1; \
1619
SDL_AtomicIncRef(&resource->referenceCount);
1621
static void D3D12_INTERNAL_TrackTexture(
1622
D3D12CommandBuffer *commandBuffer,
1623
D3D12Texture *texture)
1630
usedTextureCapacity)
1633
static void D3D12_INTERNAL_TrackBuffer(
1634
D3D12CommandBuffer *commandBuffer,
1635
D3D12Buffer *buffer)
1645
static void D3D12_INTERNAL_TrackSampler(
1646
D3D12CommandBuffer *commandBuffer,
1647
D3D12Sampler *sampler)
1654
usedSamplerCapacity)
1657
static void D3D12_INTERNAL_TrackGraphicsPipeline(
1658
D3D12CommandBuffer *commandBuffer,
1659
D3D12GraphicsPipeline *graphicsPipeline)
1663
D3D12GraphicsPipeline *,
1664
usedGraphicsPipelines,
1665
usedGraphicsPipelineCount,
1666
usedGraphicsPipelineCapacity)
1669
static void D3D12_INTERNAL_TrackComputePipeline(
1670
D3D12CommandBuffer *commandBuffer,
1671
D3D12ComputePipeline *computePipeline)
1675
D3D12ComputePipeline *,
1676
usedComputePipelines,
1677
usedComputePipelineCount,
1678
usedComputePipelineCapacity)
1681
#undef TRACK_RESOURCE
1685
static D3D12DescriptorHeap *D3D12_INTERNAL_CreateDescriptorHeap(
1686
D3D12Renderer *renderer,
1687
D3D12_DESCRIPTOR_HEAP_TYPE type,
1688
Uint32 descriptorCount,
1691
D3D12DescriptorHeap *heap;
1692
ID3D12DescriptorHeap *handle;
1693
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
1696
heap = (D3D12DescriptorHeap *)SDL_calloc(1, sizeof(D3D12DescriptorHeap));
1701
heap->currentDescriptorIndex = 0;
1702
heap->inactiveDescriptorCount = 0;
1703
heap->inactiveDescriptorIndices = NULL;
1706
heap->inactiveDescriptorIndices = (Uint32 *)SDL_calloc(descriptorCount, sizeof(Uint32));
1707
if (!heap->inactiveDescriptorIndices) {
1708
D3D12_INTERNAL_DestroyDescriptorHeap(heap);
1713
heapDesc.NumDescriptors = descriptorCount;
1714
heapDesc.Type = type;
1715
heapDesc.Flags = staging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
1716
heapDesc.NodeMask = 0;
1718
res = ID3D12Device_CreateDescriptorHeap(
1721
D3D_GUID(D3D_IID_ID3D12DescriptorHeap),
1725
D3D12_INTERNAL_LogError(renderer->device, "Failed to create descriptor heap!", res);
1726
D3D12_INTERNAL_DestroyDescriptorHeap(heap);
1730
heap->handle = handle;
1731
heap->heapType = type;
1732
heap->maxDescriptors = descriptorCount;
1733
heap->staging = staging;
1734
heap->descriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(renderer->device, type);
1735
D3D_CALL_RET(handle, GetCPUDescriptorHandleForHeapStart, &heap->descriptorHeapCPUStart);
1737
D3D_CALL_RET(handle, GetGPUDescriptorHandleForHeapStart, &heap->descriptorHeapGPUStart);
1743
static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireDescriptorHeapFromPool(
1744
D3D12CommandBuffer *commandBuffer,
1745
D3D12_DESCRIPTOR_HEAP_TYPE descriptorHeapType)
1747
D3D12DescriptorHeap *result;
1748
D3D12Renderer *renderer = commandBuffer->renderer;
1749
D3D12DescriptorHeapPool *pool = &renderer->descriptorHeapPools[descriptorHeapType];
1751
SDL_LockMutex(pool->lock);
1752
if (pool->count > 0) {
1753
result = pool->heaps[pool->count - 1];
1756
result = D3D12_INTERNAL_CreateDescriptorHeap(
1759
descriptorHeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ? VIEW_GPU_DESCRIPTOR_COUNT : SAMPLER_GPU_DESCRIPTOR_COUNT,
1762
SDL_UnlockMutex(pool->lock);
1767
static void D3D12_INTERNAL_ReturnDescriptorHeapToPool(
1768
D3D12Renderer *renderer,
1769
D3D12DescriptorHeap *heap)
1771
D3D12DescriptorHeapPool *pool = &renderer->descriptorHeapPools[heap->heapType];
1773
heap->currentDescriptorIndex = 0;
1775
SDL_LockMutex(pool->lock);
1776
if (pool->count >= pool->capacity) {
1777
pool->capacity *= 2;
1778
pool->heaps = (D3D12DescriptorHeap **)SDL_realloc(
1780
pool->capacity * sizeof(D3D12DescriptorHeap *));
1783
pool->heaps[pool->count] = heap;
1785
SDL_UnlockMutex(pool->lock);
1806
static D3D12GraphicsRootSignature *D3D12_INTERNAL_CreateGraphicsRootSignature(
1807
D3D12Renderer *renderer,
1808
D3D12Shader *vertexShader,
1809
D3D12Shader *fragmentShader)
1812
D3D12_ROOT_PARAMETER rootParameters[MAX_ROOT_SIGNATURE_PARAMETERS];
1813
D3D12_DESCRIPTOR_RANGE descriptorRanges[MAX_ROOT_SIGNATURE_PARAMETERS];
1814
Uint32 parameterCount = 0;
1815
Uint32 rangeCount = 0;
1816
D3D12_DESCRIPTOR_RANGE descriptorRange;
1817
D3D12_ROOT_PARAMETER rootParameter;
1818
D3D12GraphicsRootSignature *d3d12GraphicsRootSignature =
1819
(D3D12GraphicsRootSignature *)SDL_calloc(1, sizeof(D3D12GraphicsRootSignature));
1820
if (!d3d12GraphicsRootSignature) {
1824
SDL_zeroa(rootParameters);
1825
SDL_zeroa(descriptorRanges);
1826
SDL_zero(rootParameter);
1828
d3d12GraphicsRootSignature->vertexSamplerRootIndex = -1;
1829
d3d12GraphicsRootSignature->vertexSamplerTextureRootIndex = -1;
1830
d3d12GraphicsRootSignature->vertexStorageTextureRootIndex = -1;
1831
d3d12GraphicsRootSignature->vertexStorageBufferRootIndex = -1;
1833
d3d12GraphicsRootSignature->fragmentSamplerRootIndex = -1;
1834
d3d12GraphicsRootSignature->fragmentSamplerTextureRootIndex = -1;
1835
d3d12GraphicsRootSignature->fragmentStorageTextureRootIndex = -1;
1836
d3d12GraphicsRootSignature->fragmentStorageBufferRootIndex = -1;
1838
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
1839
d3d12GraphicsRootSignature->vertexUniformBufferRootIndex[i] = -1;
1840
d3d12GraphicsRootSignature->fragmentUniformBufferRootIndex[i] = -1;
1843
if (vertexShader->samplerCount > 0) {
1845
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
1846
descriptorRange.NumDescriptors = vertexShader->samplerCount;
1847
descriptorRange.BaseShaderRegister = 0;
1848
descriptorRange.RegisterSpace = 0;
1849
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1850
descriptorRanges[rangeCount] = descriptorRange;
1852
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1853
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1854
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1855
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1856
rootParameters[parameterCount] = rootParameter;
1857
d3d12GraphicsRootSignature->vertexSamplerRootIndex = parameterCount;
1859
parameterCount += 1;
1861
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1862
descriptorRange.NumDescriptors = vertexShader->samplerCount;
1863
descriptorRange.BaseShaderRegister = 0;
1864
descriptorRange.RegisterSpace = 0;
1865
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1866
descriptorRanges[rangeCount] = descriptorRange;
1868
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1869
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1870
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1871
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1872
rootParameters[parameterCount] = rootParameter;
1873
d3d12GraphicsRootSignature->vertexSamplerTextureRootIndex = parameterCount;
1875
parameterCount += 1;
1878
if (vertexShader->storageTextureCount) {
1880
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1881
descriptorRange.NumDescriptors = vertexShader->storageTextureCount;
1882
descriptorRange.BaseShaderRegister = vertexShader->samplerCount;
1883
descriptorRange.RegisterSpace = 0;
1884
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1885
descriptorRanges[rangeCount] = descriptorRange;
1887
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1888
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1889
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1890
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1891
rootParameters[parameterCount] = rootParameter;
1892
d3d12GraphicsRootSignature->vertexStorageTextureRootIndex = parameterCount;
1894
parameterCount += 1;
1897
if (vertexShader->storageBufferCount) {
1900
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1901
descriptorRange.NumDescriptors = vertexShader->storageBufferCount;
1902
descriptorRange.BaseShaderRegister = vertexShader->samplerCount + vertexShader->storageTextureCount;
1903
descriptorRange.RegisterSpace = 0;
1904
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1905
descriptorRanges[rangeCount] = descriptorRange;
1907
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1908
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1909
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1910
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1911
rootParameters[parameterCount] = rootParameter;
1912
d3d12GraphicsRootSignature->vertexStorageBufferRootIndex = parameterCount;
1914
parameterCount += 1;
1918
for (Uint32 i = 0; i < vertexShader->uniformBufferCount; i += 1) {
1919
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
1920
rootParameter.Descriptor.ShaderRegister = i;
1921
rootParameter.Descriptor.RegisterSpace = 1;
1922
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1923
rootParameters[parameterCount] = rootParameter;
1924
d3d12GraphicsRootSignature->vertexUniformBufferRootIndex[i] = parameterCount;
1925
parameterCount += 1;
1928
if (fragmentShader->samplerCount) {
1930
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
1931
descriptorRange.NumDescriptors = fragmentShader->samplerCount;
1932
descriptorRange.BaseShaderRegister = 0;
1933
descriptorRange.RegisterSpace = 2;
1934
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1935
descriptorRanges[rangeCount] = descriptorRange;
1937
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1938
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1939
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1940
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
1941
rootParameters[parameterCount] = rootParameter;
1942
d3d12GraphicsRootSignature->fragmentSamplerRootIndex = parameterCount;
1944
parameterCount += 1;
1946
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1947
descriptorRange.NumDescriptors = fragmentShader->samplerCount;
1948
descriptorRange.BaseShaderRegister = 0;
1949
descriptorRange.RegisterSpace = 2;
1950
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1951
descriptorRanges[rangeCount] = descriptorRange;
1953
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1954
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1955
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1956
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
1957
rootParameters[parameterCount] = rootParameter;
1958
d3d12GraphicsRootSignature->fragmentSamplerTextureRootIndex = parameterCount;
1960
parameterCount += 1;
1963
if (fragmentShader->storageTextureCount) {
1965
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1966
descriptorRange.NumDescriptors = fragmentShader->storageTextureCount;
1967
descriptorRange.BaseShaderRegister = fragmentShader->samplerCount;
1968
descriptorRange.RegisterSpace = 2;
1969
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1970
descriptorRanges[rangeCount] = descriptorRange;
1972
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1973
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1974
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1975
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
1976
rootParameters[parameterCount] = rootParameter;
1977
d3d12GraphicsRootSignature->fragmentStorageTextureRootIndex = parameterCount;
1979
parameterCount += 1;
1982
if (fragmentShader->storageBufferCount) {
1984
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
1985
descriptorRange.NumDescriptors = fragmentShader->storageBufferCount;
1986
descriptorRange.BaseShaderRegister = fragmentShader->samplerCount + fragmentShader->storageTextureCount;
1987
descriptorRange.RegisterSpace = 2;
1988
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
1989
descriptorRanges[rangeCount] = descriptorRange;
1991
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
1992
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
1993
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
1994
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
1995
rootParameters[parameterCount] = rootParameter;
1996
d3d12GraphicsRootSignature->fragmentStorageBufferRootIndex = parameterCount;
1998
parameterCount += 1;
2002
for (Uint32 i = 0; i < fragmentShader->uniformBufferCount; i += 1) {
2003
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
2004
rootParameter.Descriptor.ShaderRegister = i;
2005
rootParameter.Descriptor.RegisterSpace = 3;
2006
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2007
rootParameters[parameterCount] = rootParameter;
2008
d3d12GraphicsRootSignature->fragmentUniformBufferRootIndex[i] = parameterCount;
2009
parameterCount += 1;
2013
SDL_assert(parameterCount <= MAX_ROOT_SIGNATURE_PARAMETERS);
2014
SDL_assert(rangeCount <= MAX_ROOT_SIGNATURE_PARAMETERS);
2017
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
2018
rootSignatureDesc.NumParameters = parameterCount;
2019
rootSignatureDesc.pParameters = rootParameters;
2020
rootSignatureDesc.NumStaticSamplers = 0;
2021
rootSignatureDesc.pStaticSamplers = NULL;
2022
rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
2025
ID3DBlob *serializedRootSignature;
2026
ID3DBlob *errorBlob;
2027
HRESULT res = renderer->D3D12SerializeRootSignature_func(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedRootSignature, &errorBlob);
2031
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to serialize RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2032
ID3D10Blob_Release(errorBlob);
2034
D3D12_INTERNAL_DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
2039
ID3D12RootSignature *rootSignature;
2041
res = ID3D12Device_CreateRootSignature(
2044
ID3D10Blob_GetBufferPointer(serializedRootSignature),
2045
ID3D10Blob_GetBufferSize(serializedRootSignature),
2046
D3D_GUID(D3D_IID_ID3D12RootSignature),
2047
(void **)&rootSignature);
2051
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create RootSignature");
2052
ID3D10Blob_Release(errorBlob);
2054
D3D12_INTERNAL_DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
2058
d3d12GraphicsRootSignature->handle = rootSignature;
2059
return d3d12GraphicsRootSignature;
2062
static bool D3D12_INTERNAL_CreateShaderBytecode(
2063
D3D12Renderer *renderer,
2065
SDL_GPUShaderFormat format,
2068
const char *entryPointName,
2070
size_t *pBytecodeSize)
2072
if (pBytecode != NULL) {
2073
*pBytecode = SDL_malloc(codeSize);
2077
SDL_memcpy(*pBytecode, code, codeSize);
2078
*pBytecodeSize = codeSize;
2084
static D3D12ComputeRootSignature *D3D12_INTERNAL_CreateComputeRootSignature(
2085
D3D12Renderer *renderer,
2086
SDL_GPUComputePipelineCreateInfo *createInfo)
2089
D3D12_ROOT_PARAMETER rootParameters[MAX_ROOT_SIGNATURE_PARAMETERS];
2090
D3D12_DESCRIPTOR_RANGE descriptorRanges[MAX_ROOT_SIGNATURE_PARAMETERS];
2091
Uint32 parameterCount = 0;
2092
Uint32 rangeCount = 0;
2093
D3D12_DESCRIPTOR_RANGE descriptorRange;
2094
D3D12_ROOT_PARAMETER rootParameter;
2095
D3D12ComputeRootSignature *d3d12ComputeRootSignature =
2096
(D3D12ComputeRootSignature *)SDL_calloc(1, sizeof(D3D12ComputeRootSignature));
2097
if (!d3d12ComputeRootSignature) {
2101
SDL_zeroa(rootParameters);
2102
SDL_zeroa(descriptorRanges);
2103
SDL_zero(rootParameter);
2105
d3d12ComputeRootSignature->readOnlyStorageTextureRootIndex = -1;
2106
d3d12ComputeRootSignature->readOnlyStorageBufferRootIndex = -1;
2107
d3d12ComputeRootSignature->writeOnlyStorageTextureRootIndex = -1;
2108
d3d12ComputeRootSignature->writeOnlyStorageBufferRootIndex = -1;
2110
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
2111
d3d12ComputeRootSignature->uniformBufferRootIndex[i] = -1;
2114
if (createInfo->readOnlyStorageTextureCount) {
2115
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2116
descriptorRange.NumDescriptors = createInfo->readOnlyStorageTextureCount;
2117
descriptorRange.BaseShaderRegister = 0;
2118
descriptorRange.RegisterSpace = 0;
2119
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2120
descriptorRanges[rangeCount] = descriptorRange;
2122
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2123
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2124
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2125
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2126
rootParameters[parameterCount] = rootParameter;
2127
d3d12ComputeRootSignature->readOnlyStorageTextureRootIndex = parameterCount;
2129
parameterCount += 1;
2132
if (createInfo->readOnlyStorageBufferCount) {
2133
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2134
descriptorRange.NumDescriptors = createInfo->readOnlyStorageBufferCount;
2135
descriptorRange.BaseShaderRegister = createInfo->readOnlyStorageTextureCount;
2136
descriptorRange.RegisterSpace = 0;
2137
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2138
descriptorRanges[rangeCount] = descriptorRange;
2140
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2141
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2142
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2143
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2144
rootParameters[parameterCount] = rootParameter;
2145
d3d12ComputeRootSignature->readOnlyStorageBufferRootIndex = parameterCount;
2147
parameterCount += 1;
2150
if (createInfo->writeOnlyStorageTextureCount) {
2151
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
2152
descriptorRange.NumDescriptors = createInfo->writeOnlyStorageTextureCount;
2153
descriptorRange.BaseShaderRegister = 0;
2154
descriptorRange.RegisterSpace = 1;
2155
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2156
descriptorRanges[rangeCount] = descriptorRange;
2158
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2159
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2160
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2161
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2162
rootParameters[parameterCount] = rootParameter;
2163
d3d12ComputeRootSignature->writeOnlyStorageTextureRootIndex = parameterCount;
2165
parameterCount += 1;
2168
if (createInfo->writeOnlyStorageBufferCount) {
2169
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
2170
descriptorRange.NumDescriptors = createInfo->writeOnlyStorageBufferCount;
2171
descriptorRange.BaseShaderRegister = createInfo->writeOnlyStorageTextureCount;
2172
descriptorRange.RegisterSpace = 1;
2173
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2174
descriptorRanges[rangeCount] = descriptorRange;
2176
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2177
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2178
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2179
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2180
rootParameters[parameterCount] = rootParameter;
2181
d3d12ComputeRootSignature->writeOnlyStorageBufferRootIndex = parameterCount;
2183
parameterCount += 1;
2186
for (Uint32 i = 0; i < createInfo->uniformBufferCount; i += 1) {
2187
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
2188
rootParameter.Descriptor.ShaderRegister = i;
2189
rootParameter.Descriptor.RegisterSpace = 2;
2190
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2191
rootParameters[parameterCount] = rootParameter;
2192
d3d12ComputeRootSignature->uniformBufferRootIndex[i] = parameterCount;
2193
parameterCount += 1;
2196
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
2197
rootSignatureDesc.NumParameters = parameterCount;
2198
rootSignatureDesc.pParameters = rootParameters;
2199
rootSignatureDesc.NumStaticSamplers = 0;
2200
rootSignatureDesc.pStaticSamplers = NULL;
2201
rootSignatureDesc.Flags = (D3D12_ROOT_SIGNATURE_FLAGS)0;
2203
ID3DBlob *serializedRootSignature;
2204
ID3DBlob *errorBlob;
2205
HRESULT res = renderer->D3D12SerializeRootSignature_func(
2207
D3D_ROOT_SIGNATURE_VERSION_1,
2208
&serializedRootSignature,
2213
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to serialize RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2214
ID3D10Blob_Release(errorBlob);
2216
D3D12_INTERNAL_DestroyComputeRootSignature(d3d12ComputeRootSignature);
2220
ID3D12RootSignature *rootSignature;
2222
res = ID3D12Device_CreateRootSignature(
2225
ID3D10Blob_GetBufferPointer(serializedRootSignature),
2226
ID3D10Blob_GetBufferSize(serializedRootSignature),
2227
D3D_GUID(D3D_IID_ID3D12RootSignature),
2228
(void **)&rootSignature);
2232
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create RootSignature");
2233
ID3D10Blob_Release(errorBlob);
2235
D3D12_INTERNAL_DestroyComputeRootSignature(d3d12ComputeRootSignature);
2239
d3d12ComputeRootSignature->handle = rootSignature;
2240
return d3d12ComputeRootSignature;
2243
static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
2244
SDL_GPURenderer *driverData,
2245
SDL_GPUComputePipelineCreateInfo *pipelineCreateInfo)
2247
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2249
size_t bytecodeSize;
2250
ID3D12PipelineState *pipelineState;
2252
if (!D3D12_INTERNAL_CreateShaderBytecode(
2254
SDL_GPU_SHADERSTAGE_COMPUTE,
2255
pipelineCreateInfo->format,
2256
pipelineCreateInfo->code,
2257
pipelineCreateInfo->codeSize,
2258
pipelineCreateInfo->entryPointName,
2264
D3D12ComputeRootSignature *rootSignature = D3D12_INTERNAL_CreateComputeRootSignature(
2266
pipelineCreateInfo);
2268
if (rootSignature == NULL) {
2269
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create root signature!");
2274
D3D12_COMPUTE_PIPELINE_STATE_DESC pipelineDesc;
2275
pipelineDesc.CS.pShaderBytecode = bytecode;
2276
pipelineDesc.CS.BytecodeLength = bytecodeSize;
2277
pipelineDesc.pRootSignature = rootSignature->handle;
2278
pipelineDesc.CachedPSO.CachedBlobSizeInBytes = 0;
2279
pipelineDesc.CachedPSO.pCachedBlob = NULL;
2280
pipelineDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
2281
pipelineDesc.NodeMask = 0;
2283
HRESULT res = ID3D12Device_CreateComputePipelineState(
2286
D3D_GUID(D3D_IID_ID3D12PipelineState),
2287
(void **)&pipelineState);
2290
D3D12_INTERNAL_LogError(renderer->device, "Could not create compute pipeline state", res);
2295
D3D12ComputePipeline *computePipeline =
2296
(D3D12ComputePipeline *)SDL_calloc(1, sizeof(D3D12ComputePipeline));
2298
if (!computePipeline) {
2299
ID3D12PipelineState_Release(pipelineState);
2304
computePipeline->pipelineState = pipelineState;
2305
computePipeline->rootSignature = rootSignature;
2306
computePipeline->readOnlyStorageTextureCount = pipelineCreateInfo->readOnlyStorageTextureCount;
2307
computePipeline->readOnlyStorageBufferCount = pipelineCreateInfo->readOnlyStorageBufferCount;
2308
computePipeline->writeOnlyStorageTextureCount = pipelineCreateInfo->writeOnlyStorageTextureCount;
2309
computePipeline->writeOnlyStorageBufferCount = pipelineCreateInfo->writeOnlyStorageBufferCount;
2310
computePipeline->uniformBufferCount = pipelineCreateInfo->uniformBufferCount;
2311
SDL_AtomicSet(&computePipeline->referenceCount, 0);
2313
return (SDL_GPUComputePipeline *)computePipeline;
2316
static bool D3D12_INTERNAL_ConvertRasterizerState(SDL_GPURasterizerState rasterizerState, D3D12_RASTERIZER_DESC *desc)
2322
desc->FillMode = SDLToD3D12_FillMode[rasterizerState.fillMode];
2323
desc->CullMode = SDLToD3D12_CullMode[rasterizerState.cullMode];
2325
switch (rasterizerState.frontFace) {
2326
case SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE:
2327
desc->FrontCounterClockwise = TRUE;
2329
case SDL_GPU_FRONTFACE_CLOCKWISE:
2330
desc->FrontCounterClockwise = FALSE;
2336
if (rasterizerState.depthBiasEnable) {
2337
desc->DepthBias = SDL_lroundf(rasterizerState.depthBiasConstantFactor);
2338
desc->DepthBiasClamp = rasterizerState.depthBiasClamp;
2339
desc->SlopeScaledDepthBias = rasterizerState.depthBiasSlopeFactor;
2341
desc->DepthBias = 0;
2342
desc->DepthBiasClamp = 0.0f;
2343
desc->SlopeScaledDepthBias = 0.0f;
2346
desc->DepthClipEnable = TRUE;
2347
desc->MultisampleEnable = FALSE;
2348
desc->AntialiasedLineEnable = FALSE;
2349
desc->ForcedSampleCount = 0;
2350
desc->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
2355
static bool D3D12_INTERNAL_ConvertBlendState(SDL_GPUGraphicsPipelineCreateInfo *pipelineInfo, D3D12_BLEND_DESC *blendDesc)
2361
SDL_zerop(blendDesc);
2362
blendDesc->AlphaToCoverageEnable = FALSE;
2363
blendDesc->IndependentBlendEnable = FALSE;
2365
for (UINT i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) {
2366
D3D12_RENDER_TARGET_BLEND_DESC rtBlendDesc;
2367
rtBlendDesc.BlendEnable = FALSE;
2368
rtBlendDesc.LogicOpEnable = FALSE;
2369
rtBlendDesc.SrcBlend = D3D12_BLEND_ONE;
2370
rtBlendDesc.DestBlend = D3D12_BLEND_ZERO;
2371
rtBlendDesc.BlendOp = D3D12_BLEND_OP_ADD;
2372
rtBlendDesc.SrcBlendAlpha = D3D12_BLEND_ONE;
2373
rtBlendDesc.DestBlendAlpha = D3D12_BLEND_ZERO;
2374
rtBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
2375
rtBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
2376
rtBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
2379
if (i < pipelineInfo->attachmentInfo.colorAttachmentCount) {
2381
SDL_GPUColorAttachmentBlendState sdlBlendState = pipelineInfo->attachmentInfo.colorAttachmentDescriptions[i].blendState;
2383
rtBlendDesc.BlendEnable = sdlBlendState.blendEnable;
2384
rtBlendDesc.SrcBlend = SDLToD3D12_BlendFactor[sdlBlendState.srcColorBlendFactor];
2385
rtBlendDesc.DestBlend = SDLToD3D12_BlendFactor[sdlBlendState.dstColorBlendFactor];
2386
rtBlendDesc.BlendOp = SDLToD3D12_BlendOp[sdlBlendState.colorBlendOp];
2387
rtBlendDesc.SrcBlendAlpha = SDLToD3D12_BlendFactorAlpha[sdlBlendState.srcAlphaBlendFactor];
2388
rtBlendDesc.DestBlendAlpha = SDLToD3D12_BlendFactorAlpha[sdlBlendState.dstAlphaBlendFactor];
2389
rtBlendDesc.BlendOpAlpha = SDLToD3D12_BlendOp[sdlBlendState.alphaBlendOp];
2390
rtBlendDesc.RenderTargetWriteMask = sdlBlendState.colorWriteMask;
2393
blendDesc->IndependentBlendEnable = TRUE;
2397
blendDesc->RenderTarget[i] = rtBlendDesc;
2403
static bool D3D12_INTERNAL_ConvertDepthStencilState(SDL_GPUDepthStencilState depthStencilState, D3D12_DEPTH_STENCIL_DESC *desc)
2409
desc->DepthEnable = depthStencilState.depthTestEnable == true ? TRUE : FALSE;
2410
desc->DepthWriteMask = depthStencilState.depthWriteEnable == true ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
2411
desc->DepthFunc = SDLToD3D12_CompareOp[depthStencilState.compareOp];
2412
desc->StencilEnable = depthStencilState.stencilTestEnable == true ? TRUE : FALSE;
2413
desc->StencilReadMask = depthStencilState.compareMask;
2414
desc->StencilWriteMask = depthStencilState.writeMask;
2416
desc->FrontFace.StencilFailOp = SDLToD3D12_StencilOp[depthStencilState.frontStencilState.failOp];
2417
desc->FrontFace.StencilDepthFailOp = SDLToD3D12_StencilOp[depthStencilState.frontStencilState.depthFailOp];
2418
desc->FrontFace.StencilPassOp = SDLToD3D12_StencilOp[depthStencilState.frontStencilState.passOp];
2419
desc->FrontFace.StencilFunc = SDLToD3D12_CompareOp[depthStencilState.frontStencilState.compareOp];
2421
desc->BackFace.StencilFailOp = SDLToD3D12_StencilOp[depthStencilState.backStencilState.failOp];
2422
desc->BackFace.StencilDepthFailOp = SDLToD3D12_StencilOp[depthStencilState.backStencilState.depthFailOp];
2423
desc->BackFace.StencilPassOp = SDLToD3D12_StencilOp[depthStencilState.backStencilState.passOp];
2424
desc->BackFace.StencilFunc = SDLToD3D12_CompareOp[depthStencilState.backStencilState.compareOp];
2429
static bool D3D12_INTERNAL_ConvertVertexInputState(SDL_GPUVertexInputState vertexInputState, D3D12_INPUT_ELEMENT_DESC *desc, const char *semantic)
2431
if (desc == NULL || vertexInputState.vertexAttributeCount == 0) {
2435
for (Uint32 i = 0; i < vertexInputState.vertexAttributeCount; i += 1) {
2436
SDL_GPUVertexAttribute attribute = vertexInputState.vertexAttributes[i];
2438
desc[i].SemanticName = semantic;
2439
desc[i].SemanticIndex = attribute.location;
2440
desc[i].Format = SDLToD3D12_VertexFormat[attribute.format];
2441
desc[i].InputSlot = attribute.binding;
2442
desc[i].AlignedByteOffset = attribute.offset;
2443
desc[i].InputSlotClass = SDLToD3D12_InputRate[vertexInputState.vertexBindings[attribute.binding].inputRate];
2444
desc[i].InstanceDataStepRate = (vertexInputState.vertexBindings[attribute.binding].inputRate == SDL_GPU_VERTEXINPUTRATE_INSTANCE) ? vertexInputState.vertexBindings[attribute.binding].instanceStepRate : 0;
2450
static void D3D12_INTERNAL_AssignCpuDescriptorHandle(
2451
D3D12Renderer *renderer,
2452
D3D12_DESCRIPTOR_HEAP_TYPE heapType,
2453
D3D12CPUDescriptor *cpuDescriptor)
2455
D3D12DescriptorHeap *heap = renderer->stagingDescriptorHeaps[heapType];
2456
Uint32 descriptorIndex;
2458
cpuDescriptor->heap = heap;
2460
SDL_LockMutex(renderer->stagingDescriptorHeapLock);
2462
if (heap->inactiveDescriptorCount > 0) {
2463
descriptorIndex = heap->inactiveDescriptorIndices[heap->inactiveDescriptorCount - 1];
2464
heap->inactiveDescriptorCount -= 1;
2465
} else if (heap->currentDescriptorIndex < heap->maxDescriptors) {
2466
descriptorIndex = heap->currentDescriptorIndex;
2467
heap->currentDescriptorIndex += 1;
2469
cpuDescriptor->cpuHandleIndex = SDL_MAX_UINT32;
2470
cpuDescriptor->cpuHandle.ptr = 0;
2471
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Out of CPU descriptor handles, many bad things are going to happen!");
2472
SDL_UnlockMutex(renderer->stagingDescriptorHeapLock);
2476
SDL_UnlockMutex(renderer->stagingDescriptorHeapLock);
2478
cpuDescriptor->cpuHandleIndex = descriptorIndex;
2479
cpuDescriptor->cpuHandle.ptr = heap->descriptorHeapCPUStart.ptr + (descriptorIndex * heap->descriptorSize);
2482
static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
2483
SDL_GPURenderer *driverData,
2484
SDL_GPUGraphicsPipelineCreateInfo *pipelineCreateInfo)
2486
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2487
D3D12Shader *vertShader = (D3D12Shader *)pipelineCreateInfo->vertexShader;
2488
D3D12Shader *fragShader = (D3D12Shader *)pipelineCreateInfo->fragmentShader;
2490
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
2492
psoDesc.VS.pShaderBytecode = vertShader->bytecode;
2493
psoDesc.VS.BytecodeLength = vertShader->bytecodeSize;
2494
psoDesc.PS.pShaderBytecode = fragShader->bytecode;
2495
psoDesc.PS.BytecodeLength = fragShader->bytecodeSize;
2497
D3D12_INPUT_ELEMENT_DESC inputElementDescs[D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
2498
if (pipelineCreateInfo->vertexInputState.vertexAttributeCount > 0) {
2499
psoDesc.InputLayout.pInputElementDescs = inputElementDescs;
2500
psoDesc.InputLayout.NumElements = pipelineCreateInfo->vertexInputState.vertexAttributeCount;
2501
D3D12_INTERNAL_ConvertVertexInputState(pipelineCreateInfo->vertexInputState, inputElementDescs, renderer->semantic);
2504
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
2506
if (!D3D12_INTERNAL_ConvertRasterizerState(pipelineCreateInfo->rasterizerState, &psoDesc.RasterizerState)) {
2509
if (!D3D12_INTERNAL_ConvertBlendState(pipelineCreateInfo, &psoDesc.BlendState)) {
2512
if (!D3D12_INTERNAL_ConvertDepthStencilState(pipelineCreateInfo->depthStencilState, &psoDesc.DepthStencilState)) {
2516
D3D12GraphicsPipeline *pipeline = (D3D12GraphicsPipeline *)SDL_calloc(1, sizeof(D3D12GraphicsPipeline));
2521
psoDesc.SampleMask = UINT_MAX;
2522
psoDesc.SampleDesc.Count = SDLToD3D12_SampleCount[pipelineCreateInfo->multisampleState.sampleCount];
2523
psoDesc.SampleDesc.Quality = 0;
2525
psoDesc.DSVFormat = SDLToD3D12_TextureFormat[pipelineCreateInfo->attachmentInfo.depthStencilFormat];
2526
psoDesc.NumRenderTargets = pipelineCreateInfo->attachmentInfo.colorAttachmentCount;
2527
for (uint32_t i = 0; i < pipelineCreateInfo->attachmentInfo.colorAttachmentCount; i += 1) {
2528
psoDesc.RTVFormats[i] = SDLToD3D12_TextureFormat[pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions[i].format];
2532
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
2533
psoDesc.CachedPSO.CachedBlobSizeInBytes = 0;
2534
psoDesc.CachedPSO.pCachedBlob = NULL;
2536
psoDesc.NodeMask = 0;
2538
D3D12GraphicsRootSignature *rootSignature = D3D12_INTERNAL_CreateGraphicsRootSignature(
2543
if (rootSignature == NULL) {
2544
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create root signature!");
2545
D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
2548
pipeline->rootSignature = rootSignature;
2550
psoDesc.pRootSignature = rootSignature->handle;
2551
ID3D12PipelineState *pipelineState;
2553
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(
2556
D3D_GUID(D3D_IID_ID3D12PipelineState),
2557
(void **)&pipelineState);
2559
D3D12_INTERNAL_LogError(renderer->device, "Could not create graphics pipeline state", res);
2560
D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
2564
pipeline->pipelineState = pipelineState;
2566
for (Uint32 i = 0; i < pipelineCreateInfo->vertexInputState.vertexBindingCount; i += 1) {
2567
pipeline->vertexStrides[i] = pipelineCreateInfo->vertexInputState.vertexBindings[i].stride;
2570
pipeline->primitiveType = pipelineCreateInfo->primitiveType;
2571
pipeline->blendConstants[0] = pipelineCreateInfo->blendConstants[0];
2572
pipeline->blendConstants[1] = pipelineCreateInfo->blendConstants[1];
2573
pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2];
2574
pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3];
2575
pipeline->stencilRef = pipelineCreateInfo->depthStencilState.reference;
2577
pipeline->vertexSamplerCount = vertShader->samplerCount;
2578
pipeline->vertexStorageTextureCount = vertShader->storageTextureCount;
2579
pipeline->vertexStorageBufferCount = vertShader->storageBufferCount;
2580
pipeline->vertexUniformBufferCount = vertShader->uniformBufferCount;
2582
pipeline->fragmentSamplerCount = fragShader->samplerCount;
2583
pipeline->fragmentStorageTextureCount = fragShader->storageTextureCount;
2584
pipeline->fragmentStorageBufferCount = fragShader->storageBufferCount;
2585
pipeline->fragmentUniformBufferCount = fragShader->uniformBufferCount;
2587
SDL_AtomicSet(&pipeline->referenceCount, 0);
2588
return (SDL_GPUGraphicsPipeline *)pipeline;
2591
static SDL_GPUSampler *D3D12_CreateSampler(
2592
SDL_GPURenderer *driverData,
2593
SDL_GPUSamplerCreateInfo *samplerCreateInfo)
2595
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2596
D3D12Sampler *sampler = (D3D12Sampler *)SDL_calloc(1, sizeof(D3D12Sampler));
2600
D3D12_SAMPLER_DESC samplerDesc;
2602
samplerDesc.Filter = SDLToD3D12_Filter(
2603
samplerCreateInfo->minFilter,
2604
samplerCreateInfo->magFilter,
2605
samplerCreateInfo->mipmapMode,
2606
samplerCreateInfo->compareEnable,
2607
samplerCreateInfo->anisotropyEnable);
2608
samplerDesc.AddressU = SDLToD3D12_SamplerAddressMode[samplerCreateInfo->addressModeU];
2609
samplerDesc.AddressV = SDLToD3D12_SamplerAddressMode[samplerCreateInfo->addressModeV];
2610
samplerDesc.AddressW = SDLToD3D12_SamplerAddressMode[samplerCreateInfo->addressModeW];
2611
samplerDesc.MaxAnisotropy = (Uint32)samplerCreateInfo->maxAnisotropy;
2612
samplerDesc.ComparisonFunc = SDLToD3D12_CompareOp[samplerCreateInfo->compareOp];
2613
samplerDesc.MinLOD = samplerCreateInfo->minLod;
2614
samplerDesc.MaxLOD = samplerCreateInfo->maxLod;
2615
samplerDesc.MipLODBias = samplerCreateInfo->mipLodBias;
2616
samplerDesc.BorderColor[0] = 0;
2617
samplerDesc.BorderColor[1] = 0;
2618
samplerDesc.BorderColor[2] = 0;
2619
samplerDesc.BorderColor[3] = 0;
2621
D3D12_INTERNAL_AssignCpuDescriptorHandle(
2623
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
2626
ID3D12Device_CreateSampler(
2629
sampler->handle.cpuHandle);
2631
sampler->createInfo = *samplerCreateInfo;
2632
SDL_AtomicSet(&sampler->referenceCount, 0);
2633
return (SDL_GPUSampler *)sampler;
2636
static SDL_GPUShader *D3D12_CreateShader(
2637
SDL_GPURenderer *driverData,
2638
SDL_GPUShaderCreateInfo *shaderCreateInfo)
2640
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2642
size_t bytecodeSize;
2643
D3D12Shader *shader;
2645
if (!D3D12_INTERNAL_CreateShaderBytecode(
2647
shaderCreateInfo->stage,
2648
shaderCreateInfo->format,
2649
shaderCreateInfo->code,
2650
shaderCreateInfo->codeSize,
2651
shaderCreateInfo->entryPointName,
2656
shader = (D3D12Shader *)SDL_calloc(1, sizeof(D3D12Shader));
2661
shader->samplerCount = shaderCreateInfo->samplerCount;
2662
shader->storageBufferCount = shaderCreateInfo->storageBufferCount;
2663
shader->storageTextureCount = shaderCreateInfo->storageTextureCount;
2664
shader->uniformBufferCount = shaderCreateInfo->uniformBufferCount;
2666
shader->bytecode = bytecode;
2667
shader->bytecodeSize = bytecodeSize;
2669
return (SDL_GPUShader *)shader;
2672
static D3D12Texture *D3D12_INTERNAL_CreateTexture(
2673
D3D12Renderer *renderer,
2674
SDL_GPUTextureCreateInfo *textureCreateInfo,
2675
bool isSwapchainTexture)
2677
D3D12Texture *texture;
2678
ID3D12Resource *handle;
2679
D3D12_HEAP_PROPERTIES heapProperties;
2680
D3D12_HEAP_FLAGS heapFlags = (D3D12_HEAP_FLAGS)0;
2681
D3D12_RESOURCE_DESC desc;
2682
D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0;
2683
D3D12_RESOURCE_STATES initialState = (D3D12_RESOURCE_STATES)0;
2684
D3D12_CLEAR_VALUE clearValue;
2685
bool useClearValue = false;
2688
texture = (D3D12Texture *)SDL_calloc(1, sizeof(D3D12Texture));
2693
Uint32 layerCount = textureCreateInfo->type == SDL_GPU_TEXTURETYPE_3D ? 1 : textureCreateInfo->layerCountOrDepth;
2694
Uint32 depth = textureCreateInfo->type == SDL_GPU_TEXTURETYPE_3D ? textureCreateInfo->layerCountOrDepth : 1;
2696
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
2697
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
2698
useClearValue = true;
2699
clearValue.Color[0] = SDL_GetFloatProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_R_FLOAT, 0);
2700
clearValue.Color[1] = SDL_GetFloatProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_G_FLOAT, 0);
2701
clearValue.Color[2] = SDL_GetFloatProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_B_FLOAT, 0);
2702
clearValue.Color[3] = SDL_GetFloatProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_A_FLOAT, 0);
2705
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
2706
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
2707
useClearValue = true;
2708
clearValue.DepthStencil.Depth = SDL_GetFloatProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_DEPTH_FLOAT, 0);
2709
clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(textureCreateInfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_STENCIL_UINT8, 0);
2712
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) {
2713
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
2716
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
2717
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
2718
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
2719
heapProperties.CreationNodeMask = 0;
2720
heapProperties.VisibleNodeMask = 0;
2722
heapFlags = isSwapchainTexture ? D3D12_HEAP_FLAG_ALLOW_DISPLAY : D3D12_HEAP_FLAG_NONE;
2724
if (textureCreateInfo->type != SDL_GPU_TEXTURETYPE_3D) {
2725
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
2726
desc.Alignment = isSwapchainTexture ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2727
desc.Width = textureCreateInfo->width;
2728
desc.Height = textureCreateInfo->height;
2729
desc.DepthOrArraySize = textureCreateInfo->layerCountOrDepth;
2730
desc.MipLevels = textureCreateInfo->levelCount;
2731
desc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2732
desc.SampleDesc.Count = 1;
2733
desc.SampleDesc.Quality = 0;
2734
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
2735
desc.Flags = resourceFlags;
2737
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
2738
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2739
desc.Width = textureCreateInfo->width;
2740
desc.Height = textureCreateInfo->height;
2741
desc.DepthOrArraySize = textureCreateInfo->layerCountOrDepth;
2742
desc.MipLevels = textureCreateInfo->levelCount;
2743
desc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2744
desc.SampleDesc.Count = 1;
2745
desc.SampleDesc.Quality = 0;
2746
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
2747
desc.Flags = resourceFlags;
2750
initialState = isSwapchainTexture ? D3D12_RESOURCE_STATE_PRESENT : D3D12_INTERNAL_DefaultTextureResourceState(textureCreateInfo->usageFlags);
2751
clearValue.Format = desc.Format;
2753
res = ID3D12Device_CreateCommittedResource(
2759
useClearValue ? &clearValue : NULL,
2760
D3D_GUID(D3D_IID_ID3D12Resource),
2763
D3D12_INTERNAL_LogError(renderer->device, "Failed to create texture!", res);
2764
D3D12_INTERNAL_DestroyTexture(renderer, texture);
2768
texture->resource = handle;
2771
if ((textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_SAMPLER) ||
2772
(textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) ||
2773
(textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) {
2774
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
2776
D3D12_INTERNAL_AssignCpuDescriptorHandle(
2778
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
2779
&texture->srvHandle);
2781
srvDesc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2782
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
2784
if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
2785
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
2786
srvDesc.TextureCube.MipLevels = textureCreateInfo->levelCount;
2787
srvDesc.TextureCube.MostDetailedMip = 0;
2788
srvDesc.TextureCube.ResourceMinLODClamp = 0;
2789
} else if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
2790
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
2791
srvDesc.Texture2DArray.MipLevels = textureCreateInfo->levelCount;
2792
srvDesc.Texture2DArray.MostDetailedMip = 0;
2793
srvDesc.Texture2DArray.FirstArraySlice = 0;
2794
srvDesc.Texture2DArray.ArraySize = layerCount;
2795
srvDesc.Texture2DArray.ResourceMinLODClamp = 0;
2796
srvDesc.Texture2DArray.PlaneSlice = 0;
2797
} else if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_3D) {
2798
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
2799
srvDesc.Texture3D.MipLevels = textureCreateInfo->levelCount;
2800
srvDesc.Texture3D.MostDetailedMip = 0;
2801
srvDesc.Texture3D.ResourceMinLODClamp = 0;
2803
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
2804
srvDesc.Texture2D.MipLevels = textureCreateInfo->levelCount;
2805
srvDesc.Texture2D.MostDetailedMip = 0;
2806
srvDesc.Texture2D.PlaneSlice = 0;
2807
srvDesc.Texture2D.ResourceMinLODClamp = 0;
2810
ID3D12Device_CreateShaderResourceView(
2814
texture->srvHandle.cpuHandle);
2817
SDL_AtomicSet(&texture->referenceCount, 0);
2819
texture->subresourceCount = textureCreateInfo->levelCount * layerCount;
2820
texture->subresources = (D3D12TextureSubresource *)SDL_calloc(
2821
texture->subresourceCount, sizeof(D3D12TextureSubresource));
2822
if (!texture->subresources) {
2823
D3D12_INTERNAL_DestroyTexture(renderer, texture);
2826
for (Uint32 layerIndex = 0; layerIndex < layerCount; layerIndex += 1) {
2827
for (Uint32 levelIndex = 0; levelIndex < textureCreateInfo->levelCount; levelIndex += 1) {
2828
Uint32 subresourceIndex = D3D12_INTERNAL_CalcSubresource(
2831
textureCreateInfo->levelCount);
2833
texture->subresources[subresourceIndex].parent = texture;
2834
texture->subresources[subresourceIndex].layer = layerIndex;
2835
texture->subresources[subresourceIndex].level = levelIndex;
2836
texture->subresources[subresourceIndex].depth = depth;
2837
texture->subresources[subresourceIndex].index = subresourceIndex;
2839
texture->subresources[subresourceIndex].rtvHandles = NULL;
2840
texture->subresources[subresourceIndex].uavHandle.heap = NULL;
2841
texture->subresources[subresourceIndex].dsvHandle.heap = NULL;
2844
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
2845
texture->subresources[subresourceIndex].rtvHandles = (D3D12CPUDescriptor *)SDL_calloc(depth, sizeof(D3D12CPUDescriptor));
2847
for (Uint32 depthIndex = 0; depthIndex < depth; depthIndex += 1) {
2848
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
2850
D3D12_INTERNAL_AssignCpuDescriptorHandle(
2852
D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
2853
&texture->subresources[subresourceIndex].rtvHandles[depthIndex]);
2855
rtvDesc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2857
if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || textureCreateInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
2858
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
2859
rtvDesc.Texture2DArray.MipSlice = levelIndex;
2860
rtvDesc.Texture2DArray.FirstArraySlice = layerIndex;
2861
rtvDesc.Texture2DArray.ArraySize = 1;
2862
rtvDesc.Texture2DArray.PlaneSlice = 0;
2863
} else if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_3D) {
2864
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
2865
rtvDesc.Texture3D.MipSlice = levelIndex;
2866
rtvDesc.Texture3D.FirstWSlice = depthIndex;
2867
rtvDesc.Texture3D.WSize = 1;
2869
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
2870
rtvDesc.Texture2D.MipSlice = levelIndex;
2871
rtvDesc.Texture2D.PlaneSlice = 0;
2874
ID3D12Device_CreateRenderTargetView(
2878
texture->subresources[subresourceIndex].rtvHandles[depthIndex].cpuHandle);
2883
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
2884
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
2886
D3D12_INTERNAL_AssignCpuDescriptorHandle(
2888
D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
2889
&texture->subresources[subresourceIndex].dsvHandle);
2891
dsvDesc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2892
dsvDesc.Flags = (D3D12_DSV_FLAGS)0;
2893
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
2894
dsvDesc.Texture2D.MipSlice = levelIndex;
2896
ID3D12Device_CreateDepthStencilView(
2900
texture->subresources[subresourceIndex].dsvHandle.cpuHandle);
2904
if (textureCreateInfo->usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) {
2905
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
2907
D3D12_INTERNAL_AssignCpuDescriptorHandle(
2909
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
2910
&texture->subresources[subresourceIndex].uavHandle);
2912
uavDesc.Format = SDLToD3D12_TextureFormat[textureCreateInfo->format];
2914
if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || textureCreateInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
2915
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
2916
uavDesc.Texture2DArray.MipSlice = levelIndex;
2917
uavDesc.Texture2DArray.FirstArraySlice = layerIndex;
2918
uavDesc.Texture2DArray.ArraySize = 1;
2919
} else if (textureCreateInfo->type == SDL_GPU_TEXTURETYPE_3D) {
2920
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
2921
uavDesc.Texture3D.MipSlice = levelIndex;
2922
uavDesc.Texture3D.FirstWSlice = 0;
2923
uavDesc.Texture3D.WSize = depth;
2925
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
2926
uavDesc.Texture2D.MipSlice = levelIndex;
2927
uavDesc.Texture2D.PlaneSlice = 0;
2930
ID3D12Device_CreateUnorderedAccessView(
2935
texture->subresources[subresourceIndex].uavHandle.cpuHandle);
2943
static SDL_GPUTexture *D3D12_CreateTexture(
2944
SDL_GPURenderer *driverData,
2945
SDL_GPUTextureCreateInfo *textureCreateInfo)
2947
D3D12TextureContainer *container = (D3D12TextureContainer *)SDL_calloc(1, sizeof(D3D12TextureContainer));
2952
container->header.info = *textureCreateInfo;
2953
container->textureCapacity = 1;
2954
container->textureCount = 1;
2955
container->textures = (D3D12Texture **)SDL_calloc(
2956
container->textureCapacity, sizeof(D3D12Texture *));
2958
if (!container->textures) {
2959
SDL_free(container);
2963
container->debugName = NULL;
2964
container->canBeCycled = true;
2966
D3D12Texture *texture = D3D12_INTERNAL_CreateTexture(
2967
(D3D12Renderer *)driverData,
2972
SDL_free(container->textures);
2973
SDL_free(container);
2977
container->textures[0] = texture;
2978
container->activeTexture = texture;
2980
texture->container = container;
2981
texture->containerIndex = 0;
2983
return (SDL_GPUTexture *)container;
2986
static D3D12Buffer *D3D12_INTERNAL_CreateBuffer(
2987
D3D12Renderer *renderer,
2988
SDL_GPUBufferUsageFlags usageFlags,
2990
D3D12BufferType type)
2992
D3D12Buffer *buffer;
2993
ID3D12Resource *handle;
2994
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
2995
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
2996
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
2997
D3D12_HEAP_PROPERTIES heapProperties;
2998
D3D12_RESOURCE_DESC desc;
2999
D3D12_HEAP_FLAGS heapFlags = (D3D12_HEAP_FLAGS)0;
3000
D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0;
3001
D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON;
3004
buffer = (D3D12Buffer *)SDL_calloc(1, sizeof(D3D12Buffer));
3010
if (usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
3011
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
3013
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
3014
if (usageFlags & SDL_GPU_BUFFERUSAGE_INDIRECT) {
3015
resourceFlags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER;
3019
heapProperties.CreationNodeMask = 0;
3020
heapProperties.VisibleNodeMask = 0;
3022
if (type == D3D12_BUFFER_TYPE_GPU) {
3023
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
3024
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3025
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3026
heapFlags = D3D12_HEAP_FLAG_NONE;
3027
} else if (type == D3D12_BUFFER_TYPE_UPLOAD) {
3028
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
3029
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3030
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3031
heapFlags = D3D12_HEAP_FLAG_NONE;
3032
initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
3033
} else if (type == D3D12_BUFFER_TYPE_DOWNLOAD) {
3034
heapProperties.Type = D3D12_HEAP_TYPE_READBACK;
3035
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3036
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3037
heapFlags = D3D12_HEAP_FLAG_NONE;
3038
initialState = D3D12_RESOURCE_STATE_COPY_DEST;
3039
} else if (type == D3D12_BUFFER_TYPE_UNIFORM) {
3041
if (renderer->GPUUploadHeapSupported) {
3042
heapProperties.Type = D3D12_HEAP_TYPE_GPU_UPLOAD;
3043
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3044
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3046
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
3047
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3048
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3049
initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
3051
heapFlags = D3D12_HEAP_FLAG_NONE;
3053
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized buffer type!");
3057
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
3058
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
3059
desc.Width = sizeInBytes;
3061
desc.DepthOrArraySize = 1;
3063
desc.Format = DXGI_FORMAT_UNKNOWN;
3064
desc.SampleDesc.Count = 1;
3065
desc.SampleDesc.Quality = 0;
3066
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
3067
desc.Flags = resourceFlags;
3069
res = ID3D12Device_CreateCommittedResource(
3076
D3D_GUID(D3D_IID_ID3D12Resource),
3079
D3D12_INTERNAL_LogError(renderer->device, "Could not create buffer!", res);
3080
D3D12_INTERNAL_DestroyBuffer(renderer, buffer);
3084
buffer->handle = handle;
3085
SDL_AtomicSet(&buffer->referenceCount, 0);
3087
buffer->uavDescriptor.heap = NULL;
3088
buffer->srvDescriptor.heap = NULL;
3089
buffer->cbvDescriptor.heap = NULL;
3091
if (usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
3092
D3D12_INTERNAL_AssignCpuDescriptorHandle(
3094
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3095
&buffer->uavDescriptor);
3097
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
3098
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
3099
uavDesc.Buffer.FirstElement = 0;
3100
uavDesc.Buffer.NumElements = sizeInBytes / sizeof(Uint32);
3101
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
3102
uavDesc.Buffer.CounterOffsetInBytes = 0;
3103
uavDesc.Buffer.StructureByteStride = 0;
3106
ID3D12Device_CreateUnorderedAccessView(
3111
buffer->uavDescriptor.cpuHandle);
3115
(usageFlags & SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ) ||
3116
(usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ)) {
3117
D3D12_INTERNAL_AssignCpuDescriptorHandle(
3119
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3120
&buffer->srvDescriptor);
3122
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
3123
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
3124
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
3125
srvDesc.Buffer.FirstElement = 0;
3126
srvDesc.Buffer.NumElements = sizeInBytes / sizeof(Uint32);
3127
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
3128
srvDesc.Buffer.StructureByteStride = 0;
3131
ID3D12Device_CreateShaderResourceView(
3135
buffer->srvDescriptor.cpuHandle);
3139
if (type == D3D12_BUFFER_TYPE_UNIFORM) {
3140
D3D12_INTERNAL_AssignCpuDescriptorHandle(
3142
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3143
&buffer->cbvDescriptor);
3145
cbvDesc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(handle);
3146
cbvDesc.SizeInBytes = sizeInBytes;
3149
ID3D12Device_CreateConstantBufferView(
3152
buffer->cbvDescriptor.cpuHandle);
3155
buffer->virtualAddress = 0;
3156
if (type == D3D12_BUFFER_TYPE_GPU || type == D3D12_BUFFER_TYPE_UNIFORM) {
3157
buffer->virtualAddress = ID3D12Resource_GetGPUVirtualAddress(buffer->handle);
3160
buffer->mapPointer = NULL;
3162
if (type == D3D12_BUFFER_TYPE_UPLOAD) {
3163
res = ID3D12Resource_Map(
3167
(void **)&buffer->mapPointer);
3169
D3D12_INTERNAL_LogError(renderer->device, "Failed to map upload buffer!", res);
3170
D3D12_INTERNAL_DestroyBuffer(renderer, buffer);
3175
buffer->container = NULL;
3176
buffer->containerIndex = 0;
3178
buffer->transitioned = initialState != D3D12_RESOURCE_STATE_COMMON;
3179
SDL_AtomicSet(&buffer->referenceCount, 0);
3183
static D3D12BufferContainer *D3D12_INTERNAL_CreateBufferContainer(
3184
D3D12Renderer *renderer,
3185
SDL_GPUBufferUsageFlags usageFlags,
3187
D3D12BufferType type)
3189
D3D12BufferContainer *container;
3190
D3D12Buffer *buffer;
3192
container = (D3D12BufferContainer *)SDL_calloc(1, sizeof(D3D12BufferContainer));
3197
container->usageFlags = usageFlags;
3198
container->size = sizeInBytes;
3199
container->type = type;
3201
container->bufferCapacity = 1;
3202
container->bufferCount = 1;
3203
container->buffers = (D3D12Buffer **)SDL_calloc(
3204
container->bufferCapacity, sizeof(D3D12Buffer *));
3205
if (!container->buffers) {
3206
SDL_free(container);
3209
container->debugName = NULL;
3211
buffer = D3D12_INTERNAL_CreateBuffer(
3217
if (buffer == NULL) {
3218
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create buffer!");
3219
SDL_free(container->buffers);
3220
SDL_free(container);
3224
container->activeBuffer = buffer;
3225
container->buffers[0] = buffer;
3226
buffer->container = container;
3227
buffer->containerIndex = 0;
3232
static SDL_GPUBuffer *D3D12_CreateBuffer(
3233
SDL_GPURenderer *driverData,
3234
SDL_GPUBufferUsageFlags usageFlags,
3237
return (SDL_GPUBuffer *)D3D12_INTERNAL_CreateBufferContainer(
3238
(D3D12Renderer *)driverData,
3241
D3D12_BUFFER_TYPE_GPU);
3244
static SDL_GPUTransferBuffer *D3D12_CreateTransferBuffer(
3245
SDL_GPURenderer *driverData,
3246
SDL_GPUTransferBufferUsage usage,
3249
return (SDL_GPUTransferBuffer *)D3D12_INTERNAL_CreateBufferContainer(
3250
(D3D12Renderer *)driverData,
3253
usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD ? D3D12_BUFFER_TYPE_UPLOAD : D3D12_BUFFER_TYPE_DOWNLOAD);
3258
static void D3D12_SetBufferName(
3259
SDL_GPURenderer *driverData,
3260
SDL_GPUBuffer *buffer,
3263
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3264
D3D12BufferContainer *container = (D3D12BufferContainer *)buffer;
3265
size_t textLength = SDL_strlen(text) + 1;
3267
if (renderer->debugMode) {
3268
container->debugName = (char *)SDL_realloc(
3269
container->debugName,
3273
container->debugName,
3277
for (Uint32 i = 0; i < container->bufferCount; i += 1) {
3278
D3D12_INTERNAL_SetResourceName(
3280
container->buffers[i]->handle,
3286
static void D3D12_SetTextureName(
3287
SDL_GPURenderer *driverData,
3288
SDL_GPUTexture *texture,
3291
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3292
D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
3293
size_t textLength = SDL_strlen(text) + 1;
3295
if (renderer->debugMode) {
3296
container->debugName = (char *)SDL_realloc(
3297
container->debugName,
3301
container->debugName,
3305
for (Uint32 i = 0; i < container->textureCount; i += 1) {
3306
D3D12_INTERNAL_SetResourceName(
3308
container->textures[i]->resource,
3318
static bool D3D12_INTERNAL_StrToWStr(
3319
D3D12Renderer *renderer,
3325
size_t inlen, result;
3326
size_t outlen = wstr_size;
3328
if (renderer->iconv == NULL) {
3329
renderer->iconv = SDL_iconv_open("WCHAR_T", "UTF-8");
3330
SDL_assert(renderer->iconv);
3334
inlen = SDL_strlen(str) + 1;
3342
*outSize = (Uint32)outlen;
3346
case SDL_ICONV_ERROR:
3347
case SDL_ICONV_E2BIG:
3348
case SDL_ICONV_EILSEQ:
3349
case SDL_ICONV_EINVAL:
3350
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Failed to convert string to wchar_t!");
3359
static void D3D12_InsertDebugLabel(
3360
SDL_GPUCommandBuffer *commandBuffer,
3363
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3367
if (!D3D12_INTERNAL_StrToWStr(
3368
d3d12CommandBuffer->renderer,
3376
ID3D12GraphicsCommandList_SetMarker(
3377
d3d12CommandBuffer->graphicsCommandList,
3383
static void D3D12_PushDebugGroup(
3384
SDL_GPUCommandBuffer *commandBuffer,
3387
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3391
if (!D3D12_INTERNAL_StrToWStr(
3392
d3d12CommandBuffer->renderer,
3400
ID3D12GraphicsCommandList_BeginEvent(
3401
d3d12CommandBuffer->graphicsCommandList,
3407
static void D3D12_PopDebugGroup(
3408
SDL_GPUCommandBuffer *commandBuffer)
3410
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3411
ID3D12GraphicsCommandList_EndEvent(d3d12CommandBuffer->graphicsCommandList);
3416
static void D3D12_ReleaseTexture(
3417
SDL_GPURenderer *driverData,
3418
SDL_GPUTexture *texture)
3420
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3421
D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
3423
D3D12_INTERNAL_ReleaseTextureContainer(
3428
static void D3D12_ReleaseSampler(
3429
SDL_GPURenderer *driverData,
3430
SDL_GPUSampler *sampler)
3432
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3433
D3D12Sampler *d3d12Sampler = (D3D12Sampler *)sampler;
3435
SDL_LockMutex(renderer->disposeLock);
3437
EXPAND_ARRAY_IF_NEEDED(
3438
renderer->samplersToDestroy,
3440
renderer->samplersToDestroyCount + 1,
3441
renderer->samplersToDestroyCapacity,
3442
renderer->samplersToDestroyCapacity * 2)
3444
renderer->samplersToDestroy[renderer->samplersToDestroyCount] = d3d12Sampler;
3445
renderer->samplersToDestroyCount += 1;
3447
SDL_UnlockMutex(renderer->disposeLock);
3450
static void D3D12_ReleaseBuffer(
3451
SDL_GPURenderer *driverData,
3452
SDL_GPUBuffer *buffer)
3454
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3455
D3D12BufferContainer *bufferContainer = (D3D12BufferContainer *)buffer;
3457
D3D12_INTERNAL_ReleaseBufferContainer(
3462
static void D3D12_ReleaseTransferBuffer(
3463
SDL_GPURenderer *driverData,
3464
SDL_GPUTransferBuffer *transferBuffer)
3466
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3467
D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)transferBuffer;
3469
D3D12_INTERNAL_ReleaseBufferContainer(
3471
transferBufferContainer);
3474
static void D3D12_ReleaseShader(
3475
SDL_GPURenderer *driverData,
3476
SDL_GPUShader *shader)
3479
D3D12Shader *d3d12shader = (D3D12Shader *)shader;
3481
if (d3d12shader->bytecode) {
3482
SDL_free(d3d12shader->bytecode);
3483
d3d12shader->bytecode = NULL;
3485
SDL_free(d3d12shader);
3488
static void D3D12_ReleaseComputePipeline(
3489
SDL_GPURenderer *driverData,
3490
SDL_GPUComputePipeline *computePipeline)
3492
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3493
D3D12ComputePipeline *d3d12ComputePipeline = (D3D12ComputePipeline *)computePipeline;
3495
SDL_LockMutex(renderer->disposeLock);
3497
EXPAND_ARRAY_IF_NEEDED(
3498
renderer->computePipelinesToDestroy,
3499
D3D12ComputePipeline *,
3500
renderer->computePipelinesToDestroyCount + 1,
3501
renderer->computePipelinesToDestroyCapacity,
3502
renderer->computePipelinesToDestroyCapacity * 2)
3504
renderer->computePipelinesToDestroy[renderer->computePipelinesToDestroyCount] = d3d12ComputePipeline;
3505
renderer->computePipelinesToDestroyCount += 1;
3507
SDL_UnlockMutex(renderer->disposeLock);
3510
static void D3D12_ReleaseGraphicsPipeline(
3511
SDL_GPURenderer *driverData,
3512
SDL_GPUGraphicsPipeline *graphicsPipeline)
3514
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3515
D3D12GraphicsPipeline *d3d12GraphicsPipeline = (D3D12GraphicsPipeline *)graphicsPipeline;
3517
SDL_LockMutex(renderer->disposeLock);
3519
EXPAND_ARRAY_IF_NEEDED(
3520
renderer->graphicsPipelinesToDestroy,
3521
D3D12GraphicsPipeline *,
3522
renderer->graphicsPipelinesToDestroyCount + 1,
3523
renderer->graphicsPipelinesToDestroyCapacity,
3524
renderer->graphicsPipelinesToDestroyCapacity * 2)
3526
renderer->graphicsPipelinesToDestroy[renderer->graphicsPipelinesToDestroyCount] = d3d12GraphicsPipeline;
3527
renderer->graphicsPipelinesToDestroyCount += 1;
3529
SDL_UnlockMutex(renderer->disposeLock);
3532
static void D3D12_INTERNAL_ReleaseBlitPipelines(SDL_GPURenderer *driverData)
3534
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3535
D3D12_ReleaseSampler(driverData, renderer->blitLinearSampler);
3536
D3D12_ReleaseSampler(driverData, renderer->blitNearestSampler);
3537
D3D12_ReleaseShader(driverData, renderer->blitVertexShader);
3538
D3D12_ReleaseShader(driverData, renderer->blitFrom2DShader);
3539
D3D12_ReleaseShader(driverData, renderer->blitFrom2DArrayShader);
3540
D3D12_ReleaseShader(driverData, renderer->blitFrom3DShader);
3541
D3D12_ReleaseShader(driverData, renderer->blitFromCubeShader);
3543
for (Uint32 i = 0; i < renderer->blitPipelineCount; i += 1) {
3544
D3D12_ReleaseGraphicsPipeline(driverData, renderer->blitPipelines[i].pipeline);
3546
SDL_free(renderer->blitPipelines);
3551
static void D3D12_SetViewport(
3552
SDL_GPUCommandBuffer *commandBuffer,
3553
SDL_GPUViewport *viewport)
3555
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3556
D3D12_VIEWPORT d3d12Viewport;
3557
d3d12Viewport.TopLeftX = viewport->x;
3558
d3d12Viewport.TopLeftY = viewport->y;
3559
d3d12Viewport.Width = viewport->w;
3560
d3d12Viewport.Height = viewport->h;
3561
d3d12Viewport.MinDepth = viewport->minDepth;
3562
d3d12Viewport.MaxDepth = viewport->maxDepth;
3563
ID3D12GraphicsCommandList_RSSetViewports(d3d12CommandBuffer->graphicsCommandList, 1, &d3d12Viewport);
3566
static void D3D12_SetScissor(
3567
SDL_GPUCommandBuffer *commandBuffer,
3570
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3571
D3D12_RECT scissorRect;
3572
scissorRect.left = scissor->x;
3573
scissorRect.top = scissor->y;
3574
scissorRect.right = scissor->x + scissor->w;
3575
scissorRect.bottom = scissor->y + scissor->h;
3576
ID3D12GraphicsCommandList_RSSetScissorRects(d3d12CommandBuffer->graphicsCommandList, 1, &scissorRect);
3579
static D3D12TextureSubresource *D3D12_INTERNAL_FetchTextureSubresource(
3580
D3D12TextureContainer *container,
3584
Uint32 index = D3D12_INTERNAL_CalcSubresource(
3587
container->header.info.levelCount);
3588
return &container->activeTexture->subresources[index];
3591
static void D3D12_INTERNAL_CycleActiveTexture(
3592
D3D12Renderer *renderer,
3593
D3D12TextureContainer *container)
3595
D3D12Texture *texture;
3598
for (Uint32 i = 0; i < container->textureCount; i += 1) {
3599
texture = container->textures[i];
3601
if (SDL_AtomicGet(&texture->referenceCount) == 0) {
3602
container->activeTexture = texture;
3608
texture = D3D12_INTERNAL_CreateTexture(
3610
&container->header.info,
3614
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to cycle active texture!");
3618
EXPAND_ARRAY_IF_NEEDED(
3619
container->textures,
3621
container->textureCount + 1,
3622
container->textureCapacity,
3623
container->textureCapacity * 2);
3625
container->textures[container->textureCount] = texture;
3626
texture->container = container;
3627
texture->containerIndex = container->textureCount;
3628
container->textureCount += 1;
3630
container->activeTexture = texture;
3632
if (renderer->debugMode && container->debugName != NULL) {
3633
D3D12_INTERNAL_SetResourceName(
3635
container->activeTexture->resource,
3636
container->debugName);
3640
static D3D12TextureSubresource *D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
3641
D3D12CommandBuffer *commandBuffer,
3642
D3D12TextureContainer *container,
3646
D3D12_RESOURCE_STATES destinationUsageMode)
3648
D3D12TextureSubresource *subresource = D3D12_INTERNAL_FetchTextureSubresource(
3654
container->canBeCycled &&
3656
SDL_AtomicGet(&subresource->parent->referenceCount) > 0) {
3657
D3D12_INTERNAL_CycleActiveTexture(
3658
commandBuffer->renderer,
3661
subresource = D3D12_INTERNAL_FetchTextureSubresource(
3667
D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
3669
destinationUsageMode,
3675
static void D3D12_INTERNAL_CycleActiveBuffer(
3676
D3D12Renderer *renderer,
3677
D3D12BufferContainer *container)
3680
for (Uint32 i = 0; i < container->bufferCount; i += 1) {
3681
D3D12Buffer *buffer = container->buffers[i];
3682
if (SDL_AtomicGet(&buffer->referenceCount) == 0) {
3683
container->activeBuffer = buffer;
3689
D3D12Buffer *buffer = D3D12_INTERNAL_CreateBuffer(
3691
container->usageFlags,
3696
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to cycle active buffer!");
3700
EXPAND_ARRAY_IF_NEEDED(
3703
container->bufferCount + 1,
3704
container->bufferCapacity,
3705
container->bufferCapacity * 2);
3707
container->buffers[container->bufferCount] = buffer;
3708
buffer->container = container;
3709
buffer->containerIndex = container->bufferCount;
3710
container->bufferCount += 1;
3712
container->activeBuffer = buffer;
3714
if (renderer->debugMode && container->debugName != NULL) {
3715
D3D12_INTERNAL_SetResourceName(
3717
container->activeBuffer->handle,
3718
container->debugName);
3722
static D3D12Buffer *D3D12_INTERNAL_PrepareBufferForWrite(
3723
D3D12CommandBuffer *commandBuffer,
3724
D3D12BufferContainer *container,
3726
D3D12_RESOURCE_STATES destinationState)
3730
SDL_AtomicGet(&container->activeBuffer->referenceCount) > 0) {
3731
D3D12_INTERNAL_CycleActiveBuffer(
3732
commandBuffer->renderer,
3736
D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
3739
container->activeBuffer);
3741
return container->activeBuffer;
3744
static void D3D12_BeginRenderPass(
3745
SDL_GPUCommandBuffer *commandBuffer,
3746
SDL_GPUColorAttachmentInfo *colorAttachmentInfos,
3747
Uint32 colorAttachmentCount,
3748
SDL_GPUDepthStencilAttachmentInfo *depthStencilAttachmentInfo)
3750
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3753
Uint32 framebufferWidth = SDL_MAX_UINT32;
3754
Uint32 framebufferHeight = SDL_MAX_UINT32;
3756
for (Uint32 i = 0; i < colorAttachmentCount; i += 1) {
3757
D3D12TextureContainer *container = (D3D12TextureContainer *)colorAttachmentInfos[i].texture;
3758
Uint32 h = container->header.info.height >> colorAttachmentInfos[i].mipLevel;
3759
Uint32 w = container->header.info.width >> colorAttachmentInfos[i].mipLevel;
3763
if (w < framebufferWidth) {
3764
framebufferWidth = w;
3767
if (h < framebufferHeight) {
3768
framebufferHeight = h;
3771
if (!(container->header.info.usageFlags & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) {
3772
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Color attachment texture was not designated as a color target!");
3777
if (depthStencilAttachmentInfo != NULL) {
3778
D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilAttachmentInfo->texture;
3780
Uint32 h = container->header.info.height;
3781
Uint32 w = container->header.info.width;
3785
if (w < framebufferWidth) {
3786
framebufferWidth = w;
3789
if (h < framebufferHeight) {
3790
framebufferHeight = h;
3794
if (!(container->header.info.usageFlags & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET)) {
3795
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Depth stencil attachment texture was not designated as a depth target!");
3800
D3D12_CPU_DESCRIPTOR_HANDLE rtvs[MAX_COLOR_TARGET_BINDINGS];
3802
for (Uint32 i = 0; i < colorAttachmentCount; i += 1) {
3803
D3D12TextureContainer *container = (D3D12TextureContainer *)colorAttachmentInfos[i].texture;
3804
D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
3807
container->header.info.type == SDL_GPU_TEXTURETYPE_3D ? 0 : colorAttachmentInfos[i].layerOrDepthPlane,
3808
colorAttachmentInfos[i].mipLevel,
3809
colorAttachmentInfos[i].cycle,
3810
D3D12_RESOURCE_STATE_RENDER_TARGET);
3812
Uint32 rtvIndex = container->header.info.type == SDL_GPU_TEXTURETYPE_3D ? colorAttachmentInfos[i].layerOrDepthPlane : 0;
3813
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
3814
subresource->rtvHandles[rtvIndex].cpuHandle;
3816
if (colorAttachmentInfos[i].loadOp == SDL_GPU_LOADOP_CLEAR) {
3817
float clearColor[4];
3818
clearColor[0] = colorAttachmentInfos[i].clearColor.r;
3819
clearColor[1] = colorAttachmentInfos[i].clearColor.g;
3820
clearColor[2] = colorAttachmentInfos[i].clearColor.b;
3821
clearColor[3] = colorAttachmentInfos[i].clearColor.a;
3823
ID3D12GraphicsCommandList_ClearRenderTargetView(
3824
d3d12CommandBuffer->graphicsCommandList,
3832
d3d12CommandBuffer->colorAttachmentTextureSubresources[i] = subresource;
3834
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, subresource->parent);
3837
d3d12CommandBuffer->colorAttachmentTextureSubresourceCount = colorAttachmentCount;
3839
D3D12_CPU_DESCRIPTOR_HANDLE dsv;
3840
if (depthStencilAttachmentInfo != NULL) {
3841
D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilAttachmentInfo->texture;
3842
D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
3847
depthStencilAttachmentInfo->cycle,
3848
D3D12_RESOURCE_STATE_DEPTH_WRITE);
3851
depthStencilAttachmentInfo->loadOp == SDL_GPU_LOADOP_CLEAR ||
3852
depthStencilAttachmentInfo->stencilLoadOp == SDL_GPU_LOADOP_CLEAR) {
3853
D3D12_CLEAR_FLAGS clearFlags = (D3D12_CLEAR_FLAGS)0;
3854
if (depthStencilAttachmentInfo->loadOp == SDL_GPU_LOADOP_CLEAR) {
3855
clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
3857
if (depthStencilAttachmentInfo->stencilLoadOp == SDL_GPU_LOADOP_CLEAR) {
3858
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
3861
ID3D12GraphicsCommandList_ClearDepthStencilView(
3862
d3d12CommandBuffer->graphicsCommandList,
3863
subresource->dsvHandle.cpuHandle,
3865
depthStencilAttachmentInfo->depthStencilClearValue.depth,
3866
depthStencilAttachmentInfo->depthStencilClearValue.stencil,
3871
dsv = subresource->dsvHandle.cpuHandle;
3872
d3d12CommandBuffer->depthStencilTextureSubresource = subresource;
3873
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, subresource->parent);
3876
ID3D12GraphicsCommandList_OMSetRenderTargets(
3877
d3d12CommandBuffer->graphicsCommandList,
3878
colorAttachmentCount,
3881
(depthStencilAttachmentInfo == NULL) ? NULL : &dsv);
3884
SDL_GPUViewport defaultViewport;
3885
defaultViewport.x = 0;
3886
defaultViewport.y = 0;
3887
defaultViewport.w = (float)framebufferWidth;
3888
defaultViewport.h = (float)framebufferHeight;
3889
defaultViewport.minDepth = 0;
3890
defaultViewport.maxDepth = 1;
3896
SDL_Rect defaultScissor;
3897
defaultScissor.x = 0;
3898
defaultScissor.y = 0;
3899
defaultScissor.w = (Sint32)framebufferWidth;
3900
defaultScissor.h = (Sint32)framebufferHeight;
3907
static void D3D12_INTERNAL_TrackUniformBuffer(
3908
D3D12CommandBuffer *commandBuffer,
3909
D3D12UniformBuffer *uniformBuffer)
3912
for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
3913
if (commandBuffer->usedUniformBuffers[i] == uniformBuffer) {
3918
if (commandBuffer->usedUniformBufferCount == commandBuffer->usedUniformBufferCapacity) {
3919
commandBuffer->usedUniformBufferCapacity += 1;
3920
commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_realloc(
3921
commandBuffer->usedUniformBuffers,
3922
commandBuffer->usedUniformBufferCapacity * sizeof(D3D12UniformBuffer *));
3925
commandBuffer->usedUniformBuffers[commandBuffer->usedUniformBufferCount] = uniformBuffer;
3926
commandBuffer->usedUniformBufferCount += 1;
3928
D3D12_INTERNAL_TrackBuffer(
3930
uniformBuffer->buffer);
3933
static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
3934
D3D12CommandBuffer *commandBuffer)
3936
D3D12Renderer *renderer = commandBuffer->renderer;
3937
D3D12UniformBuffer *uniformBuffer;
3939
SDL_LockMutex(renderer->acquireUniformBufferLock);
3941
if (renderer->uniformBufferPoolCount > 0) {
3942
uniformBuffer = renderer->uniformBufferPool[renderer->uniformBufferPoolCount - 1];
3943
renderer->uniformBufferPoolCount -= 1;
3945
uniformBuffer = (D3D12UniformBuffer *)SDL_calloc(1, sizeof(D3D12UniformBuffer));
3946
if (!uniformBuffer) {
3947
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
3951
uniformBuffer->buffer = D3D12_INTERNAL_CreateBuffer(
3954
UNIFORM_BUFFER_SIZE,
3955
D3D12_BUFFER_TYPE_UNIFORM);
3956
if (!uniformBuffer->buffer) {
3957
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
3962
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
3964
uniformBuffer->currentBlockSize = 0;
3965
uniformBuffer->drawOffset = 0;
3966
uniformBuffer->writeOffset = 0;
3968
HRESULT res = ID3D12Resource_Map(
3969
uniformBuffer->buffer->handle,
3972
(void **)&uniformBuffer->buffer->mapPointer);
3973
ERROR_CHECK_RETURN("Failed to map buffer pool!", NULL);
3975
D3D12_INTERNAL_TrackUniformBuffer(commandBuffer, uniformBuffer);
3977
return uniformBuffer;
3980
static void D3D12_INTERNAL_ReturnUniformBufferToPool(
3981
D3D12Renderer *renderer,
3982
D3D12UniformBuffer *uniformBuffer)
3984
if (renderer->uniformBufferPoolCount >= renderer->uniformBufferPoolCapacity) {
3985
renderer->uniformBufferPoolCapacity *= 2;
3986
renderer->uniformBufferPool = (D3D12UniformBuffer **)SDL_realloc(
3987
renderer->uniformBufferPool,
3988
renderer->uniformBufferPoolCapacity * sizeof(D3D12UniformBuffer *));
3991
renderer->uniformBufferPool[renderer->uniformBufferPoolCount] = uniformBuffer;
3992
renderer->uniformBufferPoolCount += 1;
3995
static void D3D12_INTERNAL_PushUniformData(
3996
D3D12CommandBuffer *commandBuffer,
3997
SDL_GPUShaderStage shaderStage,
4000
Uint32 dataLengthInBytes)
4002
D3D12UniformBuffer *uniformBuffer;
4004
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4005
if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) {
4006
commandBuffer->vertexUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4009
uniformBuffer = commandBuffer->vertexUniformBuffers[slotIndex];
4010
} else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4011
if (commandBuffer->fragmentUniformBuffers[slotIndex] == NULL) {
4012
commandBuffer->fragmentUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4015
uniformBuffer = commandBuffer->fragmentUniformBuffers[slotIndex];
4016
} else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4017
if (commandBuffer->computeUniformBuffers[slotIndex] == NULL) {
4018
commandBuffer->computeUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4021
uniformBuffer = commandBuffer->computeUniformBuffers[slotIndex];
4023
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4027
uniformBuffer->currentBlockSize =
4028
D3D12_INTERNAL_Align(
4033
if (uniformBuffer->writeOffset + uniformBuffer->currentBlockSize >= UNIFORM_BUFFER_SIZE) {
4034
ID3D12Resource_Unmap(
4035
uniformBuffer->buffer->handle,
4038
uniformBuffer->buffer->mapPointer = NULL;
4040
uniformBuffer = D3D12_INTERNAL_AcquireUniformBufferFromPool(commandBuffer);
4042
uniformBuffer->drawOffset = 0;
4043
uniformBuffer->writeOffset = 0;
4045
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4046
commandBuffer->vertexUniformBuffers[slotIndex] = uniformBuffer;
4047
} else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4048
commandBuffer->fragmentUniformBuffers[slotIndex] = uniformBuffer;
4049
} else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4050
commandBuffer->computeUniformBuffers[slotIndex] = uniformBuffer;
4052
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4056
uniformBuffer->drawOffset = uniformBuffer->writeOffset;
4059
(Uint8 *)uniformBuffer->buffer->mapPointer + uniformBuffer->writeOffset,
4063
uniformBuffer->writeOffset += uniformBuffer->currentBlockSize;
4065
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4066
commandBuffer->needVertexUniformBufferBind[slotIndex] = true;
4067
} else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4068
commandBuffer->needFragmentUniformBufferBind[slotIndex] = true;
4069
} else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4070
commandBuffer->needComputeUniformBufferBind[slotIndex] = true;
4072
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4076
static void D3D12_BindGraphicsPipeline(
4077
SDL_GPUCommandBuffer *commandBuffer,
4078
SDL_GPUGraphicsPipeline *graphicsPipeline)
4080
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4081
D3D12GraphicsPipeline *pipeline = (D3D12GraphicsPipeline *)graphicsPipeline;
4084
d3d12CommandBuffer->currentGraphicsPipeline = pipeline;
4087
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandBuffer->graphicsCommandList, pipeline->pipelineState);
4089
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandBuffer->graphicsCommandList, pipeline->rootSignature->handle);
4091
ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandBuffer->graphicsCommandList, SDLToD3D12_PrimitiveType[pipeline->primitiveType]);
4093
float blendFactor[4] = {
4094
pipeline->blendConstants[0],
4095
pipeline->blendConstants[1],
4096
pipeline->blendConstants[2],
4097
pipeline->blendConstants[3]
4099
ID3D12GraphicsCommandList_OMSetBlendFactor(d3d12CommandBuffer->graphicsCommandList, blendFactor);
4101
ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandBuffer->graphicsCommandList, pipeline->stencilRef);
4104
d3d12CommandBuffer->needVertexSamplerBind = true;
4105
d3d12CommandBuffer->needVertexStorageTextureBind = true;
4106
d3d12CommandBuffer->needVertexStorageBufferBind = true;
4107
d3d12CommandBuffer->needFragmentSamplerBind = true;
4108
d3d12CommandBuffer->needFragmentStorageTextureBind = true;
4109
d3d12CommandBuffer->needFragmentStorageBufferBind = true;
4111
for (i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4112
d3d12CommandBuffer->needVertexUniformBufferBind[i] = true;
4113
d3d12CommandBuffer->needFragmentUniformBufferBind[i] = true;
4116
for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
4117
if (d3d12CommandBuffer->vertexUniformBuffers[i] == NULL) {
4118
d3d12CommandBuffer->vertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4119
d3d12CommandBuffer);
4123
for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
4124
if (d3d12CommandBuffer->fragmentUniformBuffers[i] == NULL) {
4125
d3d12CommandBuffer->fragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4126
d3d12CommandBuffer);
4130
D3D12_INTERNAL_TrackGraphicsPipeline(d3d12CommandBuffer, pipeline);
4133
static void D3D12_BindVertexBuffers(
4134
SDL_GPUCommandBuffer *commandBuffer,
4135
Uint32 firstBinding,
4136
SDL_GPUBufferBinding *pBindings,
4137
Uint32 bindingCount)
4139
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4141
for (Uint32 i = 0; i < bindingCount; i += 1) {
4142
D3D12Buffer *currentBuffer = ((D3D12BufferContainer *)pBindings[i].buffer)->activeBuffer;
4143
d3d12CommandBuffer->vertexBuffers[firstBinding + i] = currentBuffer;
4144
d3d12CommandBuffer->vertexBufferOffsets[firstBinding + i] = pBindings[i].offset;
4145
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, currentBuffer);
4148
d3d12CommandBuffer->vertexBufferCount =
4149
SDL_max(d3d12CommandBuffer->vertexBufferCount, firstBinding + bindingCount);
4151
d3d12CommandBuffer->needVertexBufferBind = true;
4154
static void D3D12_BindIndexBuffer(
4155
SDL_GPUCommandBuffer *commandBuffer,
4156
SDL_GPUBufferBinding *pBinding,
4157
SDL_GPUIndexElementSize indexElementSize)
4159
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4160
D3D12Buffer *buffer = ((D3D12BufferContainer *)pBinding->buffer)->activeBuffer;
4161
D3D12_INDEX_BUFFER_VIEW view;
4163
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, buffer);
4165
view.BufferLocation = buffer->virtualAddress + pBinding->offset;
4166
view.SizeInBytes = buffer->container->size - pBinding->offset;
4168
indexElementSize == SDL_GPU_INDEXELEMENTSIZE_16BIT ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
4170
ID3D12GraphicsCommandList_IASetIndexBuffer(
4171
d3d12CommandBuffer->graphicsCommandList,
4175
static void D3D12_BindVertexSamplers(
4176
SDL_GPUCommandBuffer *commandBuffer,
4178
SDL_GPUTextureSamplerBinding *textureSamplerBindings,
4179
Uint32 bindingCount)
4181
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4183
for (Uint32 i = 0; i < bindingCount; i += 1) {
4184
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
4185
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
4187
D3D12_INTERNAL_TrackTexture(
4189
container->activeTexture);
4191
D3D12_INTERNAL_TrackSampler(
4195
d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler;
4196
d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture;
4199
d3d12CommandBuffer->needVertexSamplerBind = true;
4202
static void D3D12_BindVertexStorageTextures(
4203
SDL_GPUCommandBuffer *commandBuffer,
4205
SDL_GPUTexture **storageTextures,
4206
Uint32 bindingCount)
4208
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4210
for (Uint32 i = 0; i < bindingCount; i += 1) {
4211
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
4212
D3D12Texture *texture = container->activeTexture;
4214
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
4216
d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture;
4219
d3d12CommandBuffer->needVertexStorageTextureBind = true;
4222
static void D3D12_BindVertexStorageBuffers(
4223
SDL_GPUCommandBuffer *commandBuffer,
4225
SDL_GPUBuffer **storageBuffers,
4226
Uint32 bindingCount)
4228
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4230
for (Uint32 i = 0; i < bindingCount; i += 1) {
4231
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
4233
D3D12_INTERNAL_TrackBuffer(
4235
container->activeBuffer);
4237
d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer;
4240
d3d12CommandBuffer->needVertexStorageBufferBind = true;
4243
static void D3D12_BindFragmentSamplers(
4244
SDL_GPUCommandBuffer *commandBuffer,
4246
SDL_GPUTextureSamplerBinding *textureSamplerBindings,
4247
Uint32 bindingCount)
4249
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4251
for (Uint32 i = 0; i < bindingCount; i += 1) {
4252
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
4253
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
4255
D3D12_INTERNAL_TrackTexture(
4257
container->activeTexture);
4259
D3D12_INTERNAL_TrackSampler(
4263
d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler;
4264
d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture;
4267
d3d12CommandBuffer->needFragmentSamplerBind = true;
4270
static void D3D12_BindFragmentStorageTextures(
4271
SDL_GPUCommandBuffer *commandBuffer,
4273
SDL_GPUTexture **storageTextures,
4274
Uint32 bindingCount)
4276
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4278
for (Uint32 i = 0; i < bindingCount; i += 1) {
4279
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
4280
D3D12Texture *texture = container->activeTexture;
4282
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
4284
d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture;
4287
d3d12CommandBuffer->needFragmentStorageTextureBind = true;
4290
static void D3D12_BindFragmentStorageBuffers(
4291
SDL_GPUCommandBuffer *commandBuffer,
4293
SDL_GPUBuffer **storageBuffers,
4294
Uint32 bindingCount)
4296
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4298
for (Uint32 i = 0; i < bindingCount; i += 1) {
4299
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
4301
D3D12_INTERNAL_TrackBuffer(
4303
container->activeBuffer);
4305
d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer;
4308
d3d12CommandBuffer->needFragmentStorageBufferBind = true;
4311
static void D3D12_PushVertexUniformData(
4312
SDL_GPUCommandBuffer *commandBuffer,
4315
Uint32 dataLengthInBytes)
4317
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4319
D3D12_INTERNAL_PushUniformData(
4321
SDL_GPU_SHADERSTAGE_VERTEX,
4327
static void D3D12_PushFragmentUniformData(
4328
SDL_GPUCommandBuffer *commandBuffer,
4331
Uint32 dataLengthInBytes)
4333
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4335
D3D12_INTERNAL_PushUniformData(
4337
SDL_GPU_SHADERSTAGE_FRAGMENT,
4343
static void D3D12_INTERNAL_WriteGPUDescriptors(
4344
D3D12CommandBuffer *commandBuffer,
4345
D3D12_DESCRIPTOR_HEAP_TYPE heapType,
4346
D3D12_CPU_DESCRIPTOR_HANDLE *resourceDescriptorHandles,
4347
Uint32 resourceHandleCount,
4348
D3D12_GPU_DESCRIPTOR_HANDLE *gpuBaseDescriptor)
4350
D3D12DescriptorHeap *heap = commandBuffer->gpuDescriptorHeaps[heapType];
4351
D3D12_CPU_DESCRIPTOR_HANDLE gpuHeapCpuHandle;
4354
gpuHeapCpuHandle.ptr = heap->descriptorHeapCPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize);
4355
gpuBaseDescriptor->ptr = heap->descriptorHeapGPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize);
4357
for (Uint32 i = 0; i < resourceHandleCount; i += 1) {
4358
ID3D12Device_CopyDescriptorsSimple(
4359
commandBuffer->renderer->device,
4362
resourceDescriptorHandles[i],
4365
heap->currentDescriptorIndex += 1;
4366
gpuHeapCpuHandle.ptr += heap->descriptorSize;
4370
static void D3D12_INTERNAL_BindGraphicsResources(
4371
D3D12CommandBuffer *commandBuffer)
4373
D3D12GraphicsPipeline *graphicsPipeline = commandBuffer->currentGraphicsPipeline;
4375
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
4376
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
4377
D3D12_VERTEX_BUFFER_VIEW vertexBufferViews[MAX_BUFFER_BINDINGS];
4379
if (commandBuffer->needVertexBufferBind) {
4380
for (Uint32 i = 0; i < commandBuffer->vertexBufferCount; i += 1) {
4381
vertexBufferViews[i].BufferLocation = commandBuffer->vertexBuffers[i]->virtualAddress + commandBuffer->vertexBufferOffsets[i];
4382
vertexBufferViews[i].SizeInBytes = commandBuffer->vertexBuffers[i]->container->size - commandBuffer->vertexBufferOffsets[i];
4383
vertexBufferViews[i].StrideInBytes = graphicsPipeline->vertexStrides[i];
4386
ID3D12GraphicsCommandList_IASetVertexBuffers(
4387
commandBuffer->graphicsCommandList,
4389
commandBuffer->vertexBufferCount,
4393
if (commandBuffer->needVertexSamplerBind) {
4394
if (graphicsPipeline->vertexSamplerCount > 0) {
4395
for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
4396
cpuHandles[i] = commandBuffer->vertexSamplers[i]->handle.cpuHandle;
4399
D3D12_INTERNAL_WriteGPUDescriptors(
4401
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
4403
graphicsPipeline->vertexSamplerCount,
4404
&gpuDescriptorHandle);
4406
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4407
commandBuffer->graphicsCommandList,
4408
graphicsPipeline->rootSignature->vertexSamplerRootIndex,
4409
gpuDescriptorHandle);
4411
for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
4412
cpuHandles[i] = commandBuffer->vertexSamplerTextures[i]->srvHandle.cpuHandle;
4415
D3D12_INTERNAL_WriteGPUDescriptors(
4417
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4419
graphicsPipeline->vertexSamplerCount,
4420
&gpuDescriptorHandle);
4422
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4423
commandBuffer->graphicsCommandList,
4424
graphicsPipeline->rootSignature->vertexSamplerTextureRootIndex,
4425
gpuDescriptorHandle);
4427
commandBuffer->needVertexSamplerBind = false;
4430
if (commandBuffer->needVertexStorageTextureBind) {
4431
if (graphicsPipeline->vertexStorageTextureCount > 0) {
4432
for (Uint32 i = 0; i < graphicsPipeline->vertexStorageTextureCount; i += 1) {
4433
cpuHandles[i] = commandBuffer->vertexStorageTextures[i]->srvHandle.cpuHandle;
4436
D3D12_INTERNAL_WriteGPUDescriptors(
4438
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4440
graphicsPipeline->vertexStorageTextureCount,
4441
&gpuDescriptorHandle);
4443
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4444
commandBuffer->graphicsCommandList,
4445
graphicsPipeline->rootSignature->vertexStorageTextureRootIndex,
4446
gpuDescriptorHandle);
4448
commandBuffer->needVertexStorageTextureBind = false;
4451
if (commandBuffer->needVertexStorageBufferBind) {
4452
if (graphicsPipeline->vertexStorageBufferCount > 0) {
4453
for (Uint32 i = 0; i < graphicsPipeline->vertexStorageBufferCount; i += 1) {
4454
cpuHandles[i] = commandBuffer->vertexStorageBuffers[i]->srvDescriptor.cpuHandle;
4457
D3D12_INTERNAL_WriteGPUDescriptors(
4459
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4461
graphicsPipeline->vertexStorageBufferCount,
4462
&gpuDescriptorHandle);
4464
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4465
commandBuffer->graphicsCommandList,
4466
graphicsPipeline->rootSignature->vertexStorageBufferRootIndex,
4467
gpuDescriptorHandle);
4469
commandBuffer->needVertexStorageBufferBind = false;
4472
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4473
if (commandBuffer->needVertexUniformBufferBind[i]) {
4474
if (graphicsPipeline->vertexUniformBufferCount > i) {
4475
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
4476
commandBuffer->graphicsCommandList,
4477
graphicsPipeline->rootSignature->vertexUniformBufferRootIndex[i],
4478
commandBuffer->vertexUniformBuffers[i]->buffer->virtualAddress + commandBuffer->vertexUniformBuffers[i]->drawOffset);
4480
commandBuffer->needVertexUniformBufferBind[i] = false;
4484
if (commandBuffer->needFragmentSamplerBind) {
4485
if (graphicsPipeline->fragmentSamplerCount > 0) {
4486
for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
4487
cpuHandles[i] = commandBuffer->fragmentSamplers[i]->handle.cpuHandle;
4490
D3D12_INTERNAL_WriteGPUDescriptors(
4492
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
4494
graphicsPipeline->fragmentSamplerCount,
4495
&gpuDescriptorHandle);
4497
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4498
commandBuffer->graphicsCommandList,
4499
graphicsPipeline->rootSignature->fragmentSamplerRootIndex,
4500
gpuDescriptorHandle);
4502
for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
4503
cpuHandles[i] = commandBuffer->fragmentSamplerTextures[i]->srvHandle.cpuHandle;
4506
D3D12_INTERNAL_WriteGPUDescriptors(
4508
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4510
graphicsPipeline->fragmentSamplerCount,
4511
&gpuDescriptorHandle);
4513
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4514
commandBuffer->graphicsCommandList,
4515
graphicsPipeline->rootSignature->fragmentSamplerTextureRootIndex,
4516
gpuDescriptorHandle);
4518
commandBuffer->needFragmentSamplerBind = false;
4521
if (commandBuffer->needFragmentStorageTextureBind) {
4522
if (graphicsPipeline->fragmentStorageTextureCount > 0) {
4523
for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageTextureCount; i += 1) {
4524
cpuHandles[i] = commandBuffer->fragmentStorageTextures[i]->srvHandle.cpuHandle;
4527
D3D12_INTERNAL_WriteGPUDescriptors(
4529
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4531
graphicsPipeline->fragmentStorageTextureCount,
4532
&gpuDescriptorHandle);
4534
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4535
commandBuffer->graphicsCommandList,
4536
graphicsPipeline->rootSignature->fragmentStorageTextureRootIndex,
4537
gpuDescriptorHandle);
4539
commandBuffer->needFragmentStorageTextureBind = false;
4542
if (commandBuffer->needFragmentStorageBufferBind) {
4543
if (graphicsPipeline->fragmentStorageBufferCount > 0) {
4544
for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageBufferCount; i += 1) {
4545
cpuHandles[i] = commandBuffer->fragmentStorageBuffers[i]->srvDescriptor.cpuHandle;
4548
D3D12_INTERNAL_WriteGPUDescriptors(
4550
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4552
graphicsPipeline->fragmentStorageBufferCount,
4553
&gpuDescriptorHandle);
4555
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4556
commandBuffer->graphicsCommandList,
4557
graphicsPipeline->rootSignature->fragmentStorageBufferRootIndex,
4558
gpuDescriptorHandle);
4560
commandBuffer->needFragmentStorageBufferBind = false;
4563
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4564
if (commandBuffer->needFragmentUniformBufferBind[i]) {
4565
if (graphicsPipeline->fragmentUniformBufferCount > i) {
4566
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
4567
commandBuffer->graphicsCommandList,
4568
graphicsPipeline->rootSignature->fragmentUniformBufferRootIndex[i],
4569
commandBuffer->fragmentUniformBuffers[i]->buffer->virtualAddress + commandBuffer->fragmentUniformBuffers[i]->drawOffset);
4571
commandBuffer->needFragmentUniformBufferBind[i] = false;
4576
static void D3D12_DrawIndexedPrimitives(
4577
SDL_GPUCommandBuffer *commandBuffer,
4579
Uint32 instanceCount,
4581
Sint32 vertexOffset,
4582
Uint32 firstInstance)
4584
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4585
D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
4587
ID3D12GraphicsCommandList_DrawIndexedInstanced(
4588
d3d12CommandBuffer->graphicsCommandList,
4596
static void D3D12_DrawPrimitives(
4597
SDL_GPUCommandBuffer *commandBuffer,
4599
Uint32 instanceCount,
4601
Uint32 firstInstance)
4603
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4604
D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
4606
ID3D12GraphicsCommandList_DrawInstanced(
4607
d3d12CommandBuffer->graphicsCommandList,
4614
static void D3D12_DrawPrimitivesIndirect(
4615
SDL_GPUCommandBuffer *commandBuffer,
4616
SDL_GPUBuffer *buffer,
4617
Uint32 offsetInBytes,
4621
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4622
D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
4624
D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
4626
if (stride == sizeof(SDL_GPUIndirectDrawCommand)) {
4628
ID3D12GraphicsCommandList_ExecuteIndirect(
4629
d3d12CommandBuffer->graphicsCommandList,
4630
d3d12CommandBuffer->renderer->indirectDrawCommandSignature,
4632
d3d12Buffer->handle,
4641
for (Uint32 i = 0; i < drawCount; i += 1) {
4642
ID3D12GraphicsCommandList_ExecuteIndirect(
4643
d3d12CommandBuffer->graphicsCommandList,
4644
d3d12CommandBuffer->renderer->indirectDrawCommandSignature,
4646
d3d12Buffer->handle,
4647
offsetInBytes + (stride * i),
4654
static void D3D12_DrawIndexedPrimitivesIndirect(
4655
SDL_GPUCommandBuffer *commandBuffer,
4656
SDL_GPUBuffer *buffer,
4657
Uint32 offsetInBytes,
4661
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4662
D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
4664
D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
4666
if (stride == sizeof(SDL_GPUIndexedIndirectDrawCommand)) {
4668
ID3D12GraphicsCommandList_ExecuteIndirect(
4669
d3d12CommandBuffer->graphicsCommandList,
4670
d3d12CommandBuffer->renderer->indirectIndexedDrawCommandSignature,
4672
d3d12Buffer->handle,
4681
for (Uint32 i = 0; i < drawCount; i += 1) {
4682
ID3D12GraphicsCommandList_ExecuteIndirect(
4683
d3d12CommandBuffer->graphicsCommandList,
4684
d3d12CommandBuffer->renderer->indirectIndexedDrawCommandSignature,
4686
d3d12Buffer->handle,
4687
offsetInBytes + (stride * i),
4694
static void D3D12_EndRenderPass(
4695
SDL_GPUCommandBuffer *commandBuffer)
4697
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4700
for (i = 0; i < d3d12CommandBuffer->colorAttachmentTextureSubresourceCount; i += 1) {
4701
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
4703
D3D12_RESOURCE_STATE_RENDER_TARGET,
4704
d3d12CommandBuffer->colorAttachmentTextureSubresources[i]);
4706
d3d12CommandBuffer->colorAttachmentTextureSubresources[i] = NULL;
4708
d3d12CommandBuffer->colorAttachmentTextureSubresourceCount = 0;
4710
if (d3d12CommandBuffer->depthStencilTextureSubresource != NULL) {
4711
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
4713
D3D12_RESOURCE_STATE_DEPTH_WRITE,
4714
d3d12CommandBuffer->depthStencilTextureSubresource);
4716
d3d12CommandBuffer->depthStencilTextureSubresource = NULL;
4719
d3d12CommandBuffer->currentGraphicsPipeline = NULL;
4721
ID3D12GraphicsCommandList_OMSetRenderTargets(
4722
d3d12CommandBuffer->graphicsCommandList,
4729
SDL_zeroa(d3d12CommandBuffer->colorAttachmentTextureSubresources);
4730
d3d12CommandBuffer->depthStencilTextureSubresource = NULL;
4732
SDL_zeroa(d3d12CommandBuffer->vertexBuffers);
4733
SDL_zeroa(d3d12CommandBuffer->vertexBufferOffsets);
4734
d3d12CommandBuffer->vertexBufferCount = 0;
4736
SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextures);
4737
SDL_zeroa(d3d12CommandBuffer->vertexSamplers);
4738
SDL_zeroa(d3d12CommandBuffer->vertexStorageTextures);
4739
SDL_zeroa(d3d12CommandBuffer->vertexStorageBuffers);
4741
SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextures);
4742
SDL_zeroa(d3d12CommandBuffer->fragmentSamplers);
4743
SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextures);
4744
SDL_zeroa(d3d12CommandBuffer->fragmentStorageBuffers);
4749
static void D3D12_BeginComputePass(
4750
SDL_GPUCommandBuffer *commandBuffer,
4751
SDL_GPUStorageTextureWriteOnlyBinding *storageTextureBindings,
4752
Uint32 storageTextureBindingCount,
4753
SDL_GPUStorageBufferWriteOnlyBinding *storageBufferBindings,
4754
Uint32 storageBufferBindingCount)
4756
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4758
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresourceCount = storageTextureBindingCount;
4759
d3d12CommandBuffer->computeWriteOnlyStorageBufferCount = storageBufferBindingCount;
4765
if (storageTextureBindingCount > 0) {
4766
for (Uint32 i = 0; i < storageTextureBindingCount; i += 1) {
4767
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextureBindings[i].texture;
4768
if (!(container->header.info.usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE)) {
4769
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Attempted to bind read-only texture as compute write texture");
4772
D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
4775
storageTextureBindings[i].layer,
4776
storageTextureBindings[i].mipLevel,
4777
storageTextureBindings[i].cycle,
4778
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
4780
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresources[i] = subresource;
4782
D3D12_INTERNAL_TrackTexture(
4784
subresource->parent);
4788
if (storageBufferBindingCount > 0) {
4789
for (Uint32 i = 0; i < storageBufferBindingCount; i += 1) {
4790
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBufferBindings[i].buffer;
4791
if (!(container->usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE)) {
4792
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Attempted to bind read-only texture as compute write texture");
4794
D3D12Buffer *buffer = D3D12_INTERNAL_PrepareBufferForWrite(
4797
storageBufferBindings[i].cycle,
4798
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
4800
d3d12CommandBuffer->computeWriteOnlyStorageBuffers[i] = buffer;
4802
D3D12_INTERNAL_TrackBuffer(
4809
static void D3D12_BindComputePipeline(
4810
SDL_GPUCommandBuffer *commandBuffer,
4811
SDL_GPUComputePipeline *computePipeline)
4813
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4814
D3D12ComputePipeline *pipeline = (D3D12ComputePipeline *)computePipeline;
4815
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
4816
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
4818
ID3D12GraphicsCommandList_SetPipelineState(
4819
d3d12CommandBuffer->graphicsCommandList,
4820
pipeline->pipelineState);
4822
ID3D12GraphicsCommandList_SetComputeRootSignature(
4823
d3d12CommandBuffer->graphicsCommandList,
4824
pipeline->rootSignature->handle);
4826
d3d12CommandBuffer->currentComputePipeline = pipeline;
4828
d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
4829
d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
4831
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4832
d3d12CommandBuffer->needComputeUniformBufferBind[i] = true;
4835
for (Uint32 i = 0; i < pipeline->uniformBufferCount; i += 1) {
4836
if (d3d12CommandBuffer->computeUniformBuffers[i] == NULL) {
4837
d3d12CommandBuffer->computeUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4838
d3d12CommandBuffer);
4842
D3D12_INTERNAL_TrackComputePipeline(d3d12CommandBuffer, pipeline);
4845
if (pipeline->writeOnlyStorageTextureCount > 0) {
4846
for (Uint32 i = 0; i < pipeline->writeOnlyStorageTextureCount; i += 1) {
4847
cpuHandles[i] = d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresources[i]->uavHandle.cpuHandle;
4850
D3D12_INTERNAL_WriteGPUDescriptors(
4852
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4854
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresourceCount,
4855
&gpuDescriptorHandle);
4857
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
4858
d3d12CommandBuffer->graphicsCommandList,
4859
d3d12CommandBuffer->currentComputePipeline->rootSignature->writeOnlyStorageTextureRootIndex,
4860
gpuDescriptorHandle);
4863
if (pipeline->writeOnlyStorageBufferCount > 0) {
4864
for (Uint32 i = 0; i < pipeline->writeOnlyStorageBufferCount; i += 1) {
4865
cpuHandles[i] = d3d12CommandBuffer->computeWriteOnlyStorageBuffers[i]->uavDescriptor.cpuHandle;
4868
D3D12_INTERNAL_WriteGPUDescriptors(
4870
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4872
d3d12CommandBuffer->computeWriteOnlyStorageBufferCount,
4873
&gpuDescriptorHandle);
4875
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
4876
d3d12CommandBuffer->graphicsCommandList,
4877
d3d12CommandBuffer->currentComputePipeline->rootSignature->writeOnlyStorageBufferRootIndex,
4878
gpuDescriptorHandle);
4882
static void D3D12_BindComputeStorageTextures(
4883
SDL_GPUCommandBuffer *commandBuffer,
4885
SDL_GPUTexture **storageTextures,
4886
Uint32 bindingCount)
4888
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4890
for (Uint32 i = 0; i < bindingCount; i += 1) {
4891
if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != NULL) {
4892
D3D12_INTERNAL_TextureTransitionToDefaultUsage(
4894
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
4895
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i]);
4898
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
4899
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture;
4901
D3D12_INTERNAL_TextureTransitionFromDefaultUsage(
4903
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
4904
container->activeTexture);
4906
D3D12_INTERNAL_TrackTexture(
4908
container->activeTexture);
4911
d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
4914
static void D3D12_BindComputeStorageBuffers(
4915
SDL_GPUCommandBuffer *commandBuffer,
4917
SDL_GPUBuffer **storageBuffers,
4918
Uint32 bindingCount)
4920
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4922
for (Uint32 i = 0; i < bindingCount; i += 1) {
4923
if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != NULL) {
4924
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
4926
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
4927
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i]);
4930
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
4931
D3D12Buffer *buffer = container->activeBuffer;
4933
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
4935
D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
4937
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
4940
D3D12_INTERNAL_TrackBuffer(
4945
d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
4948
static void D3D12_PushComputeUniformData(
4949
SDL_GPUCommandBuffer *commandBuffer,
4952
Uint32 dataLengthInBytes)
4954
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4956
D3D12_INTERNAL_PushUniformData(
4958
SDL_GPU_SHADERSTAGE_COMPUTE,
4964
static void D3D12_INTERNAL_BindComputeResources(
4965
D3D12CommandBuffer *commandBuffer)
4967
D3D12ComputePipeline *computePipeline = commandBuffer->currentComputePipeline;
4969
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
4970
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
4972
if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
4973
if (computePipeline->readOnlyStorageTextureCount > 0) {
4974
for (Uint32 i = 0; i < computePipeline->readOnlyStorageTextureCount; i += 1) {
4975
cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextures[i]->srvHandle.cpuHandle;
4978
D3D12_INTERNAL_WriteGPUDescriptors(
4980
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4982
computePipeline->readOnlyStorageTextureCount,
4983
&gpuDescriptorHandle);
4985
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
4986
commandBuffer->graphicsCommandList,
4987
computePipeline->rootSignature->readOnlyStorageTextureRootIndex,
4988
gpuDescriptorHandle);
4990
commandBuffer->needComputeReadOnlyStorageTextureBind = false;
4993
if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
4994
if (computePipeline->readOnlyStorageBufferCount > 0) {
4995
for (Uint32 i = 0; i < computePipeline->readOnlyStorageBufferCount; i += 1) {
4996
cpuHandles[i] = commandBuffer->computeReadOnlyStorageBuffers[i]->srvDescriptor.cpuHandle;
4999
D3D12_INTERNAL_WriteGPUDescriptors(
5001
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5003
computePipeline->readOnlyStorageBufferCount,
5004
&gpuDescriptorHandle);
5006
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5007
commandBuffer->graphicsCommandList,
5008
computePipeline->rootSignature->readOnlyStorageBufferRootIndex,
5009
gpuDescriptorHandle);
5011
commandBuffer->needComputeReadOnlyStorageBufferBind = false;
5014
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
5015
if (commandBuffer->needComputeUniformBufferBind[i]) {
5016
if (computePipeline->uniformBufferCount > i) {
5017
ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(
5018
commandBuffer->graphicsCommandList,
5019
computePipeline->rootSignature->uniformBufferRootIndex[i],
5020
commandBuffer->computeUniformBuffers[i]->buffer->virtualAddress + commandBuffer->computeUniformBuffers[i]->drawOffset);
5023
commandBuffer->needComputeUniformBufferBind[i] = false;
5027
static void D3D12_DispatchCompute(
5028
SDL_GPUCommandBuffer *commandBuffer,
5033
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5035
D3D12_INTERNAL_BindComputeResources(d3d12CommandBuffer);
5036
ID3D12GraphicsCommandList_Dispatch(
5037
d3d12CommandBuffer->graphicsCommandList,
5043
static void D3D12_DispatchComputeIndirect(
5044
SDL_GPUCommandBuffer *commandBuffer,
5045
SDL_GPUBuffer *buffer,
5046
Uint32 offsetInBytes)
5048
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5049
D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
5051
D3D12_INTERNAL_BindComputeResources(d3d12CommandBuffer);
5052
ID3D12GraphicsCommandList_ExecuteIndirect(
5053
d3d12CommandBuffer->graphicsCommandList,
5054
d3d12CommandBuffer->renderer->indirectDispatchCommandSignature,
5056
d3d12Buffer->handle,
5062
static void D3D12_EndComputePass(
5063
SDL_GPUCommandBuffer *commandBuffer)
5065
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5067
for (Uint32 i = 0; i < d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresourceCount; i += 1) {
5068
if (d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresources[i]) {
5069
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5071
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
5072
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresources[i]);
5074
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresources[i] = NULL;
5077
d3d12CommandBuffer->computeWriteOnlyStorageTextureSubresourceCount = 0;
5079
for (Uint32 i = 0; i < d3d12CommandBuffer->computeWriteOnlyStorageBufferCount; i += 1) {
5080
if (d3d12CommandBuffer->computeWriteOnlyStorageBuffers[i]) {
5081
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5083
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
5084
d3d12CommandBuffer->computeWriteOnlyStorageBuffers[i]);
5086
d3d12CommandBuffer->computeWriteOnlyStorageBuffers[i] = NULL;
5089
d3d12CommandBuffer->computeWriteOnlyStorageBufferCount = 0;
5091
for (Uint32 i = 0; i < MAX_STORAGE_TEXTURES_PER_STAGE; i += 1) {
5092
if (d3d12CommandBuffer->computeReadOnlyStorageTextures[i]) {
5093
D3D12_INTERNAL_TextureTransitionToDefaultUsage(
5095
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5096
d3d12CommandBuffer->computeReadOnlyStorageTextures[i]);
5098
d3d12CommandBuffer->computeReadOnlyStorageTextures[i] = NULL;
5102
for (Uint32 i = 0; i < MAX_STORAGE_BUFFERS_PER_STAGE; i += 1) {
5103
if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[i]) {
5104
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5106
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5107
d3d12CommandBuffer->computeReadOnlyStorageBuffers[i]);
5109
d3d12CommandBuffer->computeReadOnlyStorageBuffers[i] = NULL;
5113
d3d12CommandBuffer->currentComputePipeline = NULL;
5118
static void *D3D12_MapTransferBuffer(
5119
SDL_GPURenderer *driverData,
5120
SDL_GPUTransferBuffer *transferBuffer,
5123
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
5124
D3D12BufferContainer *container = (D3D12BufferContainer *)transferBuffer;
5129
SDL_AtomicGet(&container->activeBuffer->referenceCount) > 0) {
5130
D3D12_INTERNAL_CycleActiveBuffer(
5136
if (container->type == D3D12_BUFFER_TYPE_UPLOAD) {
5137
dataPointer = container->activeBuffer->mapPointer;
5140
container->activeBuffer->handle,
5143
(void **)&dataPointer);
5149
static void D3D12_UnmapTransferBuffer(
5150
SDL_GPURenderer *driverData,
5151
SDL_GPUTransferBuffer *transferBuffer)
5154
D3D12BufferContainer *container = (D3D12BufferContainer *)transferBuffer;
5157
if (container->type == D3D12_BUFFER_TYPE_DOWNLOAD) {
5158
ID3D12Resource_Unmap(
5159
container->activeBuffer->handle,
5167
static void D3D12_BeginCopyPass(
5168
SDL_GPUCommandBuffer *commandBuffer)
5171
(void)commandBuffer;
5174
static void D3D12_UploadToTexture(
5175
SDL_GPUCommandBuffer *commandBuffer,
5176
SDL_GPUTextureTransferInfo *source,
5177
SDL_GPUTextureRegion *destination,
5180
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5181
D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)source->transferBuffer;
5182
D3D12Buffer *temporaryBuffer = NULL;
5183
D3D12_TEXTURE_COPY_LOCATION sourceLocation;
5184
D3D12_TEXTURE_COPY_LOCATION destinationLocation;
5185
Uint32 pixelsPerRow = source->imagePitch;
5187
Uint32 alignedRowPitch;
5188
Uint32 rowsPerSlice = source->imageHeight;
5189
Uint32 bytesPerSlice;
5190
bool needsRealignment;
5191
bool needsPlacementCopy;
5195
D3D12TextureContainer *textureContainer = (D3D12TextureContainer *)destination->texture;
5196
D3D12TextureSubresource *textureSubresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
5200
destination->mipLevel,
5202
D3D12_RESOURCE_STATE_COPY_DEST);
5215
if (pixelsPerRow == 0) {
5216
pixelsPerRow = destination->w;
5219
rowPitch = BytesPerRow(pixelsPerRow, textureContainer->header.info.format);
5221
if (rowsPerSlice == 0) {
5222
rowsPerSlice = destination->h;
5225
bytesPerSlice = rowsPerSlice * rowPitch;
5227
alignedRowPitch = D3D12_INTERNAL_Align(rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
5228
needsRealignment = rowsPerSlice != destination->h || rowPitch != alignedRowPitch;
5229
needsPlacementCopy = source->offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT != 0;
5231
sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
5232
sourceLocation.PlacedFootprint.Footprint.Format = SDLToD3D12_TextureFormat[textureContainer->header.info.format];
5233
sourceLocation.PlacedFootprint.Footprint.RowPitch = alignedRowPitch;
5235
destinationLocation.pResource = textureContainer->activeTexture->resource;
5236
destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5237
destinationLocation.SubresourceIndex = textureSubresource->index;
5239
if (needsRealignment) {
5240
temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
5241
d3d12CommandBuffer->renderer,
5243
alignedRowPitch * destination->h * destination->d,
5244
D3D12_BUFFER_TYPE_UPLOAD);
5246
if (!temporaryBuffer) {
5247
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create temporary upload buffer.");
5251
sourceLocation.pResource = temporaryBuffer->handle;
5253
for (Uint32 sliceIndex = 0; sliceIndex < destination->d; sliceIndex += 1) {
5255
for (Uint32 rowIndex = 0; rowIndex < rowsPerSlice - 1; rowIndex += 1) {
5257
temporaryBuffer->mapPointer + (sliceIndex * rowsPerSlice) + (rowIndex * alignedRowPitch),
5258
transferBufferContainer->activeBuffer->mapPointer + source->offset + (sliceIndex * bytesPerSlice) + (rowIndex * rowPitch),
5261
Uint32 offset = source->offset + (sliceIndex * bytesPerSlice) + ((rowsPerSlice - 1) * rowPitch);
5263
temporaryBuffer->mapPointer + (sliceIndex * rowsPerSlice) + ((rowsPerSlice - 1) * alignedRowPitch),
5264
transferBufferContainer->activeBuffer->mapPointer + offset,
5265
SDL_min(alignedRowPitch, transferBufferContainer->size - offset));
5267
sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5268
sourceLocation.PlacedFootprint.Footprint.Height = rowsPerSlice;
5269
sourceLocation.PlacedFootprint.Footprint.Depth = 1;
5270
sourceLocation.PlacedFootprint.Offset = (sliceIndex * bytesPerSlice);
5272
ID3D12GraphicsCommandList_CopyTextureRegion(
5273
d3d12CommandBuffer->graphicsCommandList,
5274
&destinationLocation,
5282
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, temporaryBuffer);
5283
D3D12_INTERNAL_ReleaseBuffer(
5284
d3d12CommandBuffer->renderer,
5286
} else if (needsPlacementCopy) {
5287
temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
5288
d3d12CommandBuffer->renderer,
5290
alignedRowPitch * destination->h * destination->d,
5291
D3D12_BUFFER_TYPE_UPLOAD);
5293
if (!temporaryBuffer) {
5294
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create temporary upload buffer.");
5299
temporaryBuffer->mapPointer,
5300
transferBufferContainer->activeBuffer->mapPointer + source->offset,
5301
alignedRowPitch * destination->h * destination->d);
5303
sourceLocation.pResource = temporaryBuffer->handle;
5304
sourceLocation.PlacedFootprint.Offset = 0;
5305
sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5306
sourceLocation.PlacedFootprint.Footprint.Height = destination->h;
5307
sourceLocation.PlacedFootprint.Footprint.Depth = 1;
5309
ID3D12GraphicsCommandList_CopyTextureRegion(
5310
d3d12CommandBuffer->graphicsCommandList,
5311
&destinationLocation,
5318
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, temporaryBuffer);
5319
D3D12_INTERNAL_ReleaseBuffer(
5320
d3d12CommandBuffer->renderer,
5323
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Texture upload offset not aligned to 512 bytes! This is suboptimal on D3D12!");
5325
sourceLocation.pResource = transferBufferContainer->activeBuffer->handle;
5326
sourceLocation.PlacedFootprint.Offset = source->offset;
5327
sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5328
sourceLocation.PlacedFootprint.Footprint.Height = destination->h;
5329
sourceLocation.PlacedFootprint.Footprint.Depth = destination->d;
5331
ID3D12GraphicsCommandList_CopyTextureRegion(
5332
d3d12CommandBuffer->graphicsCommandList,
5333
&destinationLocation,
5341
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5343
D3D12_RESOURCE_STATE_COPY_DEST,
5344
textureSubresource);
5346
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, transferBufferContainer->activeBuffer);
5347
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, textureSubresource->parent);
5350
static void D3D12_UploadToBuffer(
5351
SDL_GPUCommandBuffer *commandBuffer,
5352
SDL_GPUTransferBufferLocation *source,
5353
SDL_GPUBufferRegion *destination,
5356
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5357
D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)source->transferBuffer;
5358
D3D12BufferContainer *bufferContainer = (D3D12BufferContainer *)destination->buffer;
5362
D3D12Buffer *buffer = D3D12_INTERNAL_PrepareBufferForWrite(
5366
D3D12_RESOURCE_STATE_COPY_DEST);
5368
ID3D12GraphicsCommandList_CopyBufferRegion(
5369
d3d12CommandBuffer->graphicsCommandList,
5371
destination->offset,
5372
transferBufferContainer->activeBuffer->handle,
5376
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5378
D3D12_RESOURCE_STATE_COPY_DEST,
5381
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, transferBufferContainer->activeBuffer);
5382
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, buffer);
5385
static void D3D12_CopyTextureToTexture(
5386
SDL_GPUCommandBuffer *commandBuffer,
5387
SDL_GPUTextureLocation *source,
5388
SDL_GPUTextureLocation *destination,
5394
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5395
D3D12_TEXTURE_COPY_LOCATION sourceLocation;
5396
D3D12_TEXTURE_COPY_LOCATION destinationLocation;
5398
D3D12TextureSubresource *sourceSubresource = D3D12_INTERNAL_FetchTextureSubresource(
5399
(D3D12TextureContainer *)source->texture,
5403
D3D12TextureSubresource *destinationSubresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
5405
(D3D12TextureContainer *)destination->texture,
5407
destination->mipLevel,
5409
D3D12_RESOURCE_STATE_COPY_DEST);
5411
D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
5413
D3D12_RESOURCE_STATE_COPY_SOURCE,
5416
sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5417
sourceLocation.SubresourceIndex = sourceSubresource->index;
5418
sourceLocation.pResource = sourceSubresource->parent->resource;
5420
destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5421
destinationLocation.SubresourceIndex = destinationSubresource->index;
5422
destinationLocation.pResource = destinationSubresource->parent->resource;
5424
D3D12_BOX sourceBox = { source->x, source->y, source->z, source->x + w, source->y + h, source->z + d };
5426
ID3D12GraphicsCommandList_CopyTextureRegion(
5427
d3d12CommandBuffer->graphicsCommandList,
5428
&destinationLocation,
5435
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5437
D3D12_RESOURCE_STATE_COPY_SOURCE,
5440
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5442
D3D12_RESOURCE_STATE_COPY_DEST,
5443
destinationSubresource);
5445
D3D12_INTERNAL_TrackTexture(
5447
sourceSubresource->parent);
5449
D3D12_INTERNAL_TrackTexture(
5451
destinationSubresource->parent);
5454
static void D3D12_CopyBufferToBuffer(
5455
SDL_GPUCommandBuffer *commandBuffer,
5456
SDL_GPUBufferLocation *source,
5457
SDL_GPUBufferLocation *destination,
5461
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5462
D3D12BufferContainer *sourceContainer = (D3D12BufferContainer *)source->buffer;
5463
D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->buffer;
5465
D3D12Buffer *sourceBuffer = sourceContainer->activeBuffer;
5466
D3D12Buffer *destinationBuffer = D3D12_INTERNAL_PrepareBufferForWrite(
5468
destinationContainer,
5470
D3D12_RESOURCE_STATE_COPY_DEST);
5472
D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
5474
D3D12_RESOURCE_STATE_COPY_SOURCE,
5477
ID3D12GraphicsCommandList_CopyBufferRegion(
5478
d3d12CommandBuffer->graphicsCommandList,
5479
destinationBuffer->handle,
5480
destination->offset,
5481
sourceBuffer->handle,
5485
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5487
D3D12_RESOURCE_STATE_COPY_SOURCE,
5490
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5492
D3D12_RESOURCE_STATE_COPY_DEST,
5495
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, sourceBuffer);
5496
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
5499
static void D3D12_DownloadFromTexture(
5500
SDL_GPUCommandBuffer *commandBuffer,
5501
SDL_GPUTextureRegion *source,
5502
SDL_GPUTextureTransferInfo *destination)
5504
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5505
D3D12_TEXTURE_COPY_LOCATION sourceLocation;
5506
D3D12_TEXTURE_COPY_LOCATION destinationLocation;
5507
Uint32 pixelsPerRow = destination->imagePitch;
5509
Uint32 alignedRowPitch;
5510
Uint32 rowsPerSlice = destination->imageHeight;
5511
bool needsRealignment;
5512
bool needsPlacementCopy;
5513
D3D12TextureDownload *textureDownload = NULL;
5514
D3D12TextureContainer *sourceContainer = (D3D12TextureContainer *)source->texture;
5515
D3D12TextureSubresource *sourceSubresource = D3D12_INTERNAL_FetchTextureSubresource(
5519
D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->transferBuffer;
5520
D3D12Buffer *destinationBuffer = destinationContainer->activeBuffer;
5536
if (pixelsPerRow == 0) {
5537
pixelsPerRow = source->w;
5540
rowPitch = BytesPerRow(pixelsPerRow, sourceContainer->header.info.format);
5542
if (rowsPerSlice == 0) {
5543
rowsPerSlice = source->h;
5546
alignedRowPitch = D3D12_INTERNAL_Align(rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
5547
needsRealignment = rowsPerSlice != source->h || rowPitch != alignedRowPitch;
5548
needsPlacementCopy = destination->offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT != 0;
5550
sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5551
sourceLocation.SubresourceIndex = sourceSubresource->index;
5552
sourceLocation.pResource = sourceSubresource->parent->resource;
5554
D3D12_BOX sourceBox = { source->x, source->y, source->z, source->x + source->w, source->y + rowsPerSlice, source->z + source->d };
5556
destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
5557
destinationLocation.PlacedFootprint.Footprint.Format = SDLToD3D12_TextureFormat[sourceContainer->header.info.format];
5558
destinationLocation.PlacedFootprint.Footprint.Width = source->w;
5559
destinationLocation.PlacedFootprint.Footprint.Height = rowsPerSlice;
5560
destinationLocation.PlacedFootprint.Footprint.Depth = source->d;
5561
destinationLocation.PlacedFootprint.Footprint.RowPitch = alignedRowPitch;
5563
if (needsRealignment || needsPlacementCopy) {
5564
textureDownload = (D3D12TextureDownload *)SDL_malloc(sizeof(D3D12TextureDownload));
5566
if (!textureDownload) {
5567
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create texture download structure!");
5571
textureDownload->temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
5572
d3d12CommandBuffer->renderer,
5574
alignedRowPitch * rowsPerSlice * source->d,
5575
D3D12_BUFFER_TYPE_DOWNLOAD);
5577
if (!textureDownload->temporaryBuffer) {
5578
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create temporary download buffer!");
5579
SDL_free(textureDownload);
5583
textureDownload->destinationBuffer = destinationBuffer;
5584
textureDownload->bufferOffset = destination->offset;
5585
textureDownload->width = source->w;
5586
textureDownload->height = rowsPerSlice;
5587
textureDownload->depth = source->d;
5588
textureDownload->bytesPerRow = rowPitch;
5589
textureDownload->bytesPerDepthSlice = rowPitch * rowsPerSlice;
5590
textureDownload->alignedBytesPerRow = alignedRowPitch;
5592
destinationLocation.pResource = textureDownload->temporaryBuffer->handle;
5593
destinationLocation.PlacedFootprint.Offset = 0;
5595
destinationLocation.pResource = destinationBuffer->handle;
5596
destinationLocation.PlacedFootprint.Offset = destination->offset;
5599
D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
5601
D3D12_RESOURCE_STATE_COPY_SOURCE,
5604
ID3D12GraphicsCommandList_CopyTextureRegion(
5605
d3d12CommandBuffer->graphicsCommandList,
5606
&destinationLocation,
5613
D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5615
D3D12_RESOURCE_STATE_COPY_SOURCE,
5618
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
5619
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, sourceSubresource->parent);
5621
if (textureDownload != NULL) {
5622
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, textureDownload->temporaryBuffer);
5624
if (d3d12CommandBuffer->textureDownloadCount >= d3d12CommandBuffer->textureDownloadCapacity) {
5625
d3d12CommandBuffer->textureDownloadCapacity *= 2;
5626
d3d12CommandBuffer->textureDownloads = (D3D12TextureDownload **)SDL_realloc(
5627
d3d12CommandBuffer->textureDownloads,
5628
d3d12CommandBuffer->textureDownloadCapacity * sizeof(D3D12TextureDownload *));
5631
d3d12CommandBuffer->textureDownloads[d3d12CommandBuffer->textureDownloadCount] = textureDownload;
5632
d3d12CommandBuffer->textureDownloadCount += 1;
5634
D3D12_INTERNAL_ReleaseBuffer(d3d12CommandBuffer->renderer, textureDownload->temporaryBuffer);
5638
static void D3D12_DownloadFromBuffer(
5639
SDL_GPUCommandBuffer *commandBuffer,
5640
SDL_GPUBufferRegion *source,
5641
SDL_GPUTransferBufferLocation *destination)
5643
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5644
D3D12BufferContainer *sourceContainer = (D3D12BufferContainer *)source->buffer;
5645
D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->transferBuffer;
5647
D3D12Buffer *sourceBuffer = sourceContainer->activeBuffer;
5648
D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
5650
D3D12_RESOURCE_STATE_COPY_SOURCE,
5653
D3D12Buffer *destinationBuffer = destinationContainer->activeBuffer;
5655
ID3D12GraphicsCommandList_CopyBufferRegion(
5656
d3d12CommandBuffer->graphicsCommandList,
5657
destinationBuffer->handle,
5658
destination->offset,
5659
sourceBuffer->handle,
5663
D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5665
D3D12_RESOURCE_STATE_COPY_SOURCE,
5668
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, sourceBuffer);
5669
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
5672
static void D3D12_EndCopyPass(
5673
SDL_GPUCommandBuffer *commandBuffer)
5676
(void)commandBuffer;
5679
static void D3D12_GenerateMipmaps(
5680
SDL_GPUCommandBuffer *commandBuffer,
5681
SDL_GPUTexture *texture)
5683
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5684
D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
5685
D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
5686
SDL_GPUGraphicsPipeline *blitPipeline;
5687
SDL_GPUBlitRegion srcRegion, dstRegion;
5689
blitPipeline = SDL_GPU_FetchBlitPipeline(
5690
renderer->sdlGPUDevice,
5691
container->header.info.type,
5692
container->header.info.format,
5693
renderer->blitVertexShader,
5694
renderer->blitFrom2DShader,
5695
renderer->blitFrom2DArrayShader,
5696
renderer->blitFrom3DShader,
5697
renderer->blitFromCubeShader,
5698
&renderer->blitPipelines,
5699
&renderer->blitPipelineCount,
5700
&renderer->blitPipelineCapacity);
5702
if (blitPipeline == NULL) {
5703
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not fetch blit pipeline");
5708
for (Uint32 layerOrDepthIndex = 0; layerOrDepthIndex < container->header.info.layerCountOrDepth; layerOrDepthIndex += 1) {
5709
for (Uint32 levelIndex = 1; levelIndex < container->header.info.levelCount; levelIndex += 1) {
5711
srcRegion.texture = texture;
5712
srcRegion.mipLevel = levelIndex - 1;
5713
srcRegion.layerOrDepthPlane = layerOrDepthIndex;
5716
srcRegion.w = container->header.info.width >> (levelIndex - 1);
5717
srcRegion.h = container->header.info.height >> (levelIndex - 1);
5719
dstRegion.texture = texture;
5720
dstRegion.mipLevel = levelIndex;
5721
dstRegion.layerOrDepthPlane = layerOrDepthIndex;
5724
dstRegion.w = container->header.info.width >> levelIndex;
5725
dstRegion.h = container->header.info.height >> levelIndex;
5732
SDL_GPU_FILTER_LINEAR,
5737
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, container->activeTexture);
5740
static void D3D12_Blit(
5741
SDL_GPUCommandBuffer *commandBuffer,
5742
SDL_GPUBlitRegion *source,
5743
SDL_GPUBlitRegion *destination,
5744
SDL_FlipMode flipMode,
5745
SDL_GPUFilter filterMode,
5748
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5749
D3D12Renderer *renderer = (D3D12Renderer *)d3d12CommandBuffer->renderer;
5758
renderer->blitLinearSampler,
5759
renderer->blitNearestSampler,
5760
renderer->blitVertexShader,
5761
renderer->blitFrom2DShader,
5762
renderer->blitFrom2DArrayShader,
5763
renderer->blitFrom3DShader,
5764
renderer->blitFromCubeShader,
5765
&renderer->blitPipelines,
5766
&renderer->blitPipelineCount,
5767
&renderer->blitPipelineCapacity);
5772
static D3D12WindowData *D3D12_INTERNAL_FetchWindowData(
5775
SDL_PropertiesID properties = SDL_GetWindowProperties(window);
5776
return (D3D12WindowData *)SDL_GetPointerProperty(properties, WINDOW_PROPERTY_DATA, NULL);
5779
static bool D3D12_SupportsSwapchainComposition(
5780
SDL_GPURenderer *driverData,
5782
SDL_GPUSwapchainComposition swapchainComposition)
5784
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
5786
return swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR ||
5787
swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR;
5789
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
5791
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport;
5792
Uint32 colorSpaceSupport;
5795
format = SwapchainCompositionToTextureFormat[swapchainComposition];
5797
formatSupport.Format = format;
5798
res = ID3D12Device_CheckFeatureSupport(
5800
D3D12_FEATURE_FORMAT_SUPPORT,
5802
sizeof(formatSupport));
5808
if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DISPLAY)) {
5812
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
5813
if (windowData == NULL) {
5814
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Must claim window before querying swapchain composition support!");
5819
if (swapchainComposition != SDL_GPU_SWAPCHAINCOMPOSITION_SDR) {
5820
IDXGISwapChain3_CheckColorSpaceSupport(
5821
windowData->swapchain,
5822
SwapchainCompositionToColorSpace[swapchainComposition],
5823
&colorSpaceSupport);
5825
if (!(colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)) {
5834
static bool D3D12_SupportsPresentMode(
5835
SDL_GPURenderer *driverData,
5837
SDL_GPUPresentMode presentMode)
5842
switch (presentMode) {
5843
case SDL_GPU_PRESENTMODE_IMMEDIATE:
5844
case SDL_GPU_PRESENTMODE_VSYNC:
5846
case SDL_GPU_PRESENTMODE_MAILBOX:
5847
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
5853
SDL_assert(!"Unrecognized present mode");
5858
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
5859
static bool D3D12_INTERNAL_CreateSwapchain(
5860
D3D12Renderer *renderer,
5861
D3D12WindowData *windowData,
5862
SDL_GPUSwapchainComposition swapchainComposition,
5863
SDL_GPUPresentMode presentMode)
5866
SDL_GPUTextureCreateInfo createInfo;
5867
D3D12Texture *texture;
5870
SDL_GetWindowSize(windowData->window, &width, &height);
5873
SDL_zero(createInfo);
5874
createInfo.type = SDL_GPU_TEXTURETYPE_2D;
5875
createInfo.width = width;
5876
createInfo.height = height;
5877
createInfo.format = SwapchainCompositionToSDLTextureFormat[swapchainComposition];
5878
createInfo.usageFlags = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
5879
createInfo.layerCountOrDepth = 1;
5880
createInfo.levelCount = 1;
5882
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
5883
texture = D3D12_INTERNAL_CreateTexture(renderer, &createInfo, true);
5884
texture->container = &windowData->textureContainers[i];
5885
windowData->textureContainers[i].activeTexture = texture;
5886
windowData->textureContainers[i].canBeCycled = false;
5887
windowData->textureContainers[i].header.info = createInfo;
5888
windowData->textureContainers[i].textureCapacity = 1;
5889
windowData->textureContainers[i].textureCount = 1;
5890
windowData->textureContainers[i].textures = &windowData->textureContainers[i].activeTexture;
5894
windowData->presentMode = presentMode;
5895
windowData->swapchainComposition = swapchainComposition;
5896
windowData->swapchainColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
5897
windowData->frameCounter = 0;
5898
windowData->swapchainWidth = width;
5899
windowData->swapchainHeight = height;
5902
for (Uint32 i = 0; i < 4; i += 1) {
5903
SDL_GPU_FetchBlitPipeline(
5904
renderer->sdlGPUDevice,
5905
(SDL_GPUTextureType)i,
5907
renderer->blitVertexShader,
5908
renderer->blitFrom2DShader,
5909
renderer->blitFrom2DArrayShader,
5910
renderer->blitFrom3DShader,
5911
renderer->blitFromCubeShader,
5912
&renderer->blitPipelines,
5913
&renderer->blitPipelineCount,
5914
&renderer->blitPipelineCapacity);
5920
static void D3D12_INTERNAL_DestroySwapchain(
5921
D3D12Renderer *renderer,
5922
D3D12WindowData *windowData)
5924
renderer->commandQueue->PresentX(0, NULL, NULL);
5925
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
5926
D3D12_INTERNAL_DestroyTexture(
5928
windowData->textureContainers[i].activeTexture);
5932
static bool D3D12_INTERNAL_ResizeSwapchainIfNeeded(
5933
D3D12Renderer *renderer,
5934
D3D12WindowData *windowData)
5937
SDL_GetWindowSize(windowData->window, &w, &h);
5939
if (w != windowData->swapchainWidth || h != windowData->swapchainHeight) {
5941
D3D12_Wait((SDL_GPURenderer *)renderer);
5944
renderer->commandQueue->PresentX(0, NULL, NULL);
5947
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
5948
D3D12_INTERNAL_DestroyTexture(
5950
windowData->textureContainers[i].activeTexture);
5954
D3D12_INTERNAL_CreateSwapchain(
5957
windowData->swapchainComposition,
5958
windowData->presentMode);
5964
static bool D3D12_INTERNAL_InitializeSwapchainTexture(
5965
D3D12Renderer *renderer,
5966
IDXGISwapChain3 *swapchain,
5967
SDL_GPUSwapchainComposition composition,
5969
D3D12TextureContainer *pTextureContainer)
5971
D3D12Texture *pTexture;
5972
ID3D12Resource *swapchainTexture;
5973
D3D12_RESOURCE_DESC textureDesc;
5974
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
5975
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
5976
DXGI_FORMAT swapchainFormat = SwapchainCompositionToTextureFormat[composition];
5979
res = IDXGISwapChain_GetBuffer(
5982
D3D_GUID(D3D_IID_ID3D12Resource),
5983
(void **)&swapchainTexture);
5984
ERROR_CHECK_RETURN("Could not get buffer from swapchain!", 0);
5986
pTexture = (D3D12Texture *)SDL_calloc(1, sizeof(D3D12Texture));
5988
ID3D12Resource_Release(swapchainTexture);
5991
pTexture->resource = NULL;
5992
SDL_AtomicSet(&pTexture->referenceCount, 0);
5993
pTexture->subresourceCount = 1;
5994
pTexture->subresources = (D3D12TextureSubresource *)SDL_calloc(1, sizeof(D3D12TextureSubresource));
5995
if (!pTexture->subresources) {
5997
ID3D12Resource_Release(swapchainTexture);
6000
pTexture->subresources[0].rtvHandles = SDL_calloc(1, sizeof(D3D12CPUDescriptor));
6001
pTexture->subresources[0].uavHandle.heap = NULL;
6002
pTexture->subresources[0].dsvHandle.heap = NULL;
6003
pTexture->subresources[0].parent = pTexture;
6004
pTexture->subresources[0].index = 0;
6005
pTexture->subresources[0].layer = 0;
6006
pTexture->subresources[0].depth = 1;
6007
pTexture->subresources[0].level = 0;
6009
ID3D12Resource_GetDesc(swapchainTexture, &textureDesc);
6010
pTextureContainer->header.info.width = (Uint32)textureDesc.Width;
6011
pTextureContainer->header.info.height = (Uint32)textureDesc.Height;
6012
pTextureContainer->header.info.layerCountOrDepth = 1;
6013
pTextureContainer->header.info.levelCount = 1;
6014
pTextureContainer->header.info.type = SDL_GPU_TEXTURETYPE_2D;
6015
pTextureContainer->header.info.usageFlags = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
6016
pTextureContainer->header.info.sampleCount = SDL_GPU_SAMPLECOUNT_1;
6017
pTextureContainer->header.info.format = SwapchainCompositionToSDLTextureFormat[composition];
6019
pTextureContainer->debugName = NULL;
6020
pTextureContainer->textures = (D3D12Texture **)SDL_calloc(1, sizeof(D3D12Texture *));
6021
if (!pTextureContainer->textures) {
6022
SDL_free(pTexture->subresources);
6024
ID3D12Resource_Release(swapchainTexture);
6028
pTextureContainer->textureCapacity = 1;
6029
pTextureContainer->textureCount = 1;
6030
pTextureContainer->textures[0] = pTexture;
6031
pTextureContainer->activeTexture = pTexture;
6032
pTextureContainer->canBeCycled = false;
6034
pTexture->container = pTextureContainer;
6035
pTexture->containerIndex = 0;
6038
D3D12_INTERNAL_AssignCpuDescriptorHandle(
6040
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
6041
&pTexture->srvHandle);
6043
srvDesc.Format = SwapchainCompositionToTextureFormat[composition];
6044
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
6045
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
6046
srvDesc.Texture2D.MipLevels = 1;
6047
srvDesc.Texture2D.MostDetailedMip = 0;
6048
srvDesc.Texture2D.ResourceMinLODClamp = 0;
6049
srvDesc.Texture2D.PlaneSlice = 0;
6051
ID3D12Device_CreateShaderResourceView(
6055
pTexture->srvHandle.cpuHandle);
6058
D3D12_INTERNAL_AssignCpuDescriptorHandle(
6060
D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
6061
&pTexture->subresources[0].rtvHandles[0]);
6063
rtvDesc.Format = (composition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : swapchainFormat;
6064
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
6065
rtvDesc.Texture2D.MipSlice = 0;
6066
rtvDesc.Texture2D.PlaneSlice = 0;
6068
ID3D12Device_CreateRenderTargetView(
6072
pTexture->subresources[0].rtvHandles[0].cpuHandle);
6074
ID3D12Resource_Release(swapchainTexture);
6079
static bool D3D12_INTERNAL_ResizeSwapchainIfNeeded(
6080
D3D12Renderer *renderer,
6081
D3D12WindowData *windowData)
6083
DXGI_SWAP_CHAIN_DESC swapchainDesc;
6086
IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
6087
SDL_GetWindowSize(windowData->window, &w, &h);
6089
if (w != swapchainDesc.BufferDesc.Width || h != swapchainDesc.BufferDesc.Height) {
6091
D3D12_Wait((SDL_GPURenderer *)renderer);
6094
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6095
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
6097
&windowData->textureContainers[i].activeTexture->srvHandle);
6098
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
6100
&windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]);
6102
SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles);
6103
SDL_free(windowData->textureContainers[i].activeTexture->subresources);
6104
SDL_free(windowData->textureContainers[i].activeTexture);
6105
SDL_free(windowData->textureContainers[i].textures);
6109
HRESULT res = IDXGISwapChain_ResizeBuffers(
6110
windowData->swapchain,
6114
DXGI_FORMAT_UNKNOWN,
6115
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
6116
ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0)
6119
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6120
if (!D3D12_INTERNAL_InitializeSwapchainTexture(
6122
windowData->swapchain,
6123
windowData->swapchainComposition,
6125
&windowData->textureContainers[i])) {
6134
static void D3D12_INTERNAL_DestroySwapchain(
6135
D3D12Renderer *renderer,
6136
D3D12WindowData *windowData)
6139
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6140
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
6142
&windowData->textureContainers[i].activeTexture->srvHandle);
6143
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
6145
&windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]);
6147
SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles);
6148
SDL_free(windowData->textureContainers[i].activeTexture->subresources);
6149
SDL_free(windowData->textureContainers[i].activeTexture);
6150
SDL_free(windowData->textureContainers[i].textures);
6153
IDXGISwapChain_Release(windowData->swapchain);
6154
windowData->swapchain = NULL;
6157
static bool D3D12_INTERNAL_CreateSwapchain(
6158
D3D12Renderer *renderer,
6159
D3D12WindowData *windowData,
6160
SDL_GPUSwapchainComposition swapchainComposition,
6161
SDL_GPUPresentMode presentMode)
6165
DXGI_SWAP_CHAIN_DESC1 swapchainDesc;
6166
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc;
6167
DXGI_FORMAT swapchainFormat;
6168
IDXGIFactory1 *pParent;
6169
IDXGISwapChain1 *swapchain;
6170
IDXGISwapChain3 *swapchain3;
6175
dxgiHandle = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(windowData->window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
6177
dxgiHandle = (HWND)windowData->window;
6181
SDL_GetWindowSize(windowData->window, &width, &height);
6183
swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition];
6186
swapchainDesc.Width = 0;
6187
swapchainDesc.Height = 0;
6188
swapchainDesc.Format = swapchainFormat;
6189
swapchainDesc.SampleDesc.Count = 1;
6190
swapchainDesc.SampleDesc.Quality = 0;
6191
swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
6192
swapchainDesc.BufferCount = MAX_FRAMES_IN_FLIGHT;
6193
swapchainDesc.Scaling = DXGI_SCALING_STRETCH;
6194
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
6195
swapchainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
6196
swapchainDesc.Flags = 0;
6197
swapchainDesc.Stereo = 0;
6200
fullscreenDesc.RefreshRate.Numerator = 0;
6201
fullscreenDesc.RefreshRate.Denominator = 0;
6202
fullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
6203
fullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
6204
fullscreenDesc.Windowed = true;
6206
if (renderer->supportsTearing) {
6207
swapchainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
6209
swapchainDesc.Flags = 0;
6212
#ifndef SDL_PLATFORM_WINRT
6213
if (!IsWindow(dxgiHandle)) {
6219
res = IDXGIFactory4_CreateSwapChainForHwnd(
6221
(IUnknown *)renderer->commandQueue,
6227
ERROR_CHECK_RETURN("Could not create swapchain", 0);
6229
res = IDXGISwapChain1_QueryInterface(
6231
D3D_GUID(D3D_IID_IDXGISwapChain3),
6232
(void **)&swapchain3);
6233
IDXGISwapChain1_Release(swapchain);
6234
ERROR_CHECK_RETURN("Could not create IDXGISwapChain3", 0);
6236
if (swapchainComposition != SDL_GPU_SWAPCHAINCOMPOSITION_SDR) {
6238
IDXGISwapChain3_SetColorSpace1(
6240
SwapchainCompositionToColorSpace[swapchainComposition]);
6250
res = IDXGISwapChain3_GetParent(
6252
D3D_GUID(D3D_IID_IDXGIFactory1),
6256
SDL_LOG_CATEGORY_APPLICATION,
6257
"Could not get swapchain parent! Error Code: " HRESULT_FMT,
6261
res = IDXGIFactory1_MakeWindowAssociation(
6264
DXGI_MWA_NO_WINDOW_CHANGES);
6267
SDL_LOG_CATEGORY_APPLICATION,
6268
"MakeWindowAssociation failed! Error Code: " HRESULT_FMT,
6273
IDXGIFactory1_Release(pParent);
6277
windowData->swapchain = swapchain3;
6278
windowData->presentMode = presentMode;
6279
windowData->swapchainComposition = swapchainComposition;
6280
windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition];
6281
windowData->frameCounter = 0;
6284
for (Uint32 i = 0; i < 4; i += 1) {
6285
SDL_GPU_FetchBlitPipeline(
6286
renderer->sdlGPUDevice,
6287
(SDL_GPUTextureType)i,
6288
SwapchainCompositionToSDLTextureFormat[swapchainComposition],
6289
renderer->blitVertexShader,
6290
renderer->blitFrom2DShader,
6291
renderer->blitFrom2DArrayShader,
6292
renderer->blitFrom3DShader,
6293
renderer->blitFromCubeShader,
6294
&renderer->blitPipelines,
6295
&renderer->blitPipelineCount,
6296
&renderer->blitPipelineCapacity);
6302
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6303
if (!D3D12_INTERNAL_InitializeSwapchainTexture(
6306
swapchainComposition,
6308
&windowData->textureContainers[i])) {
6309
IDXGISwapChain3_Release(swapchain3);
6318
static bool D3D12_ClaimWindow(
6319
SDL_GPURenderer *driverData,
6322
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6323
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6325
if (windowData == NULL) {
6326
windowData = (D3D12WindowData *)SDL_calloc(1, sizeof(D3D12WindowData));
6330
windowData->window = window;
6332
if (D3D12_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) {
6333
SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);
6335
SDL_LockMutex(renderer->windowLock);
6337
if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) {
6338
renderer->claimedWindowCapacity *= 2;
6339
renderer->claimedWindows = (D3D12WindowData **)SDL_realloc(
6340
renderer->claimedWindows,
6341
renderer->claimedWindowCapacity * sizeof(D3D12WindowData *));
6343
renderer->claimedWindows[renderer->claimedWindowCount] = windowData;
6344
renderer->claimedWindowCount += 1;
6346
SDL_UnlockMutex(renderer->windowLock);
6350
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create swapchain, failed to claim window!");
6351
SDL_free(windowData);
6355
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Window already claimed!");
6360
static void D3D12_ReleaseWindow(
6361
SDL_GPURenderer *driverData,
6364
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6365
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6367
if (windowData == NULL) {
6368
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Window already unclaimed!");
6372
D3D12_Wait(driverData);
6374
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6375
if (windowData->inFlightFences[i] != NULL) {
6378
(SDL_GPUFence *)windowData->inFlightFences[i]);
6379
windowData->inFlightFences[i] = NULL;
6383
D3D12_INTERNAL_DestroySwapchain(renderer, windowData);
6385
SDL_LockMutex(renderer->windowLock);
6386
for (Uint32 i = 0; i < renderer->claimedWindowCount; i += 1) {
6387
if (renderer->claimedWindows[i]->window == window) {
6388
renderer->claimedWindows[i] = renderer->claimedWindows[renderer->claimedWindowCount - 1];
6389
renderer->claimedWindowCount -= 1;
6393
SDL_UnlockMutex(renderer->windowLock);
6395
SDL_free(windowData);
6396
SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA);
6399
static bool D3D12_SetSwapchainParameters(
6400
SDL_GPURenderer *driverData,
6402
SDL_GPUSwapchainComposition swapchainComposition,
6403
SDL_GPUPresentMode presentMode)
6405
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6406
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6408
if (windowData == NULL) {
6409
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot set swapchain parameters on unclaimed window!");
6413
if (!D3D12_SupportsSwapchainComposition(driverData, window, swapchainComposition)) {
6414
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Swapchain composition not supported!");
6418
if (!D3D12_SupportsPresentMode(driverData, window, presentMode)) {
6419
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Present mode not supported!");
6424
swapchainComposition != windowData->swapchainComposition ||
6425
presentMode != windowData->presentMode) {
6426
D3D12_Wait(driverData);
6429
D3D12_INTERNAL_DestroySwapchain(
6433
return D3D12_INTERNAL_CreateSwapchain(
6436
swapchainComposition,
6443
static SDL_GPUTextureFormat D3D12_GetSwapchainTextureFormat(
6444
SDL_GPURenderer *driverData,
6447
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6449
if (windowData == NULL) {
6450
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot get swapchain format, window has not been claimed!");
6451
return SDL_GPU_TEXTUREFORMAT_INVALID;
6454
return windowData->textureContainers[windowData->frameCounter].header.info.format;
6457
static D3D12Fence *D3D12_INTERNAL_AcquireFence(
6458
D3D12Renderer *renderer)
6461
ID3D12Fence *handle;
6464
SDL_LockMutex(renderer->fenceLock);
6466
if (renderer->availableFenceCount == 0) {
6467
res = ID3D12Device_CreateFence(
6469
D3D12_FENCE_UNSIGNALED_VALUE,
6470
D3D12_FENCE_FLAG_NONE,
6471
D3D_GUID(D3D_IID_ID3D12Fence),
6474
D3D12_INTERNAL_LogError(renderer->device, "Failed to create fence!", res);
6475
SDL_UnlockMutex(renderer->fenceLock);
6479
fence = (D3D12Fence *)SDL_calloc(1, sizeof(D3D12Fence));
6481
ID3D12Fence_Release(handle);
6482
SDL_UnlockMutex(renderer->fenceLock);
6485
fence->handle = handle;
6486
fence->event = CreateEventEx(NULL, 0, 0, EVENT_ALL_ACCESS);
6487
SDL_AtomicSet(&fence->referenceCount, 0);
6489
fence = renderer->availableFences[renderer->availableFenceCount - 1];
6490
renderer->availableFenceCount -= 1;
6491
ID3D12Fence_Signal(fence->handle, D3D12_FENCE_UNSIGNALED_VALUE);
6494
SDL_UnlockMutex(renderer->fenceLock);
6496
(void)SDL_AtomicIncRef(&fence->referenceCount);
6500
static void D3D12_INTERNAL_AllocateCommandBuffer(
6501
D3D12Renderer *renderer)
6503
D3D12CommandBuffer *commandBuffer;
6505
ID3D12CommandAllocator *commandAllocator;
6506
ID3D12GraphicsCommandList *commandList;
6508
commandBuffer = (D3D12CommandBuffer *)SDL_calloc(1, sizeof(D3D12CommandBuffer));
6509
if (!commandBuffer) {
6510
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create ID3D12CommandList. Out of Memory");
6514
res = ID3D12Device_CreateCommandAllocator(
6516
D3D12_COMMAND_LIST_TYPE_DIRECT,
6517
D3D_GUID(D3D_IID_ID3D12CommandAllocator),
6518
(void **)&commandAllocator);
6520
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create ID3D12CommandAllocator");
6521
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6524
commandBuffer->commandAllocator = commandAllocator;
6526
res = ID3D12Device_CreateCommandList(
6529
D3D12_COMMAND_LIST_TYPE_DIRECT,
6532
D3D_GUID(D3D_IID_ID3D12GraphicsCommandList),
6533
(void **)&commandList);
6536
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create ID3D12CommandList");
6537
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6540
commandBuffer->graphicsCommandList = commandList;
6542
commandBuffer->renderer = renderer;
6543
commandBuffer->inFlightFence = NULL;
6546
commandBuffer->presentDataCapacity = 1;
6547
commandBuffer->presentDataCount = 0;
6548
commandBuffer->presentDatas = (D3D12PresentData *)SDL_calloc(
6549
commandBuffer->presentDataCapacity, sizeof(D3D12PresentData));
6552
commandBuffer->usedTextureCapacity = 4;
6553
commandBuffer->usedTextureCount = 0;
6554
commandBuffer->usedTextures = (D3D12Texture **)SDL_calloc(
6555
commandBuffer->usedTextureCapacity, sizeof(D3D12Texture *));
6557
commandBuffer->usedBufferCapacity = 4;
6558
commandBuffer->usedBufferCount = 0;
6559
commandBuffer->usedBuffers = (D3D12Buffer **)SDL_calloc(
6560
commandBuffer->usedBufferCapacity, sizeof(D3D12Buffer *));
6562
commandBuffer->usedSamplerCapacity = 4;
6563
commandBuffer->usedSamplerCount = 0;
6564
commandBuffer->usedSamplers = (D3D12Sampler **)SDL_calloc(
6565
commandBuffer->usedSamplerCapacity, sizeof(D3D12Sampler *));
6567
commandBuffer->usedGraphicsPipelineCapacity = 4;
6568
commandBuffer->usedGraphicsPipelineCount = 0;
6569
commandBuffer->usedGraphicsPipelines = (D3D12GraphicsPipeline **)SDL_calloc(
6570
commandBuffer->usedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline *));
6572
commandBuffer->usedComputePipelineCapacity = 4;
6573
commandBuffer->usedComputePipelineCount = 0;
6574
commandBuffer->usedComputePipelines = (D3D12ComputePipeline **)SDL_calloc(
6575
commandBuffer->usedComputePipelineCapacity, sizeof(D3D12ComputePipeline *));
6577
commandBuffer->usedUniformBufferCapacity = 4;
6578
commandBuffer->usedUniformBufferCount = 0;
6579
commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_calloc(
6580
commandBuffer->usedUniformBufferCapacity, sizeof(D3D12UniformBuffer *));
6582
commandBuffer->textureDownloadCapacity = 4;
6583
commandBuffer->textureDownloadCount = 0;
6584
commandBuffer->textureDownloads = (D3D12TextureDownload **)SDL_calloc(
6585
commandBuffer->textureDownloadCapacity, sizeof(D3D12TextureDownload *));
6588
(!commandBuffer->presentDatas) ||
6589
(!commandBuffer->usedTextures) ||
6590
(!commandBuffer->usedBuffers) ||
6591
(!commandBuffer->usedSamplers) ||
6592
(!commandBuffer->usedGraphicsPipelines) ||
6593
(!commandBuffer->usedComputePipelines) ||
6594
(!commandBuffer->usedUniformBuffers) ||
6595
(!commandBuffer->textureDownloads)) {
6596
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create ID3D12CommandList. Out of Memory");
6597
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6601
D3D12CommandBuffer **resizedAvailableCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
6602
renderer->availableCommandBuffers,
6603
sizeof(D3D12CommandBuffer *) * (renderer->availableCommandBufferCapacity + 1));
6605
if (!resizedAvailableCommandBuffers) {
6606
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create ID3D12CommandList. Out of Memory");
6607
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6611
renderer->availableCommandBufferCapacity += 1;
6612
renderer->availableCommandBuffers = resizedAvailableCommandBuffers;
6614
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
6615
renderer->availableCommandBufferCount += 1;
6618
static D3D12CommandBuffer *D3D12_INTERNAL_AcquireCommandBufferFromPool(
6619
D3D12Renderer *renderer)
6621
D3D12CommandBuffer *commandBuffer;
6623
if (renderer->availableCommandBufferCount == 0) {
6624
D3D12_INTERNAL_AllocateCommandBuffer(renderer);
6627
commandBuffer = renderer->availableCommandBuffers[renderer->availableCommandBufferCount - 1];
6628
renderer->availableCommandBufferCount -= 1;
6630
return commandBuffer;
6633
static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
6634
SDL_GPURenderer *driverData)
6636
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6637
D3D12CommandBuffer *commandBuffer;
6638
ID3D12DescriptorHeap *heaps[2];
6641
SDL_LockMutex(renderer->acquireCommandBufferLock);
6642
commandBuffer = D3D12_INTERNAL_AcquireCommandBufferFromPool(renderer);
6643
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
6645
if (commandBuffer == NULL) {
6646
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire command buffer!");
6651
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] =
6652
D3D12_INTERNAL_AcquireDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
6654
if (!commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]) {
6655
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire descriptor heap!");
6656
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6660
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] =
6661
D3D12_INTERNAL_AcquireDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
6663
if (!commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]) {
6664
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire descriptor heap!");
6665
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
6669
heaps[0] = commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]->handle;
6670
heaps[1] = commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]->handle;
6672
ID3D12GraphicsCommandList_SetDescriptorHeaps(
6673
commandBuffer->graphicsCommandList,
6678
commandBuffer->currentGraphicsPipeline = NULL;
6680
SDL_zeroa(commandBuffer->colorAttachmentTextureSubresources);
6681
commandBuffer->colorAttachmentTextureSubresourceCount = 0;
6682
commandBuffer->depthStencilTextureSubresource = NULL;
6684
SDL_zeroa(commandBuffer->vertexBuffers);
6685
SDL_zeroa(commandBuffer->vertexBufferOffsets);
6686
commandBuffer->vertexBufferCount = 0;
6688
SDL_zeroa(commandBuffer->vertexSamplerTextures);
6689
SDL_zeroa(commandBuffer->vertexSamplers);
6690
SDL_zeroa(commandBuffer->vertexStorageTextures);
6691
SDL_zeroa(commandBuffer->vertexStorageBuffers);
6692
SDL_zeroa(commandBuffer->vertexUniformBuffers);
6694
SDL_zeroa(commandBuffer->fragmentSamplerTextures);
6695
SDL_zeroa(commandBuffer->fragmentSamplers);
6696
SDL_zeroa(commandBuffer->fragmentStorageTextures);
6697
SDL_zeroa(commandBuffer->fragmentStorageBuffers);
6698
SDL_zeroa(commandBuffer->fragmentUniformBuffers);
6700
SDL_zeroa(commandBuffer->computeReadOnlyStorageTextures);
6701
SDL_zeroa(commandBuffer->computeReadOnlyStorageBuffers);
6702
SDL_zeroa(commandBuffer->computeWriteOnlyStorageTextureSubresources);
6703
SDL_zeroa(commandBuffer->computeWriteOnlyStorageBuffers);
6704
SDL_zeroa(commandBuffer->computeUniformBuffers);
6706
commandBuffer->autoReleaseFence = true;
6708
return (SDL_GPUCommandBuffer *)commandBuffer;
6711
static SDL_GPUTexture *D3D12_AcquireSwapchainTexture(
6712
SDL_GPUCommandBuffer *commandBuffer,
6717
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6718
D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
6719
D3D12WindowData *windowData;
6720
Uint32 swapchainIndex;
6723
windowData = D3D12_INTERNAL_FetchWindowData(window);
6724
if (windowData == NULL) {
6728
res = D3D12_INTERNAL_ResizeSwapchainIfNeeded(
6731
ERROR_CHECK_RETURN("Could not resize swapchain", NULL);
6733
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
6734
if (windowData->presentMode == SDL_GPU_PRESENTMODE_VSYNC) {
6736
D3D12_WaitForFences(
6737
(SDL_GPURenderer *)renderer,
6739
(SDL_GPUFence **)&windowData->inFlightFences[windowData->frameCounter],
6742
if (!D3D12_QueryFence(
6743
(SDL_GPURenderer *)renderer,
6744
(SDL_GPUFence *)windowData->inFlightFences[windowData->frameCounter])) {
6754
(SDL_GPURenderer *)renderer,
6755
(SDL_GPUFence *)windowData->inFlightFences[windowData->frameCounter]);
6757
windowData->inFlightFences[windowData->frameCounter] = NULL;
6760
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
6762
windowData->frameToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
6763
renderer->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, NULL, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &windowData->frameToken);
6764
swapchainIndex = windowData->frameCounter;
6766
swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->swapchain);
6769
res = IDXGISwapChain_GetBuffer(
6770
windowData->swapchain,
6772
D3D_GUID(D3D_IID_ID3D12Resource),
6773
(void **)&windowData->textureContainers[swapchainIndex].activeTexture->resource);
6774
ERROR_CHECK_RETURN("Could not acquire swapchain!", NULL);
6778
*pWidth = windowData->textureContainers[swapchainIndex].header.info.width;
6779
*pHeight = windowData->textureContainers[swapchainIndex].header.info.height;
6782
if (d3d12CommandBuffer->presentDataCount == d3d12CommandBuffer->presentDataCapacity) {
6783
d3d12CommandBuffer->presentDataCapacity += 1;
6784
d3d12CommandBuffer->presentDatas = (D3D12PresentData *)SDL_realloc(
6785
d3d12CommandBuffer->presentDatas,
6786
d3d12CommandBuffer->presentDataCapacity * sizeof(D3D12PresentData));
6788
d3d12CommandBuffer->presentDatas[d3d12CommandBuffer->presentDataCount].windowData = windowData;
6789
d3d12CommandBuffer->presentDatas[d3d12CommandBuffer->presentDataCount].swapchainImageIndex = swapchainIndex;
6790
d3d12CommandBuffer->presentDataCount += 1;
6793
D3D12_RESOURCE_BARRIER barrierDesc;
6794
barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
6795
barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
6796
barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
6797
barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
6798
barrierDesc.Transition.pResource = windowData->textureContainers[swapchainIndex].activeTexture->resource;
6799
barrierDesc.Transition.Subresource = 0;
6801
ID3D12GraphicsCommandList_ResourceBarrier(
6802
d3d12CommandBuffer->graphicsCommandList,
6806
return (SDL_GPUTexture *)&windowData->textureContainers[swapchainIndex];
6809
static void D3D12_INTERNAL_PerformPendingDestroys(D3D12Renderer *renderer)
6811
SDL_LockMutex(renderer->disposeLock);
6813
for (Sint32 i = renderer->buffersToDestroyCount - 1; i >= 0; i -= 1) {
6814
if (SDL_AtomicGet(&renderer->buffersToDestroy[i]->referenceCount) == 0) {
6815
D3D12_INTERNAL_DestroyBuffer(
6817
renderer->buffersToDestroy[i]);
6819
renderer->buffersToDestroy[i] = renderer->buffersToDestroy[renderer->buffersToDestroyCount - 1];
6820
renderer->buffersToDestroyCount -= 1;
6824
for (Sint32 i = renderer->texturesToDestroyCount - 1; i >= 0; i -= 1) {
6825
if (SDL_AtomicGet(&renderer->texturesToDestroy[i]->referenceCount) == 0) {
6826
D3D12_INTERNAL_DestroyTexture(
6828
renderer->texturesToDestroy[i]);
6830
renderer->texturesToDestroy[i] = renderer->texturesToDestroy[renderer->texturesToDestroyCount - 1];
6831
renderer->texturesToDestroyCount -= 1;
6835
for (Sint32 i = renderer->samplersToDestroyCount - 1; i >= 0; i -= 1) {
6836
if (SDL_AtomicGet(&renderer->samplersToDestroy[i]->referenceCount) == 0) {
6837
D3D12_INTERNAL_DestroySampler(
6839
renderer->samplersToDestroy[i]);
6841
renderer->samplersToDestroy[i] = renderer->samplersToDestroy[renderer->samplersToDestroyCount - 1];
6842
renderer->samplersToDestroyCount -= 1;
6846
for (Sint32 i = renderer->graphicsPipelinesToDestroyCount - 1; i >= 0; i -= 1) {
6847
if (SDL_AtomicGet(&renderer->graphicsPipelinesToDestroy[i]->referenceCount) == 0) {
6848
D3D12_INTERNAL_DestroyGraphicsPipeline(
6849
renderer->graphicsPipelinesToDestroy[i]);
6851
renderer->graphicsPipelinesToDestroy[i] = renderer->graphicsPipelinesToDestroy[renderer->graphicsPipelinesToDestroyCount - 1];
6852
renderer->graphicsPipelinesToDestroyCount -= 1;
6856
for (Sint32 i = renderer->computePipelinesToDestroyCount - 1; i >= 0; i -= 1) {
6857
if (SDL_AtomicGet(&renderer->computePipelinesToDestroy[i]->referenceCount) == 0) {
6858
D3D12_INTERNAL_DestroyComputePipeline(
6859
renderer->computePipelinesToDestroy[i]);
6861
renderer->computePipelinesToDestroy[i] = renderer->computePipelinesToDestroy[renderer->computePipelinesToDestroyCount - 1];
6862
renderer->computePipelinesToDestroyCount -= 1;
6866
SDL_UnlockMutex(renderer->disposeLock);
6869
static void D3D12_INTERNAL_CopyTextureDownload(
6870
D3D12CommandBuffer *commandBuffer,
6871
D3D12TextureDownload *download)
6877
res = ID3D12Resource_Map(
6878
download->temporaryBuffer->handle,
6881
(void **)&sourcePtr);
6884
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to map temporary buffer!");
6888
res = ID3D12Resource_Map(
6889
download->destinationBuffer->handle,
6895
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to map destination buffer!");
6899
for (Uint32 sliceIndex = 0; sliceIndex < download->depth; sliceIndex += 1) {
6900
for (Uint32 rowIndex = 0; rowIndex < download->height; rowIndex += 1) {
6902
destPtr + download->bufferOffset + (sliceIndex * download->bytesPerDepthSlice) + (rowIndex * download->bytesPerRow),
6903
sourcePtr + (sliceIndex * download->height) + (rowIndex * download->alignedBytesPerRow),
6904
download->bytesPerRow);
6908
ID3D12Resource_Unmap(
6909
download->temporaryBuffer->handle,
6913
ID3D12Resource_Unmap(
6914
download->destinationBuffer->handle,
6919
static void D3D12_INTERNAL_CleanCommandBuffer(
6920
D3D12Renderer *renderer,
6921
D3D12CommandBuffer *commandBuffer)
6928
for (i = 0; i < commandBuffer->textureDownloadCount; i += 1) {
6929
D3D12_INTERNAL_CopyTextureDownload(
6931
commandBuffer->textureDownloads[i]);
6932
SDL_free(commandBuffer->textureDownloads[i]);
6934
commandBuffer->textureDownloadCount = 0;
6936
res = ID3D12CommandAllocator_Reset(commandBuffer->commandAllocator);
6937
ERROR_CHECK("Could not reset command allocator")
6939
res = ID3D12GraphicsCommandList_Reset(
6940
commandBuffer->graphicsCommandList,
6941
commandBuffer->commandAllocator,
6943
ERROR_CHECK("Could not reset graphicsCommandList")
6946
D3D12_INTERNAL_ReturnDescriptorHeapToPool(
6948
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]);
6949
D3D12_INTERNAL_ReturnDescriptorHeapToPool(
6951
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]);
6954
SDL_LockMutex(renderer->acquireUniformBufferLock);
6956
for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
6957
D3D12_INTERNAL_ReturnUniformBufferToPool(
6959
commandBuffer->usedUniformBuffers[i]);
6961
commandBuffer->usedUniformBufferCount = 0;
6963
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
6967
for (i = 0; i < commandBuffer->usedTextureCount; i += 1) {
6968
(void)SDL_AtomicDecRef(&commandBuffer->usedTextures[i]->referenceCount);
6970
commandBuffer->usedTextureCount = 0;
6972
for (i = 0; i < commandBuffer->usedBufferCount; i += 1) {
6973
(void)SDL_AtomicDecRef(&commandBuffer->usedBuffers[i]->referenceCount);
6975
commandBuffer->usedBufferCount = 0;
6977
for (i = 0; i < commandBuffer->usedSamplerCount; i += 1) {
6978
(void)SDL_AtomicDecRef(&commandBuffer->usedSamplers[i]->referenceCount);
6980
commandBuffer->usedSamplerCount = 0;
6982
for (i = 0; i < commandBuffer->usedGraphicsPipelineCount; i += 1) {
6983
(void)SDL_AtomicDecRef(&commandBuffer->usedGraphicsPipelines[i]->referenceCount);
6985
commandBuffer->usedGraphicsPipelineCount = 0;
6987
for (i = 0; i < commandBuffer->usedComputePipelineCount; i += 1) {
6988
(void)SDL_AtomicDecRef(&commandBuffer->usedComputePipelines[i]->referenceCount);
6990
commandBuffer->usedComputePipelineCount = 0;
6993
commandBuffer->presentDataCount = 0;
6996
if (commandBuffer->autoReleaseFence) {
6998
(SDL_GPURenderer *)renderer,
6999
(SDL_GPUFence *)commandBuffer->inFlightFence);
7001
commandBuffer->inFlightFence = NULL;
7005
SDL_LockMutex(renderer->acquireCommandBufferLock);
7007
if (renderer->availableCommandBufferCount == renderer->availableCommandBufferCapacity) {
7008
renderer->availableCommandBufferCapacity += 1;
7009
renderer->availableCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
7010
renderer->availableCommandBuffers,
7011
renderer->availableCommandBufferCapacity * sizeof(D3D12CommandBuffer *));
7014
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
7015
renderer->availableCommandBufferCount += 1;
7017
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
7020
for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) {
7021
if (renderer->submittedCommandBuffers[i] == commandBuffer) {
7022
renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1];
7023
renderer->submittedCommandBufferCount -= 1;
7028
static void D3D12_Submit(
7029
SDL_GPUCommandBuffer *commandBuffer)
7031
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7032
D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
7033
ID3D12CommandList *commandLists[1];
7036
SDL_LockMutex(renderer->submitLock);
7039
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
7040
if (d3d12CommandBuffer->vertexUniformBuffers[i] != NULL) {
7041
ID3D12Resource_Unmap(
7042
d3d12CommandBuffer->vertexUniformBuffers[i]->buffer->handle,
7045
d3d12CommandBuffer->vertexUniformBuffers[i]->buffer->mapPointer = NULL;
7048
if (d3d12CommandBuffer->fragmentUniformBuffers[i] != NULL) {
7049
ID3D12Resource_Unmap(
7050
d3d12CommandBuffer->fragmentUniformBuffers[i]->buffer->handle,
7053
d3d12CommandBuffer->fragmentUniformBuffers[i]->buffer->mapPointer = NULL;
7060
for (Uint32 i = 0; i < d3d12CommandBuffer->presentDataCount; i += 1) {
7061
Uint32 swapchainIndex = d3d12CommandBuffer->presentDatas[i].swapchainImageIndex;
7062
D3D12TextureContainer *container = &d3d12CommandBuffer->presentDatas[i].windowData->textureContainers[swapchainIndex];
7063
D3D12TextureSubresource *subresource = D3D12_INTERNAL_FetchTextureSubresource(container, 0, 0);
7065
D3D12_RESOURCE_BARRIER barrierDesc;
7066
barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7067
barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7068
barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
7069
barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
7070
barrierDesc.Transition.pResource = subresource->parent->resource;
7071
barrierDesc.Transition.Subresource = subresource->index;
7073
ID3D12GraphicsCommandList_ResourceBarrier(
7074
d3d12CommandBuffer->graphicsCommandList,
7080
res = ID3D12GraphicsCommandList_Close(d3d12CommandBuffer->graphicsCommandList);
7081
ERROR_CHECK("Failed to close command list!");
7083
res = ID3D12GraphicsCommandList_QueryInterface(
7084
d3d12CommandBuffer->graphicsCommandList,
7085
D3D_GUID(D3D_IID_ID3D12CommandList),
7086
(void **)&commandLists[0]);
7087
ERROR_CHECK("Failed to convert command list!")
7090
ID3D12CommandQueue_ExecuteCommandLists(
7091
renderer->commandQueue,
7095
ID3D12CommandList_Release(commandLists[0]);
7098
d3d12CommandBuffer->inFlightFence = D3D12_INTERNAL_AcquireFence(renderer);
7099
if (!d3d12CommandBuffer->inFlightFence) {
7100
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire fence.");
7104
res = ID3D12CommandQueue_Signal(
7105
renderer->commandQueue,
7106
d3d12CommandBuffer->inFlightFence->handle,
7107
D3D12_FENCE_SIGNAL_VALUE);
7108
ERROR_CHECK("Failed to enqueue fence signal!");
7111
if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity) {
7112
renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
7114
renderer->submittedCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
7115
renderer->submittedCommandBuffers,
7116
sizeof(D3D12CommandBuffer *) * renderer->submittedCommandBufferCapacity);
7119
renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = d3d12CommandBuffer;
7120
renderer->submittedCommandBufferCount += 1;
7123
for (Uint32 i = 0; i < d3d12CommandBuffer->presentDataCount; i += 1) {
7124
D3D12PresentData *presentData = &d3d12CommandBuffer->presentDatas[i];
7125
D3D12WindowData *windowData = presentData->windowData;
7127
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
7128
D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParams;
7129
SDL_zero(planeParams);
7130
planeParams.Token = windowData->frameToken;
7131
planeParams.ResourceCount = 1;
7132
planeParams.ppResources = &windowData->textureContainers[windowData->frameCounter].activeTexture->resource;
7133
planeParams.ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
7135
D3D12XBOX_PRESENT_PARAMETERS presentParams;
7136
SDL_zero(presentParams);
7137
presentParams.Flags = (windowData->presentMode == SDL_GPU_PRESENTMODE_IMMEDIATE) ? D3D12XBOX_PRESENT_FLAG_IMMEDIATE : D3D12XBOX_PRESENT_FLAG_NONE;
7139
renderer->commandQueue->PresentX(1, &planeParams, &presentParams);
7142
Uint32 syncInterval = 1;
7143
if (windowData->presentMode == SDL_GPU_PRESENTMODE_IMMEDIATE ||
7144
windowData->presentMode == SDL_GPU_PRESENTMODE_MAILBOX) {
7148
Uint32 presentFlags = 0;
7149
if (renderer->supportsTearing &&
7150
windowData->presentMode == SDL_GPU_PRESENTMODE_IMMEDIATE) {
7151
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
7154
IDXGISwapChain_Present(
7155
windowData->swapchain,
7159
ID3D12Resource_Release(windowData->textureContainers[presentData->swapchainImageIndex].activeTexture->resource);
7162
windowData->inFlightFences[windowData->frameCounter] = d3d12CommandBuffer->inFlightFence;
7163
(void)SDL_AtomicIncRef(&d3d12CommandBuffer->inFlightFence->referenceCount);
7164
windowData->frameCounter = (windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
7168
for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7169
Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
7170
renderer->submittedCommandBuffers[i]->inFlightFence->handle);
7172
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
7173
D3D12_INTERNAL_CleanCommandBuffer(
7175
renderer->submittedCommandBuffers[i]);
7179
D3D12_INTERNAL_PerformPendingDestroys(renderer);
7181
SDL_UnlockMutex(renderer->submitLock);
7184
static SDL_GPUFence *D3D12_SubmitAndAcquireFence(
7185
SDL_GPUCommandBuffer *commandBuffer)
7187
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7188
d3d12CommandBuffer->autoReleaseFence = false;
7189
D3D12_Submit(commandBuffer);
7190
return (SDL_GPUFence *)d3d12CommandBuffer->inFlightFence;
7193
static void D3D12_Wait(
7194
SDL_GPURenderer *driverData)
7196
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7197
D3D12Fence *fence = D3D12_INTERNAL_AcquireFence(renderer);
7199
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire fence.");
7204
SDL_LockMutex(renderer->submitLock);
7206
if (renderer->commandQueue) {
7208
ID3D12CommandQueue_Signal(
7209
renderer->commandQueue,
7211
D3D12_FENCE_SIGNAL_VALUE);
7214
if (ID3D12Fence_GetCompletedValue(fence->handle) != D3D12_FENCE_SIGNAL_VALUE) {
7215
res = ID3D12Fence_SetEventOnCompletion(
7217
D3D12_FENCE_SIGNAL_VALUE,
7219
ERROR_CHECK_RETURN("Setting fence event failed", )
7221
WaitForSingleObject(fence->event, INFINITE);
7226
(SDL_GPURenderer *)renderer,
7227
(SDL_GPUFence *)fence);
7230
for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7231
D3D12_INTERNAL_CleanCommandBuffer(renderer, renderer->submittedCommandBuffers[i]);
7234
D3D12_INTERNAL_PerformPendingDestroys(renderer);
7236
SDL_UnlockMutex(renderer->submitLock);
7239
static void D3D12_WaitForFences(
7240
SDL_GPURenderer *driverData,
7242
SDL_GPUFence **pFences,
7245
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7247
HANDLE *events = SDL_stack_alloc(HANDLE, fenceCount);
7250
SDL_LockMutex(renderer->submitLock);
7252
for (Uint32 i = 0; i < fenceCount; i += 1) {
7253
fence = (D3D12Fence *)pFences[i];
7255
res = ID3D12Fence_SetEventOnCompletion(
7257
D3D12_FENCE_SIGNAL_VALUE,
7259
ERROR_CHECK_RETURN("Setting fence event failed", )
7261
events[i] = fence->event;
7264
WaitForMultipleObjects(
7271
for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7272
Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
7273
renderer->submittedCommandBuffers[i]->inFlightFence->handle);
7275
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
7276
D3D12_INTERNAL_CleanCommandBuffer(
7278
renderer->submittedCommandBuffers[i]);
7282
D3D12_INTERNAL_PerformPendingDestroys(renderer);
7284
SDL_stack_free(events);
7286
SDL_UnlockMutex(renderer->submitLock);
7291
static bool D3D12_SupportsTextureFormat(
7292
SDL_GPURenderer *driverData,
7293
SDL_GPUTextureFormat format,
7294
SDL_GPUTextureType type,
7295
SDL_GPUTextureUsageFlags usage)
7297
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7298
DXGI_FORMAT dxgiFormat = SDLToD3D12_TextureFormat[format];
7299
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = { dxgiFormat, D3D12_FORMAT_SUPPORT1_NONE, D3D12_FORMAT_SUPPORT2_NONE };
7302
res = ID3D12Device_CheckFeatureSupport(
7304
D3D12_FEATURE_FORMAT_SUPPORT,
7306
sizeof(formatSupport));
7313
if (type == SDL_GPU_TEXTURETYPE_2D && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) {
7316
if (type == SDL_GPU_TEXTURETYPE_2D_ARRAY && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) {
7319
if (type == SDL_GPU_TEXTURETYPE_3D && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE3D)) {
7322
if (type == SDL_GPU_TEXTURETYPE_CUBE && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE)) {
7327
if ((usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) {
7330
if ((usage & (SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ | SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD)) {
7333
if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) && !(formatSupport.Support2 & D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) {
7336
if ((usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) {
7339
if ((usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)) {
7346
static bool D3D12_SupportsSampleCount(
7347
SDL_GPURenderer *driverData,
7348
SDL_GPUTextureFormat format,
7349
SDL_GPUSampleCount sampleCount)
7351
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7352
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS featureData;
7355
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
7356
featureData.Flags = (D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG)0;
7358
featureData.Flags = (D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS)0;
7360
featureData.Format = SDLToD3D12_TextureFormat[format];
7361
featureData.SampleCount = SDLToD3D12_SampleCount[sampleCount];
7362
res = ID3D12Device_CheckFeatureSupport(
7364
D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
7366
sizeof(featureData));
7368
return SUCCEEDED(res) && featureData.NumQualityLevels > 0;
7371
static void D3D12_INTERNAL_InitBlitResources(
7372
D3D12Renderer *renderer)
7374
SDL_GPUShaderCreateInfo shaderCreateInfo;
7375
SDL_GPUSamplerCreateInfo samplerCreateInfo;
7377
renderer->blitPipelineCapacity = 2;
7378
renderer->blitPipelineCount = 0;
7379
renderer->blitPipelines = (BlitPipelineCacheEntry *)SDL_malloc(
7380
renderer->blitPipelineCapacity * sizeof(BlitPipelineCacheEntry));
7383
SDL_zero(shaderCreateInfo);
7384
shaderCreateInfo.code = (Uint8 *)D3D12_FullscreenVert;
7385
shaderCreateInfo.codeSize = sizeof(D3D12_FullscreenVert);
7386
shaderCreateInfo.stage = SDL_GPU_SHADERSTAGE_VERTEX;
7387
shaderCreateInfo.format = SDL_GPU_SHADERFORMAT_DXBC;
7388
shaderCreateInfo.entryPointName = "main";
7390
renderer->blitVertexShader = D3D12_CreateShader(
7391
(SDL_GPURenderer *)renderer,
7394
if (renderer->blitVertexShader == NULL) {
7395
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile vertex shader for blit!");
7399
shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom2D;
7400
shaderCreateInfo.codeSize = sizeof(D3D12_BlitFrom2D);
7401
shaderCreateInfo.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
7402
shaderCreateInfo.samplerCount = 1;
7403
shaderCreateInfo.uniformBufferCount = 1;
7405
renderer->blitFrom2DShader = D3D12_CreateShader(
7406
(SDL_GPURenderer *)renderer,
7409
if (renderer->blitFrom2DShader == NULL) {
7410
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom2D pixel shader!");
7414
shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom2DArray;
7415
shaderCreateInfo.codeSize = sizeof(D3D12_BlitFrom2DArray);
7417
renderer->blitFrom2DArrayShader = D3D12_CreateShader(
7418
(SDL_GPURenderer *)renderer,
7421
if (renderer->blitFrom2DArrayShader == NULL) {
7422
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom2DArray pixel shader!");
7426
shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom3D;
7427
shaderCreateInfo.codeSize = sizeof(D3D12_BlitFrom3D);
7429
renderer->blitFrom3DShader = D3D12_CreateShader(
7430
(SDL_GPURenderer *)renderer,
7433
if (renderer->blitFrom3DShader == NULL) {
7434
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom3D pixel shader!");
7438
shaderCreateInfo.code = (Uint8 *)D3D12_BlitFromCube;
7439
shaderCreateInfo.codeSize = sizeof(D3D12_BlitFromCube);
7441
renderer->blitFromCubeShader = D3D12_CreateShader(
7442
(SDL_GPURenderer *)renderer,
7445
if (renderer->blitFromCubeShader == NULL) {
7446
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCube pixel shader!");
7450
samplerCreateInfo.addressModeU = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
7451
samplerCreateInfo.addressModeV = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
7452
samplerCreateInfo.addressModeW = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
7453
samplerCreateInfo.anisotropyEnable = 0;
7454
samplerCreateInfo.compareEnable = 0;
7455
samplerCreateInfo.magFilter = SDL_GPU_FILTER_NEAREST;
7456
samplerCreateInfo.minFilter = SDL_GPU_FILTER_NEAREST;
7457
samplerCreateInfo.mipmapMode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
7458
samplerCreateInfo.mipLodBias = 0.0f;
7459
samplerCreateInfo.minLod = 0;
7460
samplerCreateInfo.maxLod = 1000;
7461
samplerCreateInfo.maxAnisotropy = 1.0f;
7462
samplerCreateInfo.compareOp = SDL_GPU_COMPAREOP_ALWAYS;
7464
renderer->blitNearestSampler = D3D12_CreateSampler(
7465
(SDL_GPURenderer *)renderer,
7466
&samplerCreateInfo);
7468
if (renderer->blitNearestSampler == NULL) {
7469
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create blit nearest sampler!");
7472
samplerCreateInfo.magFilter = SDL_GPU_FILTER_LINEAR;
7473
samplerCreateInfo.minFilter = SDL_GPU_FILTER_LINEAR;
7474
samplerCreateInfo.mipmapMode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
7476
renderer->blitLinearSampler = D3D12_CreateSampler(
7477
(SDL_GPURenderer *)renderer,
7478
&samplerCreateInfo);
7480
if (renderer->blitLinearSampler == NULL) {
7481
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create blit linear sampler!");
7485
static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
7487
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
7492
PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc;
7493
PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
7495
ID3D12Device *device;
7496
IDXGIFactory1 *factory;
7497
IDXGIFactory4 *factory4;
7498
IDXGIFactory6 *factory6;
7499
IDXGIAdapter1 *adapter;
7503
d3d12_dll = SDL_LoadObject(D3D12_DLL);
7504
if (d3d12_dll == NULL) {
7505
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not find " D3D12_DLL);
7509
D3D12CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)SDL_LoadFunction(
7511
D3D12_CREATE_DEVICE_FUNC);
7512
if (D3D12CreateDeviceFunc == NULL) {
7513
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not find function " D3D12_CREATE_DEVICE_FUNC " in " D3D12_DLL);
7514
SDL_UnloadObject(d3d12_dll);
7520
dxgi_dll = SDL_LoadObject(DXGI_DLL);
7521
if (dxgi_dll == NULL) {
7522
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not find " DXGI_DLL);
7526
CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1)SDL_LoadFunction(
7528
CREATE_DXGI_FACTORY1_FUNC);
7529
if (CreateDXGIFactoryFunc == NULL) {
7530
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not find function " CREATE_DXGI_FACTORY1_FUNC " in " DXGI_DLL);
7531
SDL_UnloadObject(dxgi_dll);
7538
res = CreateDXGIFactoryFunc(
7539
&D3D_IID_IDXGIFactory1,
7542
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not create DXGIFactory");
7543
SDL_UnloadObject(d3d12_dll);
7544
SDL_UnloadObject(dxgi_dll);
7549
res = IDXGIFactory1_QueryInterface(
7551
D3D_GUID(D3D_IID_IDXGIFactory4),
7552
(void **)&factory4);
7554
IDXGIFactory1_Release(factory);
7555
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Failed to find DXGI1.4 support, required for DX12");
7556
SDL_UnloadObject(d3d12_dll);
7557
SDL_UnloadObject(dxgi_dll);
7560
IDXGIFactory4_Release(factory4);
7562
res = IDXGIFactory1_QueryInterface(
7564
D3D_GUID(D3D_IID_IDXGIFactory6),
7565
(void **)&factory6);
7566
if (SUCCEEDED(res)) {
7567
res = IDXGIFactory6_EnumAdapterByGpuPreference(
7570
DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
7571
D3D_GUID(D3D_IID_IDXGIAdapter1),
7573
IDXGIFactory6_Release(factory6);
7575
res = IDXGIFactory1_EnumAdapters1(
7581
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Failed to find adapter for D3D12Device");
7582
IDXGIFactory1_Release(factory);
7583
SDL_UnloadObject(d3d12_dll);
7584
SDL_UnloadObject(dxgi_dll);
7588
res = D3D12CreateDeviceFunc(
7589
(IUnknown *)adapter,
7590
D3D_FEATURE_LEVEL_CHOICE,
7591
D3D_GUID(D3D_IID_ID3D12Device),
7594
if (SUCCEEDED(res)) {
7595
ID3D12Device_Release(device);
7597
IDXGIAdapter1_Release(adapter);
7598
IDXGIFactory1_Release(factory);
7600
SDL_UnloadObject(d3d12_dll);
7601
SDL_UnloadObject(dxgi_dll);
7604
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR);
7612
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7613
static void D3D12_INTERNAL_TryInitializeDXGIDebug(D3D12Renderer *renderer)
7615
PFN_DXGI_GET_DEBUG_INTERFACE DXGIGetDebugInterfaceFunc;
7618
renderer->dxgidebug_dll = SDL_LoadObject(DXGIDEBUG_DLL);
7619
if (renderer->dxgidebug_dll == NULL) {
7620
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Could not find " DXGIDEBUG_DLL);
7624
DXGIGetDebugInterfaceFunc = (PFN_DXGI_GET_DEBUG_INTERFACE)SDL_LoadFunction(
7625
renderer->dxgidebug_dll,
7626
DXGI_GET_DEBUG_INTERFACE_FUNC);
7627
if (DXGIGetDebugInterfaceFunc == NULL) {
7628
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Could not load function: " DXGI_GET_DEBUG_INTERFACE_FUNC);
7632
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIDebug, (void **)&renderer->dxgiDebug);
7634
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Could not get IDXGIDebug interface");
7637
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIInfoQueue, (void **)&renderer->dxgiInfoQueue);
7639
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Could not get IDXGIInfoQueue interface");
7644
static void D3D12_INTERNAL_TryInitializeD3D12Debug(D3D12Renderer *renderer)
7646
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterfaceFunc;
7649
D3D12GetDebugInterfaceFunc = (PFN_D3D12_GET_DEBUG_INTERFACE)SDL_LoadFunction(
7650
renderer->d3d12_dll,
7651
D3D12_GET_DEBUG_INTERFACE_FUNC);
7652
if (D3D12GetDebugInterfaceFunc == NULL) {
7653
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load function: " D3D12_GET_DEBUG_INTERFACE_FUNC);
7657
res = D3D12GetDebugInterfaceFunc(D3D_GUID(D3D_IID_ID3D12Debug), (void **)&renderer->d3d12Debug);
7659
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Could not get ID3D12Debug interface");
7663
ID3D12Debug_EnableDebugLayer(renderer->d3d12Debug);
7666
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7667
static void D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *renderer)
7669
ID3D12InfoQueue *infoQueue = NULL;
7670
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
7671
D3D12_INFO_QUEUE_FILTER filter;
7674
res = ID3D12Device_QueryInterface(
7676
D3D_GUID(D3D_IID_ID3D12InfoQueue),
7677
(void **)&infoQueue);
7679
ERROR_CHECK_RETURN("Failed to convert ID3D12Device to ID3D12InfoQueue", );
7683
filter.DenyList.NumSeverities = 1;
7684
filter.DenyList.pSeverityList = severities;
7685
ID3D12InfoQueue_PushStorageFilter(
7689
ID3D12InfoQueue_SetBreakOnSeverity(
7691
D3D12_MESSAGE_SEVERITY_ERROR,
7694
ID3D12InfoQueue_SetBreakOnSeverity(
7696
D3D12_MESSAGE_SEVERITY_CORRUPTION,
7699
ID3D12InfoQueue_Release(infoQueue);
7703
static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
7705
SDL_GPUDevice *result;
7706
D3D12Renderer *renderer;
7709
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7710
PFN_D3D12_XBOX_CREATE_DEVICE D3D12XboxCreateDeviceFunc;
7711
D3D12XBOX_CREATE_DEVICE_PARAMETERS createDeviceParams;
7713
PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
7714
IDXGIFactory1 *factory1;
7715
IDXGIFactory5 *factory5;
7716
IDXGIFactory6 *factory6;
7717
DXGI_ADAPTER_DESC1 adapterDesc;
7718
PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc;
7720
D3D12_FEATURE_DATA_ARCHITECTURE architecture;
7721
D3D12_COMMAND_QUEUE_DESC queueDesc;
7723
renderer = (D3D12Renderer *)SDL_calloc(1, sizeof(D3D12Renderer));
7725
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7727
renderer->dxgi_dll = SDL_LoadObject(DXGI_DLL);
7728
if (renderer->dxgi_dll == NULL) {
7729
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not find " DXGI_DLL);
7730
D3D12_INTERNAL_DestroyRenderer(renderer);
7736
D3D12_INTERNAL_TryInitializeDXGIDebug(renderer);
7740
CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1)SDL_LoadFunction(
7742
CREATE_DXGI_FACTORY1_FUNC);
7743
if (CreateDXGIFactoryFunc == NULL) {
7744
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load function: " CREATE_DXGI_FACTORY1_FUNC);
7745
D3D12_INTERNAL_DestroyRenderer(renderer);
7750
res = CreateDXGIFactoryFunc(
7751
&D3D_IID_IDXGIFactory1,
7752
(void **)&factory1);
7754
D3D12_INTERNAL_DestroyRenderer(renderer);
7755
ERROR_CHECK_RETURN("Could not create DXGIFactory", NULL);
7759
res = IDXGIFactory1_QueryInterface(
7761
D3D_GUID(D3D_IID_IDXGIFactory4),
7762
(void **)&renderer->factory);
7764
D3D12_INTERNAL_DestroyRenderer(renderer);
7765
ERROR_CHECK_RETURN("DXGI1.4 support not found, required for DX12", NULL);
7767
IDXGIFactory1_Release(factory1);
7770
res = IDXGIFactory4_QueryInterface(
7772
D3D_GUID(D3D_IID_IDXGIFactory5),
7773
(void **)&factory5);
7774
if (SUCCEEDED(res)) {
7775
res = IDXGIFactory5_CheckFeatureSupport(
7777
DXGI_FEATURE_PRESENT_ALLOW_TEARING,
7778
&renderer->supportsTearing,
7779
sizeof(renderer->supportsTearing));
7781
renderer->supportsTearing = false;
7783
IDXGIFactory5_Release(factory5);
7787
res = IDXGIFactory4_QueryInterface(
7789
D3D_GUID(D3D_IID_IDXGIFactory6),
7790
(void **)&factory6);
7791
if (SUCCEEDED(res)) {
7792
res = IDXGIFactory6_EnumAdapterByGpuPreference(
7795
preferLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER : DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
7796
D3D_GUID(D3D_IID_IDXGIAdapter1),
7797
(void **)&renderer->adapter);
7798
IDXGIFactory6_Release(factory6);
7800
res = IDXGIFactory4_EnumAdapters1(
7803
&renderer->adapter);
7807
D3D12_INTERNAL_DestroyRenderer(renderer);
7808
ERROR_CHECK_RETURN("Could not find adapter for D3D12Device", NULL);
7812
res = IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc);
7814
D3D12_INTERNAL_DestroyRenderer(renderer);
7815
ERROR_CHECK_RETURN("Could not get adapter description", NULL);
7818
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12");
7819
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %S", adapterDesc.Description);
7823
renderer->d3d12_dll = SDL_LoadObject(D3D12_DLL);
7824
if (renderer->d3d12_dll == NULL) {
7825
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not find " D3D12_DLL);
7826
D3D12_INTERNAL_DestroyRenderer(renderer);
7831
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7832
D3D12XboxCreateDeviceFunc = (PFN_D3D12_XBOX_CREATE_DEVICE)SDL_LoadFunction(
7833
renderer->d3d12_dll,
7834
"D3D12XboxCreateDevice");
7835
if (D3D12XboxCreateDeviceFunc == NULL) {
7836
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load function: D3D12XboxCreateDevice");
7837
D3D12_INTERNAL_DestroyRenderer(renderer);
7841
D3D12CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)SDL_LoadFunction(
7842
renderer->d3d12_dll,
7843
D3D12_CREATE_DEVICE_FUNC);
7844
if (D3D12CreateDeviceFunc == NULL) {
7845
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load function: " D3D12_CREATE_DEVICE_FUNC);
7846
D3D12_INTERNAL_DestroyRenderer(renderer);
7851
renderer->D3D12SerializeRootSignature_func = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)SDL_LoadFunction(
7852
renderer->d3d12_dll,
7853
D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC);
7854
if (renderer->D3D12SerializeRootSignature_func == NULL) {
7855
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load function: " D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC);
7856
D3D12_INTERNAL_DestroyRenderer(renderer);
7862
D3D12_INTERNAL_TryInitializeD3D12Debug(renderer);
7866
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7867
if (s_Device != NULL) {
7868
renderer->device = s_Device;
7870
SDL_zero(createDeviceParams);
7871
createDeviceParams.Version = D3D12_SDK_VERSION;
7872
createDeviceParams.GraphicsCommandQueueRingSizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
7873
createDeviceParams.GraphicsScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
7874
createDeviceParams.ComputeScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
7875
createDeviceParams.DisableGeometryShaderAllocations = TRUE;
7876
createDeviceParams.DisableTessellationShaderAllocations = TRUE;
7877
#if defined(SDL_PLATFORM_XBOXSERIES)
7878
createDeviceParams.DisableDXR = TRUE;
7881
createDeviceParams.ProcessDebugFlags = D3D12XBOX_PROCESS_DEBUG_FLAG_DEBUG;
7884
res = D3D12XboxCreateDeviceFunc(
7886
&createDeviceParams,
7887
IID_GRAPHICS_PPV_ARGS(&renderer->device));
7889
D3D12_INTERNAL_DestroyRenderer(renderer);
7890
ERROR_CHECK_RETURN("Could not create D3D12Device", NULL);
7893
res = renderer->device->SetFrameIntervalX(
7895
D3D12XBOX_FRAME_INTERVAL_60_HZ,
7896
MAX_FRAMES_IN_FLIGHT - 1,
7897
D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
7899
D3D12_INTERNAL_DestroyRenderer(renderer);
7900
ERROR_CHECK_RETURN("Could not get set frame interval", NULL);
7903
res = renderer->device->ScheduleFrameEventX(
7904
D3D12XBOX_FRAME_EVENT_ORIGIN,
7907
D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE);
7909
D3D12_INTERNAL_DestroyRenderer(renderer);
7910
ERROR_CHECK_RETURN("Could not schedule frame events", NULL);
7913
s_Device = renderer->device;
7916
res = D3D12CreateDeviceFunc(
7917
(IUnknown *)renderer->adapter,
7918
D3D_FEATURE_LEVEL_CHOICE,
7919
D3D_GUID(D3D_IID_ID3D12Device),
7920
(void **)&renderer->device);
7923
D3D12_INTERNAL_DestroyRenderer(renderer);
7924
ERROR_CHECK_RETURN("Could not create D3D12Device", NULL);
7929
D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(renderer);
7934
architecture.NodeIndex = 0;
7935
res = ID3D12Device_CheckFeatureSupport(
7937
D3D12_FEATURE_ARCHITECTURE,
7939
sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
7941
D3D12_INTERNAL_DestroyRenderer(renderer);
7942
ERROR_CHECK_RETURN("Could not get device architecture", NULL);
7945
renderer->UMA = (bool)architecture.UMA;
7946
renderer->UMACacheCoherent = (bool)architecture.CacheCoherentUMA;
7948
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7949
renderer->GPUUploadHeapSupported = false;
7952
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
7953
renderer->GPUUploadHeapSupported = false;
7954
res = ID3D12Device_CheckFeatureSupport(
7956
D3D12_FEATURE_D3D12_OPTIONS16,
7960
if (SUCCEEDED(res)) {
7961
renderer->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
7966
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7967
if (s_CommandQueue != NULL) {
7968
renderer->commandQueue = s_CommandQueue;
7971
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
7972
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
7973
queueDesc.NodeMask = 0;
7974
queueDesc.Priority = 0;
7976
res = ID3D12Device_CreateCommandQueue(
7979
D3D_GUID(D3D_IID_ID3D12CommandQueue),
7980
(void **)&renderer->commandQueue);
7983
D3D12_INTERNAL_DestroyRenderer(renderer);
7984
ERROR_CHECK_RETURN("Could not create D3D12CommandQueue", NULL);
7986
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7987
s_CommandQueue = renderer->commandQueue;
7993
D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc;
7994
D3D12_INDIRECT_ARGUMENT_DESC indirectArgumentDesc;
7995
SDL_zero(indirectArgumentDesc);
7997
indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
7998
commandSignatureDesc.NodeMask = 0;
7999
commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndirectDrawCommand);
8000
commandSignatureDesc.NumArgumentDescs = 1;
8001
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8003
res = ID3D12Device_CreateCommandSignature(
8005
&commandSignatureDesc,
8007
D3D_GUID(D3D_IID_ID3D12CommandSignature),
8008
(void **)&renderer->indirectDrawCommandSignature);
8010
D3D12_INTERNAL_DestroyRenderer(renderer);
8011
ERROR_CHECK_RETURN("Could not create indirect draw command signature", NULL)
8014
indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
8015
commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndexedIndirectDrawCommand);
8016
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8018
res = ID3D12Device_CreateCommandSignature(
8020
&commandSignatureDesc,
8022
D3D_GUID(D3D_IID_ID3D12CommandSignature),
8023
(void **)&renderer->indirectIndexedDrawCommandSignature);
8025
D3D12_INTERNAL_DestroyRenderer(renderer);
8026
ERROR_CHECK_RETURN("Could not create indirect indexed draw command signature", NULL)
8029
indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
8030
commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndirectDispatchCommand);
8031
commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8033
res = ID3D12Device_CreateCommandSignature(
8035
&commandSignatureDesc,
8037
D3D_GUID(D3D_IID_ID3D12CommandSignature),
8038
(void **)&renderer->indirectDispatchCommandSignature);
8040
D3D12_INTERNAL_DestroyRenderer(renderer);
8041
ERROR_CHECK_RETURN("Could not create indirect dispatch command signature", NULL)
8046
renderer->submittedCommandBufferCapacity = 4;
8047
renderer->submittedCommandBufferCount = 0;
8048
renderer->submittedCommandBuffers = (D3D12CommandBuffer **)SDL_calloc(
8049
renderer->submittedCommandBufferCapacity, sizeof(D3D12CommandBuffer *));
8050
if (!renderer->submittedCommandBuffers) {
8051
D3D12_INTERNAL_DestroyRenderer(renderer);
8055
renderer->uniformBufferPoolCapacity = 4;
8056
renderer->uniformBufferPoolCount = 0;
8057
renderer->uniformBufferPool = (D3D12UniformBuffer **)SDL_calloc(
8058
renderer->uniformBufferPoolCapacity, sizeof(D3D12UniformBuffer *));
8059
if (!renderer->uniformBufferPool) {
8060
D3D12_INTERNAL_DestroyRenderer(renderer);
8064
renderer->claimedWindowCapacity = 4;
8065
renderer->claimedWindowCount = 0;
8066
renderer->claimedWindows = (D3D12WindowData **)SDL_calloc(
8067
renderer->claimedWindowCapacity, sizeof(D3D12WindowData *));
8068
if (!renderer->claimedWindows) {
8069
D3D12_INTERNAL_DestroyRenderer(renderer);
8073
renderer->availableFenceCapacity = 4;
8074
renderer->availableFenceCount = 0;
8075
renderer->availableFences = (D3D12Fence **)SDL_calloc(
8076
renderer->availableFenceCapacity, sizeof(D3D12Fence *));
8077
if (!renderer->availableFences) {
8078
D3D12_INTERNAL_DestroyRenderer(renderer);
8083
for (Uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1) {
8084
renderer->stagingDescriptorHeaps[i] = D3D12_INTERNAL_CreateDescriptorHeap(
8086
(D3D12_DESCRIPTOR_HEAP_TYPE)i,
8087
(i <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) ? VIEW_SAMPLER_STAGING_DESCRIPTOR_COUNT : TARGET_STAGING_DESCRIPTOR_COUNT,
8092
for (Uint32 i = 0; i < 2; i += 1) {
8093
renderer->descriptorHeapPools[i].lock = SDL_CreateMutex();
8094
renderer->descriptorHeapPools[i].capacity = 4;
8095
renderer->descriptorHeapPools[i].count = 4;
8096
renderer->descriptorHeapPools[i].heaps = (D3D12DescriptorHeap **)SDL_calloc(
8097
renderer->descriptorHeapPools[i].capacity, sizeof(D3D12DescriptorHeap *));
8099
for (Uint32 j = 0; j < renderer->descriptorHeapPools[i].capacity; j += 1) {
8100
renderer->descriptorHeapPools[i].heaps[j] = D3D12_INTERNAL_CreateDescriptorHeap(
8102
(D3D12_DESCRIPTOR_HEAP_TYPE)i,
8103
i == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ? VIEW_GPU_DESCRIPTOR_COUNT : SAMPLER_GPU_DESCRIPTOR_COUNT,
8110
renderer->buffersToDestroyCapacity = 4;
8111
renderer->buffersToDestroyCount = 0;
8112
renderer->buffersToDestroy = (D3D12Buffer **)SDL_calloc(
8113
renderer->buffersToDestroyCapacity, sizeof(D3D12Buffer *));
8114
if (!renderer->buffersToDestroy) {
8115
D3D12_INTERNAL_DestroyRenderer(renderer);
8119
renderer->texturesToDestroyCapacity = 4;
8120
renderer->texturesToDestroyCount = 0;
8121
renderer->texturesToDestroy = (D3D12Texture **)SDL_calloc(
8122
renderer->texturesToDestroyCapacity, sizeof(D3D12Texture *));
8123
if (!renderer->texturesToDestroy) {
8124
D3D12_INTERNAL_DestroyRenderer(renderer);
8128
renderer->samplersToDestroyCapacity = 4;
8129
renderer->samplersToDestroyCount = 0;
8130
renderer->samplersToDestroy = (D3D12Sampler **)SDL_calloc(
8131
renderer->samplersToDestroyCapacity, sizeof(D3D12Sampler *));
8132
if (!renderer->samplersToDestroy) {
8133
D3D12_INTERNAL_DestroyRenderer(renderer);
8137
renderer->graphicsPipelinesToDestroyCapacity = 4;
8138
renderer->graphicsPipelinesToDestroyCount = 0;
8139
renderer->graphicsPipelinesToDestroy = (D3D12GraphicsPipeline **)SDL_calloc(
8140
renderer->graphicsPipelinesToDestroyCapacity, sizeof(D3D12GraphicsPipeline *));
8141
if (!renderer->graphicsPipelinesToDestroy) {
8142
D3D12_INTERNAL_DestroyRenderer(renderer);
8146
renderer->computePipelinesToDestroyCapacity = 4;
8147
renderer->computePipelinesToDestroyCount = 0;
8148
renderer->computePipelinesToDestroy = (D3D12ComputePipeline **)SDL_calloc(
8149
renderer->computePipelinesToDestroyCapacity, sizeof(D3D12ComputePipeline *));
8150
if (!renderer->computePipelinesToDestroy) {
8151
D3D12_INTERNAL_DestroyRenderer(renderer);
8156
renderer->stagingDescriptorHeapLock = SDL_CreateMutex();
8157
renderer->acquireCommandBufferLock = SDL_CreateMutex();
8158
renderer->acquireUniformBufferLock = SDL_CreateMutex();
8159
renderer->submitLock = SDL_CreateMutex();
8160
renderer->windowLock = SDL_CreateMutex();
8161
renderer->fenceLock = SDL_CreateMutex();
8162
renderer->disposeLock = SDL_CreateMutex();
8164
renderer->debugMode = debugMode;
8166
renderer->semantic = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD");
8169
D3D12_INTERNAL_InitBlitResources(renderer);
8172
result = (SDL_GPUDevice *)SDL_calloc(1, sizeof(SDL_GPUDevice));
8175
D3D12_INTERNAL_DestroyRenderer(renderer);
8179
ASSIGN_DRIVER(D3D12)
8180
result->driverData = (SDL_GPURenderer *)renderer;
8181
result->debugMode = debugMode;
8182
renderer->sdlGPUDevice = result;
8187
SDL_GPUBootstrap D3D12Driver = {
8189
SDL_GPU_DRIVER_D3D12,
8190
SDL_GPU_SHADERFORMAT_DXIL,
8191
D3D12_PrepareDriver,
8199
#ifdef SDL_PLATFORM_GDK
8201
void SDL_GDKSuspendGPU(SDL_GPUDevice *device)
8203
#if defined(SDL_GPU_D3D12) && (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8204
D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
8206
if (device == NULL) {
8207
SDL_SetError("Invalid GPU device");
8211
SDL_LockMutex(renderer->submitLock);
8212
res = renderer->commandQueue->SuspendX(0);
8214
SDL_LogError(SDL_LOG_CATEGORY_GPU, "SuspendX failed: %X", res);
8216
SDL_UnlockMutex(renderer->submitLock);
8220
void SDL_GDKResumeGPU(SDL_GPUDevice *device)
8222
#if defined(SDL_GPU_D3D12) && (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8223
D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
8225
if (device == NULL) {
8226
SDL_SetError("Invalid GPU device");
8230
SDL_LockMutex(renderer->submitLock);
8231
res = renderer->commandQueue->ResumeX();
8233
SDL_LogError(SDL_LOG_CATEGORY_GPU, "ResumeX failed: %X", res);
8235
SDL_UnlockMutex(renderer->submitLock);
8237
res = renderer->device->SetFrameIntervalX(
8239
D3D12XBOX_FRAME_INTERVAL_60_HZ,
8240
MAX_FRAMES_IN_FLIGHT - 1,
8241
D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
8243
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not set frame interval: %X", res);
8246
res = renderer->device->ScheduleFrameEventX(
8247
D3D12XBOX_FRAME_EVENT_ORIGIN,
8250
D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE);
8252
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not schedule frame events: %X", res);