diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 678e73d782..65899722d8 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -75,16 +75,15 @@ HRESULT WINAPI D3D12CreateDevice( d3d12_dll = dylib_load(d3d12_dll_name); if (!d3d12_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (PFN_D3D12_CREATE_DEVICE)dylib_proc(d3d12_dll, "D3D12CreateDevice"); - if (fp) - return fp(pAdapter, MinimumFeatureLevel, riid, ppDevice); + if (!fp) + return TYPE_E_DLLFUNCTIONNOTFOUND; -error: - return TYPE_E_CANTLOADLIBRARY; + return fp(pAdapter, MinimumFeatureLevel, riid, ppDevice); } HRESULT WINAPI D3D12GetDebugInterface(REFIID riid, void** ppvDebug) @@ -94,16 +93,15 @@ HRESULT WINAPI D3D12GetDebugInterface(REFIID riid, void** ppvDebug) d3d12_dll = dylib_load(d3d12_dll_name); if (!d3d12_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (PFN_D3D12_GET_DEBUG_INTERFACE)dylib_proc(d3d12_dll, "D3D12GetDebugInterface"); - if (fp) - return fp(riid, ppvDebug); + if (!fp) + return TYPE_E_DLLFUNCTIONNOTFOUND; -error: - return TYPE_E_CANTLOADLIBRARY; + return fp(riid, ppvDebug); } HRESULT WINAPI D3D12SerializeRootSignature( @@ -117,16 +115,15 @@ HRESULT WINAPI D3D12SerializeRootSignature( d3d12_dll = dylib_load(d3d12_dll_name); if (!d3d12_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)dylib_proc(d3d12_dll, "D3D12SerializeRootSignature"); - if (fp) - return fp(pRootSignature, Version, ppBlob, ppErrorBlob); + if (!fp) + return TYPE_E_DLLFUNCTIONNOTFOUND; -error: - return TYPE_E_CANTLOADLIBRARY; + return fp(pRootSignature, Version, ppBlob, ppErrorBlob); } HRESULT WINAPI D3D12SerializeVersionedRootSignature( @@ -139,17 +136,16 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature( d3d12_dll = dylib_load(d3d12_dll_name); if (!d3d12_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)dylib_proc( d3d12_dll, "D3D12SerializeRootSignature"); - if (fp) - return fp(pRootSignature, ppBlob, ppErrorBlob); + if (!fp) + return TYPE_E_DLLFUNCTIONNOTFOUND; -error: - return TYPE_E_CANTLOADLIBRARY; + return fp(pRootSignature, ppBlob, ppErrorBlob); } #endif @@ -195,7 +191,7 @@ bool d3d12_init_queue(d3d12_video_t* d3d12) D3D12CreateGraphicsCommandList( d3d12->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, d3d12->queue.allocator, - d3d12->pipe.handle, &d3d12->queue.cmd); + d3d12->pipes[VIDEO_SHADER_STOCK_BLEND], &d3d12->queue.cmd); D3D12CloseGraphicsCommandList(d3d12->queue.cmd); @@ -238,7 +234,7 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, HWND hwnd for (int i = 0; i < countof(d3d12->chain.renderTargets); i++) { d3d12->chain.desc_handles[i].ptr = - d3d12->pipe.rtv_heap.cpu.ptr + i * d3d12->pipe.rtv_heap.stride; + d3d12->desc.rtv_heap.cpu.ptr + i * d3d12->desc.rtv_heap.stride; DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]); D3D12CreateRenderTargetView( d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]); @@ -297,7 +293,7 @@ bool d3d12_init_descriptors(d3d12_video_t* d3d12) rootParameters[ROOT_ID_UBO].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; rootParameters[ROOT_ID_UBO].Descriptor.RegisterSpace = 0; rootParameters[ROOT_ID_UBO].Descriptor.ShaderRegister = 0; - rootParameters[ROOT_ID_UBO].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + rootParameters[ROOT_ID_UBO].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; desc.NumParameters = countof(rootParameters); desc.pParameters = rootParameters; @@ -321,24 +317,24 @@ bool d3d12_init_descriptors(d3d12_video_t* d3d12) D3D12CreateRootSignature( d3d12->device, 0, D3DGetBufferPointer(signature), D3DGetBufferSize(signature), - &d3d12->pipe.rootSignature); + &d3d12->desc.rootSignature); Release(signature); } - d3d12->pipe.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - d3d12->pipe.rtv_heap.desc.NumDescriptors = countof(d3d12->chain.renderTargets); - d3d12->pipe.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.rtv_heap); + d3d12->desc.rtv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + d3d12->desc.rtv_heap.desc.NumDescriptors = countof(d3d12->chain.renderTargets); + d3d12->desc.rtv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.rtv_heap); - d3d12->pipe.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - d3d12->pipe.srv_heap.desc.NumDescriptors = SRV_HEAP_SLOT_MAX; - d3d12->pipe.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.srv_heap); + d3d12->desc.srv_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + d3d12->desc.srv_heap.desc.NumDescriptors = SRV_HEAP_SLOT_MAX; + d3d12->desc.srv_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + d3d12_init_descriptor_heap(d3d12->device, &d3d12->desc.srv_heap); - d3d12->pipe.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - d3d12->pipe.sampler_heap.desc.NumDescriptors = 2 * RARCH_WRAP_MAX; - d3d12->pipe.sampler_heap.desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - d3d12_init_descriptor_heap(d3d12->device, &d3d12->pipe.sampler_heap); + d3d12->desc.sampler_heap.desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + d3d12->desc.sampler_heap.desc.NumDescriptors = 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); return true; } @@ -377,12 +373,12 @@ void d3d12_init_samplers(d3d12_video_t* d3d12) desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; d3d12->samplers[RARCH_FILTER_LINEAR][i] = d3d12_create_sampler( - d3d12->device, &desc, &d3d12->pipe.sampler_heap, + d3d12->device, &desc, &d3d12->desc.sampler_heap, 0 * RARCH_WRAP_MAX + i); desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; d3d12->samplers[RARCH_FILTER_NEAREST][i] = d3d12_create_sampler( - d3d12->device, &desc, &d3d12->pipe.sampler_heap, + d3d12->device, &desc, &d3d12->desc.sampler_heap, 1 * RARCH_WRAP_MAX + i); } } @@ -413,18 +409,33 @@ bool d3d12_init_pipeline( 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; diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 6db62700fb..e372306a06 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -1255,6 +1255,7 @@ D3D12GetGPUDescriptorHandleForHeapStart(D3D12DescriptorHeap descriptor_heap) #include "../common/d3dcompiler_common.h" #include "../video_driver.h" +#include "../drivers_shader/slang_process.h" typedef struct d3d12_vertex_t { @@ -1263,6 +1264,24 @@ typedef struct d3d12_vertex_t float color[4]; } d3d12_vertex_t; +typedef struct +{ + struct + { + float x, y, w, h; + } pos; + struct + { + float u, v, w, h; + } coords; + UINT32 colors[4]; + struct + { + float scaling; + float rotation; + } params; +} d3d12_sprite_t; + typedef struct { D3D12DescriptorHeap handle; /* descriptor pool */ @@ -1306,12 +1325,11 @@ typedef struct struct { - D3D12PipelineState handle; D3D12RootSignature rootSignature; /* descriptor layout */ d3d12_descriptor_heap_t srv_heap; /* ShaderResouceView descritor heap */ d3d12_descriptor_heap_t rtv_heap; /* RenderTargetView descritor heap */ d3d12_descriptor_heap_t sampler_heap; - } pipe; + } desc; struct { @@ -1348,6 +1366,17 @@ typedef struct bool fullscreen; } menu; + struct + { + D3D12PipelineState pipe; + D3D12PipelineState pipe_font; + D3D12Resource vbo; + int offset; + int capacity; + bool enabled; + } sprites; + + D3D12PipelineState pipes[GFX_MAX_SHADERS]; D3D12Resource ubo; D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view; DXGI_FORMAT format; diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index c1beed26cf..0a2515c72f 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -30,7 +30,7 @@ static void d3d12_set_filtering(void* data, unsigned index, bool smooth) { - int i; + int i; d3d12_video_t* d3d12 = (d3d12_video_t*)data; for (i = 0; i < RARCH_WRAP_MAX; i++) @@ -49,7 +49,7 @@ static void d3d12_gfx_set_rotation(void* data, unsigned rotation) D3D12_RANGE read_range = { 0, 0 }; d3d12_video_t* d3d12 = (d3d12_video_t*)data; - if(!d3d12) + if (!d3d12) return; d3d12->frame.rotation = rotation; @@ -84,12 +84,299 @@ static void d3d12_update_viewport(void* data, bool force_full) d3d12->resize_viewport = false; } - static void* +static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12) +{ + D3DBlob vs_code = NULL; + D3DBlob ps_code = NULL; + D3DBlob gs_code = NULL; + D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = { 0 }; + + desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc; + desc.pRootSignature = d3d12->desc.rootSignature; + desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + + { + static const char shader[] = +#include "../drivers/d3d_shaders/opaque_sm5.hlsl.h" + ; + + static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_vertex_t, color), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + if (!d3d_compile(shader, sizeof(shader), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(shader, sizeof(shader), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_STOCK_BLEND])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + } + { + static const char shader[] = +#include "d3d_shaders/sprite_sm4.hlsl.h" + ; + + D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_sprite_t, pos), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_sprite_t, coords), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d12_sprite_t, colors[0]), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d12_sprite_t, colors[1]), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d12_sprite_t, colors[2]), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d12_sprite_t, colors[3]), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "PARAMS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_sprite_t, params), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + if (!d3d_compile(shader, sizeof(shader), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(shader, sizeof(shader), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + if (!d3d_compile(shader, sizeof(shader), NULL, "GSMain", "gs_5_0", &gs_code)) + goto error; + + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe)) + goto error; + + Release(ps_code); + ps_code = NULL; + + if (!d3d_compile(shader, sizeof(shader), NULL, "PSMainA8", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, gs_code, &desc, &d3d12->sprites.pipe_font)) + goto error; + + Release(vs_code); + Release(ps_code); + Release(gs_code); + vs_code = NULL; + ps_code = NULL; + gs_code = NULL; + } + + { + static const char simple_snow[] = +#include "d3d_shaders/simple_snow_sm4.hlsl.h" + ; + static const char snow[] = +#include "d3d_shaders/snow_sm4.hlsl.h" + ; + static const char bokeh[] = +#include "d3d_shaders/bokeh_sm4.hlsl.h" + ; + static const char snowflake[] = +#include "d3d_shaders/snowflake_sm4.hlsl.h" + ; + + D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); + + if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU_3])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(snow, sizeof(snow), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(snow, sizeof(snow), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU_4])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU_5])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU_6])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + } + + { + static const char ribbon[] = +#include "d3d_shaders/ribbon_sm4.hlsl.h" + ; + static const char ribbon_simple[] = +#include "d3d_shaders/ribbon_simple_sm4.hlsl.h" + ; + + D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; + desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); + + if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(ribbon_simple, sizeof(ribbon), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(ribbon_simple, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_MENU_2])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + } + + return true; + +error: + Release(vs_code); + Release(ps_code); + Release(gs_code); + return false; +} + +static void d3d12_gfx_free(void* data) +{ + unsigned i; + d3d12_video_t* d3d12 = (d3d12_video_t*)data; + + Release(d3d12->frame.ubo); + Release(d3d12->frame.vbo); + Release(d3d12->frame.texture.handle); + Release(d3d12->frame.texture.upload_buffer); + Release(d3d12->menu.vbo); + Release(d3d12->menu.texture.handle); + Release(d3d12->menu.texture.upload_buffer); + + Release(d3d12->ubo); + Release(d3d12->desc.sampler_heap.handle); + Release(d3d12->desc.srv_heap.handle); + Release(d3d12->desc.rtv_heap.handle); + Release(d3d12->desc.rootSignature); + + for (i = 0; i < GFX_MAX_SHADERS; i++) + Release(d3d12->pipes[i]); + + Release(d3d12->sprites.pipe); + Release(d3d12->sprites.pipe_font); + + Release(d3d12->queue.fence); + Release(d3d12->chain.renderTargets[0]); + Release(d3d12->chain.renderTargets[1]); + Release(d3d12->chain.handle); + + Release(d3d12->queue.cmd); + Release(d3d12->queue.allocator); + Release(d3d12->queue.handle); + + Release(d3d12->factory); + Release(d3d12->device); + Release(d3d12->adapter); + + win32_monitor_from_window(); + win32_destroy_window(); + + free(d3d12); +} + +static void* d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { - WNDCLASSEX wndclass = { 0 }; - settings_t* settings = config_get_ptr(); - d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12)); + WNDCLASSEX wndclass = { 0 }; + settings_t* settings = config_get_ptr(); + d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12)); if (!d3d12) return NULL; @@ -113,45 +400,8 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i if (!d3d12_init_descriptors(d3d12)) goto error; - { - bool success = false; - D3DBlob vs_code = NULL; - D3DBlob ps_code = NULL; - D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = { 0 }; - - static const char shader[] = -#include "../drivers/d3d_shaders/opaque_sm5.hlsl.h" - ; - - static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_vertex_t, color), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - }; - - desc.pRootSignature = d3d12->pipe.rootSignature; - desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc; - desc.InputLayout.pInputElementDescs = inputElementDesc; - desc.InputLayout.NumElements = countof(inputElementDesc); - desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - - d3d_compile(shader, sizeof(shader), NULL, "VSMain", "vs_5_0", &vs_code); - d3d_compile(shader, sizeof(shader), NULL, "PSMain", "ps_5_0", &ps_code); - - if (vs_code && ps_code) - success = d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipe.handle); - - Release(vs_code); - Release(ps_code); - - if(!success) - goto error; - } + if (!d3d12_gfx_init_pipelines(d3d12)) + goto error; if (!d3d12_init_queue(d3d12)) goto error; @@ -169,15 +419,15 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d12->chain.vsync = video->vsync; d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; d3d12->frame.texture.desc.Format = - d3d12_get_closest_match_texture2D(d3d12->device, d3d12->format); + d3d12_get_closest_match_texture2D(d3d12->device, d3d12->format); d3d12->ubo_view.SizeInBytes = sizeof(math_matrix_4x4); d3d12->ubo_view.BufferLocation = - d3d12_create_buffer(d3d12->device, d3d12->ubo_view.SizeInBytes, &d3d12->ubo); + d3d12_create_buffer(d3d12->device, d3d12->ubo_view.SizeInBytes, &d3d12->ubo); d3d12->frame.ubo_view.SizeInBytes = sizeof(math_matrix_4x4); d3d12->frame.ubo_view.BufferLocation = - d3d12_create_buffer(d3d12->device, d3d12->frame.ubo_view.SizeInBytes, &d3d12->frame.ubo); + d3d12_create_buffer(d3d12->device, d3d12->frame.ubo_view.SizeInBytes, &d3d12->frame.ubo); matrix_4x4_ortho(d3d12->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); @@ -198,7 +448,7 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i error: RARCH_ERR("[D3D12]: failed to init video driver.\n"); - free(d3d12); + d3d12_gfx_free(d3d12); return NULL; } @@ -238,11 +488,12 @@ static bool d3d12_gfx_frame( PERF_START(); D3D12ResetCommandAllocator(d3d12->queue.allocator); - D3D12ResetGraphicsCommandList(d3d12->queue.cmd, d3d12->queue.allocator, d3d12->pipe.handle); - D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->pipe.rootSignature); + D3D12ResetGraphicsCommandList( + d3d12->queue.cmd, d3d12->queue.allocator, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]); + D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->desc.rootSignature); { - D3D12DescriptorHeap desc_heaps[] = { d3d12->pipe.srv_heap.handle, - d3d12->pipe.sampler_heap.handle }; + D3D12DescriptorHeap desc_heaps[] = { d3d12->desc.srv_heap.handle, + d3d12->desc.sampler_heap.handle }; D3D12SetDescriptorHeaps(d3d12->queue.cmd, countof(desc_heaps), desc_heaps); } @@ -264,7 +515,7 @@ static bool d3d12_gfx_frame( d3d12->frame.texture.desc.Width = width; d3d12->frame.texture.desc.Height = height; d3d12_init_texture( - d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_FRAME_TEXTURE, + d3d12->device, &d3d12->desc.srv_heap, SRV_HEAP_SLOT_FRAME_TEXTURE, &d3d12->frame.texture); } d3d12_update_texture(width, height, pitch, d3d12->format, frame, &d3d12->frame.texture); @@ -274,7 +525,7 @@ static bool d3d12_gfx_frame( #if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */ if (d3d12->resize_viewport) #endif - d3d12_update_viewport(d3d12, false); + d3d12_update_viewport(d3d12, false); D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport); D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->frame.scissorRect); @@ -373,44 +624,6 @@ static bool d3d12_gfx_has_windowed(void* data) return true; } -static void d3d12_gfx_free(void* data) -{ - d3d12_video_t* d3d12 = (d3d12_video_t*)data; - - Release(d3d12->frame.ubo); - Release(d3d12->frame.vbo); - Release(d3d12->frame.texture.handle); - Release(d3d12->frame.texture.upload_buffer); - Release(d3d12->menu.vbo); - Release(d3d12->menu.texture.handle); - Release(d3d12->menu.texture.upload_buffer); - - Release(d3d12->ubo); - Release(d3d12->pipe.sampler_heap.handle); - Release(d3d12->pipe.srv_heap.handle); - Release(d3d12->pipe.rtv_heap.handle); - Release(d3d12->pipe.rootSignature); - Release(d3d12->pipe.handle); - - Release(d3d12->queue.fence); - Release(d3d12->chain.renderTargets[0]); - Release(d3d12->chain.renderTargets[1]); - Release(d3d12->chain.handle); - - Release(d3d12->queue.cmd); - Release(d3d12->queue.allocator); - Release(d3d12->queue.handle); - - Release(d3d12->factory); - Release(d3d12->device); - Release(d3d12->adapter); - - win32_monitor_from_window(); - win32_destroy_window(); - - free(d3d12); -} - static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) { (void)data; @@ -438,9 +651,10 @@ static bool d3d12_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static void d3d12_set_menu_texture_frame( void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) { - d3d12_video_t* d3d12 = (d3d12_video_t*)data; - int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); - DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; + d3d12_video_t* d3d12 = (d3d12_video_t*)data; + int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); + DXGI_FORMAT format = + rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; if (d3d12->menu.texture.desc.Width != width || d3d12->menu.texture.desc.Height != height) { @@ -448,7 +662,7 @@ static void d3d12_set_menu_texture_frame( d3d12->menu.texture.desc.Height = height; d3d12->menu.texture.desc.Format = d3d12_get_closest_match_texture2D(d3d12->device, format); d3d12_init_texture( - d3d12->device, &d3d12->pipe.srv_heap, SRV_HEAP_SLOT_MENU_TEXTURE, &d3d12->menu.texture); + d3d12->device, &d3d12->desc.srv_heap, SRV_HEAP_SLOT_MENU_TEXTURE, &d3d12->menu.texture); } d3d12_update_texture(width, height, pitch, format, frame, &d3d12->menu.texture);