mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 21:32:45 +00:00
(D3D12) Move functions over to files that need it
This commit is contained in:
parent
92a7d5bf61
commit
05797eb6b8
@ -139,302 +139,6 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool d3d12_init_base(d3d12_video_t* d3d12)
|
|
||||||
{
|
|
||||||
DXGIAdapter adapter = NULL;
|
|
||||||
#ifdef DEBUG
|
|
||||||
#ifdef __WINRT__
|
|
||||||
if (SUCCEEDED(D3D12GetDebugInterface_(&d3d12->debugController)))
|
|
||||||
d3d12->debugController->lpVtbl->EnableDebugLayer(&d3d12->debugController);
|
|
||||||
#else
|
|
||||||
if (SUCCEEDED(D3D12GetDebugInterface_(&d3d12->debugController)))
|
|
||||||
d3d12->debugController->lpVtbl->EnableDebugLayer(d3d12->debugController);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __WINRT__
|
|
||||||
DXGICreateFactory2(&d3d12->factory);
|
|
||||||
#else
|
|
||||||
DXGICreateFactory(&d3d12->factory);
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
settings_t *settings = config_get_ptr();
|
|
||||||
int gpu_index = settings->ints.d3d12_gpu_index;
|
|
||||||
|
|
||||||
if (d3d12->gpu_list)
|
|
||||||
string_list_free(d3d12->gpu_list);
|
|
||||||
|
|
||||||
d3d12->gpu_list = string_list_new();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
char str[128];
|
|
||||||
union string_list_elem_attr attr = {0};
|
|
||||||
DXGI_ADAPTER_DESC desc = {0};
|
|
||||||
|
|
||||||
str[0] = '\0';
|
|
||||||
|
|
||||||
#ifdef __WINRT__
|
|
||||||
if (FAILED(DXGIEnumAdapters2(d3d12->factory, i, &adapter)))
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
if (FAILED(DXGIEnumAdapters(d3d12->factory, i, &adapter)))
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
IDXGIAdapter_GetDesc(adapter, &desc);
|
|
||||||
|
|
||||||
utf16_to_char_string((const uint16_t*)desc.Description, str, sizeof(str));
|
|
||||||
|
|
||||||
RARCH_LOG("[D3D12]: Found GPU at index %d: \"%s\".\n", i, str);
|
|
||||||
|
|
||||||
string_list_append(d3d12->gpu_list, str, attr);
|
|
||||||
|
|
||||||
if (i < D3D12_MAX_GPU_COUNT)
|
|
||||||
{
|
|
||||||
AddRef(adapter);
|
|
||||||
d3d12->adapters[i] = adapter;
|
|
||||||
}
|
|
||||||
Release(adapter);
|
|
||||||
adapter = NULL;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
if (i >= D3D12_MAX_GPU_COUNT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D12_API, d3d12->gpu_list);
|
|
||||||
|
|
||||||
if (0 <= gpu_index && gpu_index <= i && gpu_index < D3D12_MAX_GPU_COUNT)
|
|
||||||
{
|
|
||||||
d3d12->adapter = d3d12->adapters[gpu_index];
|
|
||||||
AddRef(d3d12->adapter);
|
|
||||||
RARCH_LOG("[D3D12]: Using GPU index %d.\n", gpu_index);
|
|
||||||
video_driver_set_gpu_device_string(
|
|
||||||
d3d12->gpu_list->elems[gpu_index].data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RARCH_WARN("[D3D12]: Invalid GPU index %d, using first device found.\n", gpu_index);
|
|
||||||
d3d12->adapter = d3d12->adapters[0];
|
|
||||||
AddRef(d3d12->adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device)))
|
|
||||||
RARCH_WARN("[D3D12]: Could not create D3D12 device.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool d3d12_init_queue(d3d12_video_t* d3d12)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
static const D3D12_COMMAND_QUEUE_DESC desc = {
|
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
0,
|
|
||||||
D3D12_COMMAND_QUEUE_FLAG_NONE,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
D3D12CreateCommandQueue(
|
|
||||||
d3d12->device,
|
|
||||||
(D3D12_COMMAND_QUEUE_DESC*)&desc,
|
|
||||||
&d3d12->queue.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12CreateCommandAllocator(
|
|
||||||
d3d12->device,
|
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
&d3d12->queue.allocator);
|
|
||||||
|
|
||||||
D3D12CreateGraphicsCommandList(
|
|
||||||
d3d12->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, d3d12->queue.allocator,
|
|
||||||
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND], &d3d12->queue.cmd);
|
|
||||||
|
|
||||||
D3D12CloseGraphicsCommandList(d3d12->queue.cmd);
|
|
||||||
|
|
||||||
D3D12CreateFence(d3d12->device, 0, D3D12_FENCE_FLAG_NONE, &d3d12->queue.fence);
|
|
||||||
d3d12->queue.fenceValue = 0;
|
|
||||||
d3d12->queue.fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
|
||||||
int width, int height, void* corewindow)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
HRESULT hr;
|
|
||||||
HWND hwnd = (HWND)corewindow;
|
|
||||||
#ifdef __WINRT__
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 desc = {{0}};
|
|
||||||
#else
|
|
||||||
DXGI_SWAP_CHAIN_DESC desc = {{0}};
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DXGI_HDR
|
|
||||||
DXGI_COLOR_SPACE_TYPE color_space;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DXGI_HDR
|
|
||||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_8] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_10] = DXGI_FORMAT_R10G10B10A2_UNORM;
|
|
||||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM;
|
|
||||||
|
|
||||||
if (!(d3d12->hdr.support =
|
|
||||||
dxgi_check_display_hdr_support(d3d12->factory, hwnd)))
|
|
||||||
d3d12->hdr.enable = false;
|
|
||||||
|
|
||||||
d3d12->chain.bit_depth = d3d12->hdr.enable
|
|
||||||
? DXGI_SWAPCHAIN_BIT_DEPTH_10
|
|
||||||
: DXGI_SWAPCHAIN_BIT_DEPTH_8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
desc.BufferCount = countof(d3d12->chain.renderTargets);
|
|
||||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
#ifdef __WINRT__
|
|
||||||
desc.Width = width;
|
|
||||||
desc.Height = height;
|
|
||||||
#else
|
|
||||||
desc.BufferDesc.Width = width;
|
|
||||||
desc.BufferDesc.Height = height;
|
|
||||||
desc.BufferDesc.RefreshRate.Numerator = 0;
|
|
||||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DXGI_HDR
|
|
||||||
#ifdef __WINRT__
|
|
||||||
desc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
|
||||||
#else
|
|
||||||
desc.BufferDesc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef __WINRT__
|
|
||||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
#else
|
|
||||||
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
desc.SampleDesc.Count = 1;
|
|
||||||
desc.SampleDesc.Quality = 0;
|
|
||||||
#ifdef HAVE_WINDOW
|
|
||||||
desc.OutputWindow = hwnd;
|
|
||||||
desc.Windowed = TRUE;
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
|
||||||
#else
|
|
||||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
|
||||||
#endif
|
|
||||||
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
|
||||||
|
|
||||||
#ifdef __WINRT__
|
|
||||||
hr = DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle);
|
|
||||||
#else
|
|
||||||
hr = DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle);
|
|
||||||
#endif
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
RARCH_ERR("[D3D12]: Failed to create the swap chain (0x%08X)\n", hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_WINDOW
|
|
||||||
DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DXGI_HDR
|
|
||||||
/* Check display HDR support and
|
|
||||||
initialize ST.2084 support to match
|
|
||||||
the display's support. */
|
|
||||||
color_space =
|
|
||||||
d3d12->hdr.enable
|
|
||||||
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
|
||||||
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
|
||||||
|
|
||||||
dxgi_swapchain_color_space(d3d12->chain.handle,
|
|
||||||
&d3d12->chain.color_space, color_space);
|
|
||||||
dxgi_set_hdr_metadata(
|
|
||||||
d3d12->chain.handle,
|
|
||||||
d3d12->hdr.support,
|
|
||||||
d3d12->chain.bit_depth,
|
|
||||||
d3d12->chain.color_space,
|
|
||||||
d3d12->hdr.max_output_nits,
|
|
||||||
d3d12->hdr.min_output_nits,
|
|
||||||
d3d12->hdr.max_cll,
|
|
||||||
d3d12->hdr.max_fall);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
|
||||||
|
|
||||||
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
|
||||||
{
|
|
||||||
DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]);
|
|
||||||
D3D12CreateRenderTargetView(
|
|
||||||
d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_DXGI_HDR
|
|
||||||
memset(&d3d12->chain.back_buffer,
|
|
||||||
0, sizeof(d3d12->chain.back_buffer));
|
|
||||||
d3d12->chain.back_buffer.desc.Width = width;
|
|
||||||
d3d12->chain.back_buffer.desc.Height = height;
|
|
||||||
d3d12->chain.back_buffer.desc.Format =
|
|
||||||
d3d12->shader_preset && d3d12->shader_preset->passes ? glslang_format_to_dxgi(d3d12->pass[d3d12->shader_preset->passes - 1].semantics.format) : DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
d3d12->chain.back_buffer.desc.Flags =
|
|
||||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
|
||||||
d3d12->chain.back_buffer.srv_heap =
|
|
||||||
&d3d12->desc.srv_heap;
|
|
||||||
d3d12->chain.back_buffer.rt_view.ptr =
|
|
||||||
d3d12->desc.rtv_heap.cpu.ptr
|
|
||||||
+ (countof(d3d12->chain.renderTargets))
|
|
||||||
* d3d12->desc.rtv_heap.stride;
|
|
||||||
d3d12_init_texture(d3d12->device, &d3d12->chain.back_buffer);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
d3d12->chain.viewport.Width = width;
|
|
||||||
d3d12->chain.viewport.Height = height;
|
|
||||||
d3d12->chain.scissorRect.right = width;
|
|
||||||
d3d12->chain.scissorRect.bottom = height;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void d3d12_init_descriptor_heap(D3D12Device device, d3d12_descriptor_heap_t* out)
|
|
||||||
{
|
|
||||||
D3D12CreateDescriptorHeap(device, &out->desc, &out->handle);
|
|
||||||
out->cpu = D3D12GetCPUDescriptorHandleForHeapStart(out->handle);
|
|
||||||
out->gpu = D3D12GetGPUDescriptorHandleForHeapStart(out->handle);
|
|
||||||
out->stride = D3D12GetDescriptorHandleIncrementSize(device, out->desc.Type);
|
|
||||||
out->map = (bool*)calloc(out->desc.NumDescriptors, sizeof(bool));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void d3d12_release_descriptor_heap(d3d12_descriptor_heap_t* heap)
|
|
||||||
{
|
|
||||||
free(heap->map);
|
|
||||||
Release(heap->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static D3D12_CPU_DESCRIPTOR_HANDLE d3d12_descriptor_heap_slot_alloc(d3d12_descriptor_heap_t* heap)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = { 0 };
|
|
||||||
|
|
||||||
for (i = heap->start; i < (int)heap->desc.NumDescriptors; i++)
|
|
||||||
{
|
|
||||||
if (!heap->map[i])
|
|
||||||
{
|
|
||||||
heap->map[i] = true;
|
|
||||||
handle.ptr = heap->cpu.ptr + i * heap->stride;
|
|
||||||
heap->start = i + 1;
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* if you get here try increasing NumDescriptors for this heap */
|
|
||||||
assert(0);
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
d3d12_descriptor_heap_slot_free(d3d12_descriptor_heap_t* heap, D3D12_CPU_DESCRIPTOR_HANDLE handle)
|
d3d12_descriptor_heap_slot_free(d3d12_descriptor_heap_t* heap, D3D12_CPU_DESCRIPTOR_HANDLE handle)
|
||||||
{
|
{
|
||||||
@ -454,285 +158,6 @@ d3d12_descriptor_heap_slot_free(d3d12_descriptor_heap_t* heap, D3D12_CPU_DESCRIP
|
|||||||
heap->start = i;
|
heap->start = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool d3d12_create_root_signature(
|
|
||||||
D3D12Device device, D3D12_ROOT_SIGNATURE_DESC* desc, D3D12RootSignature* out)
|
|
||||||
{
|
|
||||||
D3DBlob signature;
|
|
||||||
D3DBlob error;
|
|
||||||
D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
RARCH_ERR(
|
|
||||||
"[D3D12]: CreateRootSignature failed : %s", (const char*)D3DGetBufferPointer(error));
|
|
||||||
Release(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12CreateRootSignature(
|
|
||||||
device, 0, D3DGetBufferPointer(signature), D3DGetBufferSize(signature), out);
|
|
||||||
Release(signature);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool d3d12_init_descriptors(d3d12_video_t* d3d12)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
D3D12_ROOT_SIGNATURE_DESC desc;
|
|
||||||
D3D12_DESCRIPTOR_RANGE srv_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1 } };
|
|
||||||
D3D12_DESCRIPTOR_RANGE uav_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1 } };
|
|
||||||
D3D12_DESCRIPTOR_RANGE sampler_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1 } };
|
|
||||||
D3D12_STATIC_SAMPLER_DESC static_sampler = { D3D12_FILTER_MIN_MAG_MIP_POINT };
|
|
||||||
D3D12_ROOT_PARAMETER root_params[ROOT_ID_MAX];
|
|
||||||
D3D12_ROOT_PARAMETER cs_root_params[CS_ROOT_ID_MAX];
|
|
||||||
|
|
||||||
root_params[ROOT_ID_TEXTURE_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
root_params[ROOT_ID_TEXTURE_T].DescriptorTable.NumDescriptorRanges = countof(srv_tbl);
|
|
||||||
root_params[ROOT_ID_TEXTURE_T].DescriptorTable.pDescriptorRanges = srv_tbl;
|
|
||||||
root_params[ROOT_ID_TEXTURE_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
|
|
||||||
root_params[ROOT_ID_SAMPLER_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
root_params[ROOT_ID_SAMPLER_T].DescriptorTable.NumDescriptorRanges = countof(sampler_tbl);
|
|
||||||
root_params[ROOT_ID_SAMPLER_T].DescriptorTable.pDescriptorRanges = sampler_tbl;
|
|
||||||
root_params[ROOT_ID_SAMPLER_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
|
|
||||||
root_params[ROOT_ID_UBO].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
|
||||||
root_params[ROOT_ID_UBO].Descriptor.RegisterSpace = 0;
|
|
||||||
root_params[ROOT_ID_UBO].Descriptor.ShaderRegister = 0;
|
|
||||||
root_params[ROOT_ID_UBO].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
|
||||||
|
|
||||||
root_params[ROOT_ID_PC].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
|
||||||
root_params[ROOT_ID_PC].Descriptor.RegisterSpace = 0;
|
|
||||||
root_params[ROOT_ID_PC].Descriptor.ShaderRegister = 1;
|
|
||||||
root_params[ROOT_ID_PC].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
|
||||||
|
|
||||||
desc.NumParameters = countof(root_params);
|
|
||||||
desc.pParameters = root_params;
|
|
||||||
desc.NumStaticSamplers = 0;
|
|
||||||
desc.pStaticSamplers = NULL;
|
|
||||||
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
|
||||||
|
|
||||||
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.rootSignature);
|
|
||||||
|
|
||||||
srv_tbl[0].NumDescriptors = SLANG_NUM_BINDINGS;
|
|
||||||
sampler_tbl[0].NumDescriptors = SLANG_NUM_BINDINGS;
|
|
||||||
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.sl_rootSignature);
|
|
||||||
|
|
||||||
cs_root_params[CS_ROOT_ID_TEXTURE_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.NumDescriptorRanges = countof(srv_tbl);
|
|
||||||
cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.pDescriptorRanges = srv_tbl;
|
|
||||||
cs_root_params[CS_ROOT_ID_TEXTURE_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
|
||||||
|
|
||||||
cs_root_params[CS_ROOT_ID_UAV_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.NumDescriptorRanges = countof(uav_tbl);
|
|
||||||
cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.pDescriptorRanges = uav_tbl;
|
|
||||||
cs_root_params[CS_ROOT_ID_UAV_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
|
||||||
|
|
||||||
cs_root_params[CS_ROOT_ID_CONSTANTS].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
|
||||||
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.Num32BitValues = 3;
|
|
||||||
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.RegisterSpace = 0;
|
|
||||||
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.ShaderRegister = 0;
|
|
||||||
cs_root_params[CS_ROOT_ID_CONSTANTS].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
|
||||||
|
|
||||||
static_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
|
||||||
static_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
|
||||||
static_sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
|
||||||
#if 0
|
|
||||||
static_sampler.MaxAnisotropy = 1;
|
|
||||||
static_sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
|
||||||
static_sampler.MinLOD = -D3D12_FLOAT32_MAX;
|
|
||||||
static_sampler.MaxLOD = D3D12_FLOAT32_MAX;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
desc.NumParameters = countof(cs_root_params);
|
|
||||||
desc.pParameters = cs_root_params;
|
|
||||||
desc.NumStaticSamplers = 1;
|
|
||||||
desc.pStaticSamplers = &static_sampler;
|
|
||||||
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS |
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
|
|
||||||
|
|
||||||
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.cs_rootSignature);
|
|
||||||
|
|
||||||
d3d12->desc.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
|
||||||
d3d12->desc.rtv_heap.desc.NumDescriptors = countof(d3d12->chain.renderTargets) + GFX_MAX_SHADERS * 2;
|
|
||||||
d3d12->desc.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
|
||||||
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.rtv_heap);
|
|
||||||
|
|
||||||
d3d12->desc.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
|
||||||
d3d12->desc.srv_heap.desc.NumDescriptors = SLANG_NUM_BINDINGS * GFX_MAX_SHADERS + 2048;
|
|
||||||
d3d12->desc.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
|
||||||
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.srv_heap);
|
|
||||||
|
|
||||||
d3d12->desc.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
|
|
||||||
d3d12->desc.sampler_heap.desc.NumDescriptors =
|
|
||||||
SLANG_NUM_BINDINGS * GFX_MAX_SHADERS + 2 * RARCH_WRAP_MAX;
|
|
||||||
d3d12->desc.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
|
||||||
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.sampler_heap);
|
|
||||||
|
|
||||||
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
|
||||||
{
|
|
||||||
d3d12->chain.desc_handles[i].ptr =
|
|
||||||
d3d12->desc.rtv_heap.cpu.ptr + i * d3d12->desc.rtv_heap.stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < GFX_MAX_SHADERS; i++)
|
|
||||||
{
|
|
||||||
d3d12->pass[i].rt.rt_view.ptr =
|
|
||||||
d3d12->desc.rtv_heap.cpu.ptr +
|
|
||||||
(countof(d3d12->chain.renderTargets) + (2 * i)) * d3d12->desc.rtv_heap.stride;
|
|
||||||
d3d12->pass[i].feedback.rt_view.ptr = d3d12->pass[i].rt.rt_view.ptr + d3d12->desc.rtv_heap.stride;
|
|
||||||
|
|
||||||
d3d12->pass[i].textures.ptr = d3d12_descriptor_heap_slot_alloc(&d3d12->desc.srv_heap).ptr -
|
|
||||||
d3d12->desc.srv_heap.cpu.ptr + d3d12->desc.srv_heap.gpu.ptr;
|
|
||||||
d3d12->pass[i].samplers.ptr =
|
|
||||||
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.sampler_heap).ptr -
|
|
||||||
d3d12->desc.sampler_heap.cpu.ptr + d3d12->desc.sampler_heap.gpu.ptr;
|
|
||||||
|
|
||||||
for (j = 1; j < SLANG_NUM_BINDINGS; j++)
|
|
||||||
{
|
|
||||||
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.srv_heap);
|
|
||||||
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.sampler_heap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE D3D12_GPU_DESCRIPTOR_HANDLE
|
|
||||||
d3d12_create_sampler(D3D12Device device, D3D12_SAMPLER_DESC* desc, d3d12_descriptor_heap_t* heap)
|
|
||||||
{
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = d3d12_descriptor_heap_slot_alloc(heap);
|
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = { cpu_handle.ptr - heap->cpu.ptr + heap->gpu.ptr };
|
|
||||||
|
|
||||||
D3D12CreateSampler(device, desc, cpu_handle);
|
|
||||||
return gpu_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void d3d12_init_samplers(d3d12_video_t* d3d12)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_POINT };
|
|
||||||
desc.MaxAnisotropy = 1;
|
|
||||||
desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
|
||||||
desc.MinLOD = -D3D12_FLOAT32_MAX;
|
|
||||||
desc.MaxLOD = D3D12_FLOAT32_MAX;
|
|
||||||
|
|
||||||
for (i = 0; i < RARCH_WRAP_MAX; i++)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case RARCH_WRAP_BORDER:
|
|
||||||
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RARCH_WRAP_EDGE:
|
|
||||||
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RARCH_WRAP_REPEAT:
|
|
||||||
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RARCH_WRAP_MIRRORED_REPEAT:
|
|
||||||
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
desc.AddressV = desc.AddressU;
|
|
||||||
desc.AddressW = desc.AddressU;
|
|
||||||
|
|
||||||
desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
|
||||||
d3d12->samplers[RARCH_FILTER_LINEAR][i] =
|
|
||||||
d3d12_create_sampler(d3d12->device, &desc, &d3d12->desc.sampler_heap);
|
|
||||||
|
|
||||||
desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
|
||||||
d3d12->samplers[RARCH_FILTER_NEAREST][i] =
|
|
||||||
d3d12_create_sampler(d3d12->device, &desc, &d3d12->desc.sampler_heap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc = {
|
|
||||||
TRUE,
|
|
||||||
FALSE,
|
|
||||||
D3D12_BLEND_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_INV_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_OP_ADD,
|
|
||||||
D3D12_BLEND_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_INV_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_OP_ADD,
|
|
||||||
D3D12_LOGIC_OP_NOOP,
|
|
||||||
D3D12_COLOR_WRITE_ENABLE_ALL,
|
|
||||||
};
|
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc = {
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
D3D12_BLEND_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_INV_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_OP_ADD,
|
|
||||||
D3D12_BLEND_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_INV_SRC_ALPHA,
|
|
||||||
D3D12_BLEND_OP_ADD,
|
|
||||||
D3D12_LOGIC_OP_NOOP,
|
|
||||||
D3D12_COLOR_WRITE_ENABLE_ALL,
|
|
||||||
};
|
|
||||||
|
|
||||||
bool d3d12_init_pipeline(
|
|
||||||
D3D12Device device,
|
|
||||||
D3DBlob vs_code,
|
|
||||||
D3DBlob ps_code,
|
|
||||||
D3DBlob gs_code,
|
|
||||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC* desc,
|
|
||||||
D3D12PipelineState* out)
|
|
||||||
{
|
|
||||||
if (vs_code)
|
|
||||||
{
|
|
||||||
desc->VS.pShaderBytecode = D3DGetBufferPointer(vs_code);
|
|
||||||
desc->VS.BytecodeLength = D3DGetBufferSize(vs_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desc->VS.pShaderBytecode = NULL;
|
|
||||||
desc->VS.BytecodeLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps_code)
|
|
||||||
{
|
|
||||||
desc->PS.pShaderBytecode = D3DGetBufferPointer(ps_code);
|
|
||||||
desc->PS.BytecodeLength = D3DGetBufferSize(ps_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desc->PS.pShaderBytecode = NULL;
|
|
||||||
desc->PS.BytecodeLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gs_code)
|
|
||||||
{
|
|
||||||
desc->GS.pShaderBytecode = D3DGetBufferPointer(gs_code);
|
|
||||||
desc->GS.BytecodeLength = D3DGetBufferSize(gs_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desc->GS.pShaderBytecode = NULL;
|
|
||||||
desc->GS.BytecodeLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc->SampleMask = UINT_MAX;
|
|
||||||
desc->RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
|
||||||
desc->RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
|
||||||
desc->NumRenderTargets = 1;
|
|
||||||
desc->SampleDesc.Count = 1;
|
|
||||||
|
|
||||||
D3D12CreateGraphicsPipelineState(device, desc, out);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS
|
D3D12_GPU_VIRTUAL_ADDRESS
|
||||||
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer)
|
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer)
|
||||||
{
|
{
|
||||||
@ -772,6 +197,49 @@ void d3d12_release_texture(d3d12_texture_t* texture)
|
|||||||
Release(texture->handle);
|
Release(texture->handle);
|
||||||
Release(texture->upload_buffer);
|
Release(texture->upload_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE d3d12_descriptor_heap_slot_alloc(d3d12_descriptor_heap_t* heap)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE handle = { 0 };
|
||||||
|
|
||||||
|
for (i = heap->start; i < (int)heap->desc.NumDescriptors; i++)
|
||||||
|
{
|
||||||
|
if (!heap->map[i])
|
||||||
|
{
|
||||||
|
heap->map[i] = true;
|
||||||
|
handle.ptr = heap->cpu.ptr + i * heap->stride;
|
||||||
|
heap->start = i + 1;
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if you get here try increasing NumDescriptors for this heap */
|
||||||
|
assert(0);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DXGI_FORMAT d3d12_get_closest_match(D3D12Device device, D3D12_FEATURE_DATA_FORMAT_SUPPORT* desired)
|
||||||
|
{
|
||||||
|
DXGI_FORMAT default_list[] = { desired->Format, DXGI_FORMAT_UNKNOWN };
|
||||||
|
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired->Format);
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
format = default_list;
|
||||||
|
|
||||||
|
while (*format != DXGI_FORMAT_UNKNOWN)
|
||||||
|
{
|
||||||
|
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { *format };
|
||||||
|
if (SUCCEEDED(D3D12CheckFeatureSupport(
|
||||||
|
device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, sizeof(format_support))) &&
|
||||||
|
((format_support.Support1 & desired->Support1) == desired->Support1) &&
|
||||||
|
((format_support.Support2 & desired->Support2) == desired->Support2))
|
||||||
|
break;
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
assert(*format);
|
||||||
|
return *format;
|
||||||
|
}
|
||||||
|
|
||||||
void d3d12_init_texture(D3D12Device device, d3d12_texture_t* texture)
|
void d3d12_init_texture(D3D12Device device, d3d12_texture_t* texture)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -910,6 +378,7 @@ void d3d12_update_texture(
|
|||||||
|
|
||||||
texture->dirty = true;
|
texture->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
||||||
d3d12_texture_t* texture, void *userdata)
|
d3d12_texture_t* texture, void *userdata)
|
||||||
{
|
{
|
||||||
@ -986,49 +455,3 @@ void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
|||||||
|
|
||||||
texture->dirty = false;
|
texture->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void d3d12_create_fullscreen_quad_vbo(
|
|
||||||
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo)
|
|
||||||
{
|
|
||||||
static const d3d12_vertex_t vertices[] = {
|
|
||||||
{ { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
|
||||||
{ { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
|
||||||
{ { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
|
||||||
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
|
||||||
};
|
|
||||||
|
|
||||||
view->SizeInBytes = sizeof(vertices);
|
|
||||||
view->StrideInBytes = sizeof(*vertices);
|
|
||||||
view->BufferLocation = d3d12_create_buffer(device, view->SizeInBytes, vbo);
|
|
||||||
|
|
||||||
{
|
|
||||||
void* vertex_data_begin;
|
|
||||||
D3D12_RANGE read_range = { 0, 0 };
|
|
||||||
|
|
||||||
D3D12Map(*vbo, 0, &read_range, &vertex_data_begin);
|
|
||||||
memcpy(vertex_data_begin, vertices, sizeof(vertices));
|
|
||||||
D3D12Unmap(*vbo, 0, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DXGI_FORMAT d3d12_get_closest_match(D3D12Device device, D3D12_FEATURE_DATA_FORMAT_SUPPORT* desired)
|
|
||||||
{
|
|
||||||
DXGI_FORMAT default_list[] = { desired->Format, DXGI_FORMAT_UNKNOWN };
|
|
||||||
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired->Format);
|
|
||||||
|
|
||||||
if (!format)
|
|
||||||
format = default_list;
|
|
||||||
|
|
||||||
while (*format != DXGI_FORMAT_UNKNOWN)
|
|
||||||
{
|
|
||||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { *format };
|
|
||||||
if (SUCCEEDED(D3D12CheckFeatureSupport(
|
|
||||||
device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, sizeof(format_support))) &&
|
|
||||||
((format_support.Support1 & desired->Support1) == desired->Support1) &&
|
|
||||||
((format_support.Support2 & desired->Support2) == desired->Support2))
|
|
||||||
break;
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
assert(*format);
|
|
||||||
return *format;
|
|
||||||
}
|
|
||||||
|
@ -736,25 +736,7 @@ D3D12GetGPUDescriptorHandleForHeapStart(D3D12DescriptorHeap descriptor_heap)
|
|||||||
|
|
||||||
RETRO_BEGIN_DECLS
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
extern D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc;
|
D3D12_CPU_DESCRIPTOR_HANDLE d3d12_descriptor_heap_slot_alloc(d3d12_descriptor_heap_t* heap);
|
||||||
extern D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc;
|
|
||||||
|
|
||||||
bool d3d12_init_base(d3d12_video_t* d3d12);
|
|
||||||
|
|
||||||
bool d3d12_init_descriptors(d3d12_video_t* d3d12);
|
|
||||||
void d3d12_init_samplers(d3d12_video_t* d3d12);
|
|
||||||
|
|
||||||
bool d3d12_init_pipeline(
|
|
||||||
D3D12Device device,
|
|
||||||
D3DBlob vs_code,
|
|
||||||
D3DBlob ps_code,
|
|
||||||
D3DBlob gs_code,
|
|
||||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC* desc,
|
|
||||||
D3D12PipelineState* out);
|
|
||||||
|
|
||||||
bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, void *corewindow);
|
|
||||||
|
|
||||||
bool d3d12_init_queue(d3d12_video_t* d3d12);
|
|
||||||
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS
|
D3D12_GPU_VIRTUAL_ADDRESS
|
||||||
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer);
|
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer);
|
||||||
@ -773,11 +755,6 @@ void d3d12_update_texture(
|
|||||||
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
||||||
d3d12_texture_t* texture, void *userdata);
|
d3d12_texture_t* texture, void *userdata);
|
||||||
|
|
||||||
void d3d12_create_fullscreen_quad_vbo(
|
|
||||||
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo);
|
|
||||||
|
|
||||||
DXGI_FORMAT d3d12_get_closest_match(D3D12Device device, D3D12_FEATURE_DATA_FORMAT_SUPPORT* desired);
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||||
static INLINE void d3d12_resource_transition(
|
static INLINE void d3d12_resource_transition(
|
||||||
D3D12GraphicsCommandList cmd,
|
D3D12GraphicsCommandList cmd,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
#include <string/stdstring.h>
|
#include <string/stdstring.h>
|
||||||
#include <file/file_path.h>
|
#include <file/file_path.h>
|
||||||
|
#include <encodings/utf.h>
|
||||||
#include <formats/image.h>
|
#include <formats/image.h>
|
||||||
|
|
||||||
#include <dxgi.h>
|
#include <dxgi.h>
|
||||||
@ -64,6 +65,34 @@
|
|||||||
#include "../../uwp/uwp_func.h"
|
#include "../../uwp/uwp_func.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc = {
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
D3D12_BLEND_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_INV_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_OP_ADD,
|
||||||
|
D3D12_BLEND_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_INV_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_OP_ADD,
|
||||||
|
D3D12_LOGIC_OP_NOOP,
|
||||||
|
D3D12_COLOR_WRITE_ENABLE_ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc = {
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
D3D12_BLEND_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_INV_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_OP_ADD,
|
||||||
|
D3D12_BLEND_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_INV_SRC_ALPHA,
|
||||||
|
D3D12_BLEND_OP_ADD,
|
||||||
|
D3D12_LOGIC_OP_NOOP,
|
||||||
|
D3D12_COLOR_WRITE_ENABLE_ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Temporary workaround for d3d12 not being able to poll flags during init */
|
/* Temporary workaround for d3d12 not being able to poll flags during init */
|
||||||
static gfx_ctx_driver_t d3d12_fake_context;
|
static gfx_ctx_driver_t d3d12_fake_context;
|
||||||
static uint32_t d3d12_get_flags(void *data);
|
static uint32_t d3d12_get_flags(void *data);
|
||||||
@ -511,6 +540,56 @@ static void d3d12_free_shader_preset(d3d12_video_t* d3d12)
|
|||||||
d3d12->resize_render_targets = false;
|
d3d12->resize_render_targets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void d3d12_init_pipeline(
|
||||||
|
D3D12Device device,
|
||||||
|
D3DBlob vs_code,
|
||||||
|
D3DBlob ps_code,
|
||||||
|
D3DBlob gs_code,
|
||||||
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC* desc,
|
||||||
|
D3D12PipelineState* out)
|
||||||
|
{
|
||||||
|
if (vs_code)
|
||||||
|
{
|
||||||
|
desc->VS.pShaderBytecode = D3DGetBufferPointer(vs_code);
|
||||||
|
desc->VS.BytecodeLength = D3DGetBufferSize(vs_code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc->VS.pShaderBytecode = NULL;
|
||||||
|
desc->VS.BytecodeLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps_code)
|
||||||
|
{
|
||||||
|
desc->PS.pShaderBytecode = D3DGetBufferPointer(ps_code);
|
||||||
|
desc->PS.BytecodeLength = D3DGetBufferSize(ps_code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc->PS.pShaderBytecode = NULL;
|
||||||
|
desc->PS.BytecodeLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gs_code)
|
||||||
|
{
|
||||||
|
desc->GS.pShaderBytecode = D3DGetBufferPointer(gs_code);
|
||||||
|
desc->GS.BytecodeLength = D3DGetBufferSize(gs_code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc->GS.pShaderBytecode = NULL;
|
||||||
|
desc->GS.BytecodeLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc->SampleMask = UINT_MAX;
|
||||||
|
desc->RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||||
|
desc->RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||||
|
desc->NumRenderTargets = 1;
|
||||||
|
desc->SampleDesc.Count = 1;
|
||||||
|
|
||||||
|
D3D12CreateGraphicsPipelineState(device, desc, out);
|
||||||
|
}
|
||||||
|
|
||||||
static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
|
static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
|
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
|
||||||
@ -621,8 +700,8 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const
|
|||||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pass[i].pipe)) { }
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pass[i].pipe);
|
||||||
|
|
||||||
free(d3d12->shader_preset->pass[i].source.string.vertex);
|
free(d3d12->shader_preset->pass[i].source.string.vertex);
|
||||||
free(d3d12->shader_preset->pass[i].source.string.fragment);
|
free(d3d12->shader_preset->pass[i].source.string.fragment);
|
||||||
@ -765,10 +844,9 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc,
|
d3d12->device, vs_code, ps_code, NULL, &desc,
|
||||||
&d3d12->pipes[VIDEO_SHADER_STOCK_HDR]))
|
&d3d12->pipes[VIDEO_SHADER_STOCK_HDR]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -803,10 +881,9 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc,
|
d3d12->device, vs_code, ps_code, NULL, &desc,
|
||||||
&d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]))
|
&d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -847,14 +924,12 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_noblend))
|
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_noblend);
|
||||||
goto error;
|
|
||||||
|
|
||||||
desc.BlendState.RenderTarget[0].BlendEnable = true;
|
desc.BlendState.RenderTarget[0].BlendEnable = true;
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_blend))
|
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_blend);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
ps_code = NULL;
|
ps_code = NULL;
|
||||||
@ -862,9 +937,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(shader, sizeof(shader), NULL, "PSMainA8", "ps_5_0", &ps_code))
|
if (!d3d_compile(shader, sizeof(shader), NULL, "PSMainA8", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_font))
|
d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_font);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -900,9 +974,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -914,9 +987,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_2]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_2]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -954,9 +1026,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_3]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_3]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -968,9 +1039,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(snow, sizeof(snow), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(snow, sizeof(snow), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_4]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_4]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -982,9 +1052,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_5]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_5]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -996,9 +1065,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
d3d12_init_pipeline(
|
||||||
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_6]))
|
d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_6]);
|
||||||
goto error;
|
|
||||||
|
|
||||||
Release(vs_code);
|
Release(vs_code);
|
||||||
Release(ps_code);
|
Release(ps_code);
|
||||||
@ -1126,6 +1194,503 @@ static void d3d12_gfx_free(void* data)
|
|||||||
free(d3d12);
|
free(d3d12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||||
|
int width, int height, void* corewindow)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
HRESULT hr;
|
||||||
|
HWND hwnd = (HWND)corewindow;
|
||||||
|
#ifdef __WINRT__
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 desc = {{0}};
|
||||||
|
#else
|
||||||
|
DXGI_SWAP_CHAIN_DESC desc = {{0}};
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DXGI_HDR
|
||||||
|
DXGI_COLOR_SPACE_TYPE color_space;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DXGI_HDR
|
||||||
|
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_8] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_10] = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
|
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||||
|
|
||||||
|
if (!(d3d12->hdr.support =
|
||||||
|
dxgi_check_display_hdr_support(d3d12->factory, hwnd)))
|
||||||
|
d3d12->hdr.enable = false;
|
||||||
|
|
||||||
|
d3d12->chain.bit_depth = d3d12->hdr.enable
|
||||||
|
? DXGI_SWAPCHAIN_BIT_DEPTH_10
|
||||||
|
: DXGI_SWAPCHAIN_BIT_DEPTH_8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
desc.BufferCount = countof(d3d12->chain.renderTargets);
|
||||||
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
#ifdef __WINRT__
|
||||||
|
desc.Width = width;
|
||||||
|
desc.Height = height;
|
||||||
|
#else
|
||||||
|
desc.BufferDesc.Width = width;
|
||||||
|
desc.BufferDesc.Height = height;
|
||||||
|
desc.BufferDesc.RefreshRate.Numerator = 0;
|
||||||
|
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DXGI_HDR
|
||||||
|
#ifdef __WINRT__
|
||||||
|
desc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
||||||
|
#else
|
||||||
|
desc.BufferDesc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef __WINRT__
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
#else
|
||||||
|
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
#ifdef HAVE_WINDOW
|
||||||
|
desc.OutputWindow = hwnd;
|
||||||
|
desc.Windowed = TRUE;
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||||
|
#else
|
||||||
|
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
|
#endif
|
||||||
|
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||||
|
|
||||||
|
#ifdef __WINRT__
|
||||||
|
hr = DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle);
|
||||||
|
#else
|
||||||
|
hr = DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle);
|
||||||
|
#endif
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D12]: Failed to create the swap chain (0x%08X)\n", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOW
|
||||||
|
DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DXGI_HDR
|
||||||
|
/* Check display HDR support and
|
||||||
|
initialize ST.2084 support to match
|
||||||
|
the display's support. */
|
||||||
|
color_space =
|
||||||
|
d3d12->hdr.enable
|
||||||
|
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
||||||
|
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||||
|
|
||||||
|
dxgi_swapchain_color_space(d3d12->chain.handle,
|
||||||
|
&d3d12->chain.color_space, color_space);
|
||||||
|
dxgi_set_hdr_metadata(
|
||||||
|
d3d12->chain.handle,
|
||||||
|
d3d12->hdr.support,
|
||||||
|
d3d12->chain.bit_depth,
|
||||||
|
d3d12->chain.color_space,
|
||||||
|
d3d12->hdr.max_output_nits,
|
||||||
|
d3d12->hdr.min_output_nits,
|
||||||
|
d3d12->hdr.max_cll,
|
||||||
|
d3d12->hdr.max_fall);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
||||||
|
|
||||||
|
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
||||||
|
{
|
||||||
|
DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]);
|
||||||
|
D3D12CreateRenderTargetView(
|
||||||
|
d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DXGI_HDR
|
||||||
|
memset(&d3d12->chain.back_buffer,
|
||||||
|
0, sizeof(d3d12->chain.back_buffer));
|
||||||
|
d3d12->chain.back_buffer.desc.Width = width;
|
||||||
|
d3d12->chain.back_buffer.desc.Height = height;
|
||||||
|
d3d12->chain.back_buffer.desc.Format =
|
||||||
|
d3d12->shader_preset && d3d12->shader_preset->passes ? glslang_format_to_dxgi(d3d12->pass[d3d12->shader_preset->passes - 1].semantics.format) : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
d3d12->chain.back_buffer.desc.Flags =
|
||||||
|
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
|
d3d12->chain.back_buffer.srv_heap =
|
||||||
|
&d3d12->desc.srv_heap;
|
||||||
|
d3d12->chain.back_buffer.rt_view.ptr =
|
||||||
|
d3d12->desc.rtv_heap.cpu.ptr
|
||||||
|
+ (countof(d3d12->chain.renderTargets))
|
||||||
|
* d3d12->desc.rtv_heap.stride;
|
||||||
|
d3d12_init_texture(d3d12->device, &d3d12->chain.back_buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
d3d12->chain.viewport.Width = width;
|
||||||
|
d3d12->chain.viewport.Height = height;
|
||||||
|
d3d12->chain.scissorRect.right = width;
|
||||||
|
d3d12->chain.scissorRect.bottom = height;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_init_base(d3d12_video_t* d3d12)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
DXGIAdapter adapter = NULL;
|
||||||
|
#ifdef DEBUG
|
||||||
|
#ifdef __WINRT__
|
||||||
|
if (SUCCEEDED(D3D12GetDebugInterface_(&d3d12->debugController)))
|
||||||
|
d3d12->debugController->lpVtbl->EnableDebugLayer(&d3d12->debugController);
|
||||||
|
#else
|
||||||
|
if (SUCCEEDED(D3D12GetDebugInterface_(&d3d12->debugController)))
|
||||||
|
d3d12->debugController->lpVtbl->EnableDebugLayer(d3d12->debugController);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINRT__
|
||||||
|
DXGICreateFactory2(&d3d12->factory);
|
||||||
|
#else
|
||||||
|
DXGICreateFactory(&d3d12->factory);
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
int gpu_index = settings->ints.d3d12_gpu_index;
|
||||||
|
|
||||||
|
if (d3d12->gpu_list)
|
||||||
|
string_list_free(d3d12->gpu_list);
|
||||||
|
|
||||||
|
d3d12->gpu_list = string_list_new();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char str[128];
|
||||||
|
union string_list_elem_attr attr = {0};
|
||||||
|
DXGI_ADAPTER_DESC desc = {0};
|
||||||
|
|
||||||
|
str[0] = '\0';
|
||||||
|
|
||||||
|
#ifdef __WINRT__
|
||||||
|
if (FAILED(DXGIEnumAdapters2(d3d12->factory, i, &adapter)))
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
if (FAILED(DXGIEnumAdapters(d3d12->factory, i, &adapter)))
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
adapter->GetDesc(adapter, &desc);
|
||||||
|
#else
|
||||||
|
adapter->lpVtbl->GetDesc(adapter, &desc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
utf16_to_char_string((const uint16_t*)desc.Description, str, sizeof(str));
|
||||||
|
|
||||||
|
RARCH_LOG("[D3D12]: Found GPU at index %d: \"%s\".\n", i, str);
|
||||||
|
|
||||||
|
string_list_append(d3d12->gpu_list, str, attr);
|
||||||
|
|
||||||
|
if (i < D3D12_MAX_GPU_COUNT)
|
||||||
|
{
|
||||||
|
AddRef(adapter);
|
||||||
|
d3d12->adapters[i] = adapter;
|
||||||
|
}
|
||||||
|
Release(adapter);
|
||||||
|
adapter = NULL;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (i >= D3D12_MAX_GPU_COUNT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D12_API, d3d12->gpu_list);
|
||||||
|
|
||||||
|
if (0 <= gpu_index && gpu_index <= i && gpu_index < D3D12_MAX_GPU_COUNT)
|
||||||
|
{
|
||||||
|
d3d12->adapter = d3d12->adapters[gpu_index];
|
||||||
|
AddRef(d3d12->adapter);
|
||||||
|
RARCH_LOG("[D3D12]: Using GPU index %d.\n", gpu_index);
|
||||||
|
video_driver_set_gpu_device_string(
|
||||||
|
d3d12->gpu_list->elems[gpu_index].data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RARCH_WARN("[D3D12]: Invalid GPU index %d, using first device found.\n", gpu_index);
|
||||||
|
d3d12->adapter = d3d12->adapters[0];
|
||||||
|
AddRef(d3d12->adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device)))
|
||||||
|
RARCH_WARN("[D3D12]: Could not create D3D12 device.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void d3d12_release_descriptor_heap(d3d12_descriptor_heap_t* heap)
|
||||||
|
{
|
||||||
|
free(heap->map);
|
||||||
|
Release(heap->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_init_descriptor_heap(D3D12Device device, d3d12_descriptor_heap_t* out)
|
||||||
|
{
|
||||||
|
D3D12CreateDescriptorHeap(device, &out->desc, &out->handle);
|
||||||
|
out->cpu = D3D12GetCPUDescriptorHandleForHeapStart(out->handle);
|
||||||
|
out->gpu = D3D12GetGPUDescriptorHandleForHeapStart(out->handle);
|
||||||
|
out->stride = D3D12GetDescriptorHandleIncrementSize(device, out->desc.Type);
|
||||||
|
out->map = (bool*)calloc(out->desc.NumDescriptors, sizeof(bool));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool d3d12_create_root_signature(
|
||||||
|
D3D12Device device, D3D12_ROOT_SIGNATURE_DESC* desc, D3D12RootSignature* out)
|
||||||
|
{
|
||||||
|
D3DBlob signature;
|
||||||
|
D3DBlob error;
|
||||||
|
D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
RARCH_ERR(
|
||||||
|
"[D3D12]: CreateRootSignature failed : %s", (const char*)D3DGetBufferPointer(error));
|
||||||
|
Release(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12CreateRootSignature(
|
||||||
|
device, 0, D3DGetBufferPointer(signature), D3DGetBufferSize(signature), out);
|
||||||
|
Release(signature);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void d3d12_init_descriptors(d3d12_video_t* d3d12)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
D3D12_ROOT_SIGNATURE_DESC desc;
|
||||||
|
D3D12_DESCRIPTOR_RANGE srv_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1 } };
|
||||||
|
D3D12_DESCRIPTOR_RANGE uav_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1 } };
|
||||||
|
D3D12_DESCRIPTOR_RANGE sampler_tbl[1] = { { D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1 } };
|
||||||
|
D3D12_STATIC_SAMPLER_DESC static_sampler = { D3D12_FILTER_MIN_MAG_MIP_POINT };
|
||||||
|
D3D12_ROOT_PARAMETER root_params[ROOT_ID_MAX];
|
||||||
|
D3D12_ROOT_PARAMETER cs_root_params[CS_ROOT_ID_MAX];
|
||||||
|
|
||||||
|
root_params[ROOT_ID_TEXTURE_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
root_params[ROOT_ID_TEXTURE_T].DescriptorTable.NumDescriptorRanges = countof(srv_tbl);
|
||||||
|
root_params[ROOT_ID_TEXTURE_T].DescriptorTable.pDescriptorRanges = srv_tbl;
|
||||||
|
root_params[ROOT_ID_TEXTURE_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
|
||||||
|
root_params[ROOT_ID_SAMPLER_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
root_params[ROOT_ID_SAMPLER_T].DescriptorTable.NumDescriptorRanges = countof(sampler_tbl);
|
||||||
|
root_params[ROOT_ID_SAMPLER_T].DescriptorTable.pDescriptorRanges = sampler_tbl;
|
||||||
|
root_params[ROOT_ID_SAMPLER_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
|
||||||
|
root_params[ROOT_ID_UBO].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
||||||
|
root_params[ROOT_ID_UBO].Descriptor.RegisterSpace = 0;
|
||||||
|
root_params[ROOT_ID_UBO].Descriptor.ShaderRegister = 0;
|
||||||
|
root_params[ROOT_ID_UBO].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||||
|
|
||||||
|
root_params[ROOT_ID_PC].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
||||||
|
root_params[ROOT_ID_PC].Descriptor.RegisterSpace = 0;
|
||||||
|
root_params[ROOT_ID_PC].Descriptor.ShaderRegister = 1;
|
||||||
|
root_params[ROOT_ID_PC].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||||
|
|
||||||
|
desc.NumParameters = countof(root_params);
|
||||||
|
desc.pParameters = root_params;
|
||||||
|
desc.NumStaticSamplers = 0;
|
||||||
|
desc.pStaticSamplers = NULL;
|
||||||
|
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
||||||
|
|
||||||
|
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.rootSignature);
|
||||||
|
|
||||||
|
srv_tbl[0].NumDescriptors = SLANG_NUM_BINDINGS;
|
||||||
|
sampler_tbl[0].NumDescriptors = SLANG_NUM_BINDINGS;
|
||||||
|
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.sl_rootSignature);
|
||||||
|
|
||||||
|
cs_root_params[CS_ROOT_ID_TEXTURE_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.NumDescriptorRanges = countof(srv_tbl);
|
||||||
|
cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.pDescriptorRanges = srv_tbl;
|
||||||
|
cs_root_params[CS_ROOT_ID_TEXTURE_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||||
|
|
||||||
|
cs_root_params[CS_ROOT_ID_UAV_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.NumDescriptorRanges = countof(uav_tbl);
|
||||||
|
cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.pDescriptorRanges = uav_tbl;
|
||||||
|
cs_root_params[CS_ROOT_ID_UAV_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||||
|
|
||||||
|
cs_root_params[CS_ROOT_ID_CONSTANTS].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
||||||
|
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.Num32BitValues = 3;
|
||||||
|
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.RegisterSpace = 0;
|
||||||
|
cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.ShaderRegister = 0;
|
||||||
|
cs_root_params[CS_ROOT_ID_CONSTANTS].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||||
|
|
||||||
|
static_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
static_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
static_sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
#if 0
|
||||||
|
static_sampler.MaxAnisotropy = 1;
|
||||||
|
static_sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
||||||
|
static_sampler.MinLOD = -D3D12_FLOAT32_MAX;
|
||||||
|
static_sampler.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
desc.NumParameters = countof(cs_root_params);
|
||||||
|
desc.pParameters = cs_root_params;
|
||||||
|
desc.NumStaticSamplers = 1;
|
||||||
|
desc.pStaticSamplers = &static_sampler;
|
||||||
|
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
|
||||||
|
|
||||||
|
d3d12_create_root_signature(d3d12->device, &desc, &d3d12->desc.cs_rootSignature);
|
||||||
|
|
||||||
|
d3d12->desc.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
d3d12->desc.rtv_heap.desc.NumDescriptors = countof(d3d12->chain.renderTargets) + GFX_MAX_SHADERS * 2;
|
||||||
|
d3d12->desc.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.rtv_heap);
|
||||||
|
|
||||||
|
d3d12->desc.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||||
|
d3d12->desc.srv_heap.desc.NumDescriptors = SLANG_NUM_BINDINGS * GFX_MAX_SHADERS + 2048;
|
||||||
|
d3d12->desc.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||||
|
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.srv_heap);
|
||||||
|
|
||||||
|
d3d12->desc.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
|
||||||
|
d3d12->desc.sampler_heap.desc.NumDescriptors =
|
||||||
|
SLANG_NUM_BINDINGS * GFX_MAX_SHADERS + 2 * RARCH_WRAP_MAX;
|
||||||
|
d3d12->desc.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||||
|
d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.sampler_heap);
|
||||||
|
|
||||||
|
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
||||||
|
{
|
||||||
|
d3d12->chain.desc_handles[i].ptr =
|
||||||
|
d3d12->desc.rtv_heap.cpu.ptr + i * d3d12->desc.rtv_heap.stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < GFX_MAX_SHADERS; i++)
|
||||||
|
{
|
||||||
|
d3d12->pass[i].rt.rt_view.ptr =
|
||||||
|
d3d12->desc.rtv_heap.cpu.ptr +
|
||||||
|
(countof(d3d12->chain.renderTargets) + (2 * i)) * d3d12->desc.rtv_heap.stride;
|
||||||
|
d3d12->pass[i].feedback.rt_view.ptr = d3d12->pass[i].rt.rt_view.ptr + d3d12->desc.rtv_heap.stride;
|
||||||
|
|
||||||
|
d3d12->pass[i].textures.ptr = d3d12_descriptor_heap_slot_alloc(&d3d12->desc.srv_heap).ptr -
|
||||||
|
d3d12->desc.srv_heap.cpu.ptr + d3d12->desc.srv_heap.gpu.ptr;
|
||||||
|
d3d12->pass[i].samplers.ptr =
|
||||||
|
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.sampler_heap).ptr -
|
||||||
|
d3d12->desc.sampler_heap.cpu.ptr + d3d12->desc.sampler_heap.gpu.ptr;
|
||||||
|
|
||||||
|
for (j = 1; j < SLANG_NUM_BINDINGS; j++)
|
||||||
|
{
|
||||||
|
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.srv_heap);
|
||||||
|
d3d12_descriptor_heap_slot_alloc(&d3d12->desc.sampler_heap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE D3D12_GPU_DESCRIPTOR_HANDLE
|
||||||
|
d3d12_create_sampler(D3D12Device device, D3D12_SAMPLER_DESC* desc, d3d12_descriptor_heap_t* heap)
|
||||||
|
{
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = d3d12_descriptor_heap_slot_alloc(heap);
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = { cpu_handle.ptr - heap->cpu.ptr + heap->gpu.ptr };
|
||||||
|
|
||||||
|
D3D12CreateSampler(device, desc, cpu_handle);
|
||||||
|
return gpu_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_init_samplers(d3d12_video_t* d3d12)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_POINT };
|
||||||
|
desc.MaxAnisotropy = 1;
|
||||||
|
desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
||||||
|
desc.MinLOD = -D3D12_FLOAT32_MAX;
|
||||||
|
desc.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
|
|
||||||
|
for (i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case RARCH_WRAP_BORDER:
|
||||||
|
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RARCH_WRAP_EDGE:
|
||||||
|
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RARCH_WRAP_REPEAT:
|
||||||
|
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||||
|
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
desc.AddressV = desc.AddressU;
|
||||||
|
desc.AddressW = desc.AddressU;
|
||||||
|
|
||||||
|
desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
d3d12->samplers[RARCH_FILTER_LINEAR][i] =
|
||||||
|
d3d12_create_sampler(d3d12->device, &desc, &d3d12->desc.sampler_heap);
|
||||||
|
|
||||||
|
desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
d3d12->samplers[RARCH_FILTER_NEAREST][i] =
|
||||||
|
d3d12_create_sampler(d3d12->device, &desc, &d3d12->desc.sampler_heap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_init_queue(d3d12_video_t* d3d12)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
static const D3D12_COMMAND_QUEUE_DESC desc = {
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
0,
|
||||||
|
D3D12_COMMAND_QUEUE_FLAG_NONE,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
D3D12CreateCommandQueue(
|
||||||
|
d3d12->device,
|
||||||
|
(D3D12_COMMAND_QUEUE_DESC*)&desc,
|
||||||
|
&d3d12->queue.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12CreateCommandAllocator(
|
||||||
|
d3d12->device,
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
&d3d12->queue.allocator);
|
||||||
|
|
||||||
|
D3D12CreateGraphicsCommandList(
|
||||||
|
d3d12->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, d3d12->queue.allocator,
|
||||||
|
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND], &d3d12->queue.cmd);
|
||||||
|
|
||||||
|
D3D12CloseGraphicsCommandList(d3d12->queue.cmd);
|
||||||
|
|
||||||
|
D3D12CreateFence(d3d12->device, 0, D3D12_FENCE_FLAG_NONE, &d3d12->queue.fence);
|
||||||
|
d3d12->queue.fenceValue = 0;
|
||||||
|
d3d12->queue.fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_create_fullscreen_quad_vbo(
|
||||||
|
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo)
|
||||||
|
{
|
||||||
|
void *vertex_data_begin = NULL;
|
||||||
|
D3D12_RANGE read_range = { 0, 0 };
|
||||||
|
static const d3d12_vertex_t vertices[] = {
|
||||||
|
{ { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
||||||
|
{ { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
||||||
|
{ { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
||||||
|
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
|
||||||
|
};
|
||||||
|
|
||||||
|
view->SizeInBytes = sizeof(vertices);
|
||||||
|
view->StrideInBytes = sizeof(*vertices);
|
||||||
|
view->BufferLocation = d3d12_create_buffer(device, view->SizeInBytes, vbo);
|
||||||
|
|
||||||
|
D3D12Map(*vbo, 0, &read_range, &vertex_data_begin);
|
||||||
|
memcpy(vertex_data_begin, vertices, sizeof(vertices));
|
||||||
|
D3D12Unmap(*vbo, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void *d3d12_gfx_init(const video_info_t* video,
|
static void *d3d12_gfx_init(const video_info_t* video,
|
||||||
input_driver_t** input, void** input_data)
|
input_driver_t** input, void** input_data)
|
||||||
{
|
{
|
||||||
@ -1187,17 +1752,13 @@ static void *d3d12_gfx_init(const video_info_t* video,
|
|||||||
|
|
||||||
d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data);
|
d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data);
|
||||||
|
|
||||||
if (!d3d12_init_base(d3d12))
|
d3d12_init_base(d3d12);
|
||||||
goto error;
|
d3d12_init_descriptors(d3d12);
|
||||||
|
|
||||||
if (!d3d12_init_descriptors(d3d12))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!d3d12_gfx_init_pipelines(d3d12))
|
if (!d3d12_gfx_init_pipelines(d3d12))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_queue(d3d12))
|
d3d12_init_queue(d3d12);
|
||||||
goto error;
|
|
||||||
|
|
||||||
#ifdef __WINRT__
|
#ifdef __WINRT__
|
||||||
if (!d3d12_init_swapchain(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, uwp_get_corewindow()))
|
if (!d3d12_init_swapchain(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, uwp_get_corewindow()))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user