From 9ad3825cee3c0c3a634b89faa62dc1d63ca05e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Wed, 14 Sep 2022 20:59:59 -0700 Subject: [PATCH] D3D12: Linux build. --- examples/common/bgfx_utils.cpp | 23 +++++------ scripts/bgfx.lua | 9 ++++- src/bgfx.cpp | 7 ++-- src/config.h | 1 + src/dxgi.cpp | 2 +- src/dxgi.h | 3 ++ src/renderer_d3d12.cpp | 71 +++++++++++++++++++++++++++++++--- src/renderer_d3d12.h | 11 ++++-- 8 files changed, 99 insertions(+), 28 deletions(-) diff --git a/examples/common/bgfx_utils.cpp b/examples/common/bgfx_utils.cpp index 3d2f318eb..209e3ea7f 100644 --- a/examples/common/bgfx_utils.cpp +++ b/examples/common/bgfx_utils.cpp @@ -767,20 +767,17 @@ Args::Args(int _argc, const char* const* _argv) { m_type = bgfx::RendererType::Noop; } - else if (BX_ENABLED(BX_PLATFORM_WINDOWS|BX_PLATFORM_WINRT|BX_PLATFORM_XBOXONE) ) + if (cmdLine.hasArg("d3d9") ) { - if (cmdLine.hasArg("d3d9") ) - { - m_type = bgfx::RendererType::Direct3D9; - } - else if (cmdLine.hasArg("d3d11") ) - { - m_type = bgfx::RendererType::Direct3D11; - } - else if (cmdLine.hasArg("d3d12") ) - { - m_type = bgfx::RendererType::Direct3D12; - } + m_type = bgfx::RendererType::Direct3D9; + } + else if (cmdLine.hasArg("d3d11") ) + { + m_type = bgfx::RendererType::Direct3D11; + } + else if (cmdLine.hasArg("d3d12") ) + { + m_type = bgfx::RendererType::Direct3D12; } else if (BX_ENABLED(BX_PLATFORM_OSX) ) { diff --git a/scripts/bgfx.lua b/scripts/bgfx.lua index b96a4bbc1..e9fecc97d 100644 --- a/scripts/bgfx.lua +++ b/scripts/bgfx.lua @@ -107,11 +107,16 @@ function bgfxProjectBase(_kind, _defines) } end + configuration { "linux-*" } + includedirs { + path.join(BGFX_DIR, "3rdparty/directx-headers/include/directx"), + path.join(BGFX_DIR, "3rdparty/directx-headers/include"), + path.join(BGFX_DIR, "3rdparty/directx-headers/include/wsl/stubs"), + } + configuration { "vs* or mingw*", "not durango" } includedirs { path.join(BGFX_DIR, "3rdparty/directx-headers/include/directx"), --- path.join(BGFX_DIR, "3rdparty/directx-headers/include"), --- path.join(BGFX_DIR, "3rdparty/directx-headers/include/wsl/stubs"), } configuration { "android*" } diff --git a/src/bgfx.cpp b/src/bgfx.cpp index ad63f3601..6e52f0284 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2692,9 +2692,10 @@ namespace bgfx } else if (BX_ENABLED(BX_PLATFORM_LINUX) ) { - score += RendererType::Vulkan == renderer ? 30 : 0; - score += RendererType::OpenGL == renderer ? 20 : 0; - score += RendererType::OpenGLES == renderer ? 10 : 0; + score += RendererType::Vulkan == renderer ? 30 : 0; + score += RendererType::OpenGL == renderer ? 20 : 0; + score += RendererType::OpenGLES == renderer ? 10 : 0; + score += RendererType::Direct3D12 == renderer ? 5 : 0; } else if (BX_ENABLED(BX_PLATFORM_OSX) ) { diff --git a/src/config.h b/src/config.h index b8ff7379f..cfaa24a55 100644 --- a/src/config.h +++ b/src/config.h @@ -53,6 +53,7 @@ # ifndef BGFX_CONFIG_RENDERER_DIRECT3D12 # define BGFX_CONFIG_RENDERER_DIRECT3D12 (0 \ + || BX_PLATFORM_LINUX \ || BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ || BX_PLATFORM_XBOXONE \ diff --git a/src/dxgi.cpp b/src/dxgi.cpp index e77fbf8cf..c323ccbfb 100644 --- a/src/dxgi.cpp +++ b/src/dxgi.cpp @@ -5,7 +5,7 @@ #include "bgfx_p.h" -#if BGFX_CONFIG_RENDERER_DIRECT3D11 || BGFX_CONFIG_RENDERER_DIRECT3D12 +#if BGFX_CONFIG_RENDERER_DIRECT3D11 || (BGFX_CONFIG_RENDERER_DIRECT3D12 && !BX_PLATFORM_LINUX) #include "dxgi.h" #include "renderer_d3d.h" diff --git a/src/dxgi.h b/src/dxgi.h index cecc32aad..d936532ce 100644 --- a/src/dxgi.h +++ b/src/dxgi.h @@ -6,6 +6,9 @@ #ifndef BGFX_DXGI_H_HEADER_GUARD #define BGFX_DXGI_H_HEADER_GUARD +typedef void* HMODULE; +#define _Out_writes_bytes_to_(s,c) + #if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT # include # include diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index b7c513077..8bcf53f6e 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -479,11 +479,13 @@ namespace bgfx { namespace d3d12 static void initHeapProperties(ID3D12Device* _device) { -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS initHeapProperties(_device, s_heapProperties[HeapProperty::Default ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::Texture ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::Upload ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::ReadBack].m_properties); +#else + BX_UNUSED(_device); #endif // BX_PLATFORM_WINDOWS } @@ -539,6 +541,10 @@ namespace bgfx { namespace d3d12 return createCommittedResource(_device, _heapProperty, &resourceDesc, NULL); } +#ifndef DXGI_ERROR_NOT_CURRENTLY_AVAILABLE +# define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE HRESULT(0x887A0022) +#endif // DXGI_ERROR_NOT_CURRENTLY_AVAILABLE + inline bool isLost(HRESULT _hr) { return false @@ -602,8 +608,10 @@ namespace bgfx { namespace d3d12 static PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; static PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature; +# if !BX_PLATFORM_LINUX typedef HANDLE (WINAPI* PFN_CREATE_EVENT_EX_A)(LPSECURITY_ATTRIBUTES _attrs, LPCSTR _name, DWORD _flags, DWORD _access); static PFN_CREATE_EVENT_EX_A CreateEventExA; +# endif // !BX_PLATFORM_LINUX #endif // USE_D3D12_DYNAMIC_LIB inline D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleHeapStart(ID3D12DescriptorHeap* _heap) @@ -724,6 +732,8 @@ namespace bgfx { namespace d3d12 bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); #if USE_D3D12_DYNAMIC_LIB + +# if !BX_PLATFORM_LINUX m_kernel32Dll = bx::dlopen("kernel32.dll"); if (NULL == m_kernel32Dll) { @@ -739,13 +749,23 @@ namespace bgfx { namespace d3d12 } errorState = ErrorState::LoadedKernel32; +# endif // !BX_PLATFORM_LINUX m_nvapi.init(); - m_d3d12Dll = bx::dlopen("d3d12.dll"); + const char* d3d12DllName = +#if BX_PLATFORM_LINUX + "libd3d12.so" +#else + "d3d12.dll" +#endif // BX_PLATFORM_LINUX + ; + + m_d3d12Dll = bx::dlopen(d3d12DllName); + if (NULL == m_d3d12Dll) { - BX_TRACE("Init error: Failed to load d3d12.dll."); + BX_TRACE("Init error: Failed to load %s.", d3d12DllName); goto error; } @@ -772,17 +792,19 @@ namespace bgfx { namespace d3d12 } #endif // USE_D3D12_DYNAMIC_LIB +#if !BX_PLATFORM_LINUX if (!m_dxgi.init(g_caps) ) { goto error; } errorState = ErrorState::LoadedDXGI; +#endif // !BX_PLATFORM_LINUX HRESULT hr; { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT if (_init.debug || _init.profile) { @@ -831,7 +853,12 @@ namespace bgfx { namespace d3d12 hr = E_FAIL; for (uint32_t ii = 0; ii < BX_COUNTOF(featureLevel) && FAILED(hr); ++ii) { - hr = D3D12CreateDevice(m_dxgi.m_adapter + hr = D3D12CreateDevice( +#if BX_PLATFORM_LINUX + NULL +#else + m_dxgi.m_adapter +#endif // BX_PLATFORM_LINUX , featureLevel[ii] , IID_ID3D12Device , (void**)&m_device @@ -883,7 +910,9 @@ namespace bgfx { namespace d3d12 goto error; } +#if !BX_PLATFORM_LINUX m_dxgi.update(m_device); +#endif // !BX_PLATFORM_LINUX { m_deviceInterfaceVersion = 0; @@ -900,10 +929,12 @@ namespace bgfx { namespace d3d12 } } +#if !BX_PLATFORM_LINUX if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId) { m_nvapi.shutdown(); } +#endif // !BX_PLATFORM_LINUX { uint32_t numNodes = m_device->GetNodeCount(); @@ -973,12 +1004,15 @@ namespace bgfx { namespace d3d12 if (NULL != m_scd.nwh) { +#if BX_PLATFORM_LINUX + hr = E_FAIL; +#else hr = m_dxgi.createSwapChain( getDeviceForSwapChain() , m_scd , &m_swapChain ); - +#endif // BX_PLATFORM_LINUX if (FAILED(hr) ) { @@ -1339,7 +1373,9 @@ namespace bgfx { namespace d3d12 postReset(); m_batch.create(4<<10); +#if !BX_PLATFORM_LINUX m_batch.setIndirectMode(BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId && BGFX_PCI_ID_MICROSOFT != m_dxgi.m_adapterDesc.VendorId); +#endif // !BX_PLATFORM_LINUX m_gpuTimer.init(); m_occlusionQuery.init(); @@ -1390,7 +1426,9 @@ namespace bgfx { namespace d3d12 case ErrorState::CreatedDXGIFactory: DX_RELEASE(m_device, 0); +#if !BX_PLATFORM_LINUX m_dxgi.shutdown(); +#endif // !BX_PLATFORM_LINUX BX_FALLTHROUGH; #if USE_D3D12_DYNAMIC_LIB @@ -1478,7 +1516,9 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_device, 0); m_nvapi.shutdown(); +#if !BX_PLATFORM_LINUX m_dxgi.shutdown(); +#endif // !BX_PLATFORM_LINUX unloadRenderDoc(m_renderDocDll); @@ -1521,10 +1561,12 @@ namespace bgfx { namespace d3d12 { presentFlags |= DXGI_PRESENT_RESTART; } +#if !BX_PLATFORM_LINUX else if (m_dxgi.tearingSupported() ) { presentFlags |= DXGI_PRESENT_ALLOW_TEARING; } +#endif // !BX_PLATFORM_LINUX for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii) { @@ -2319,11 +2361,15 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_swapChain, 0); HRESULT hr; +#if BX_PLATFORM_LINUX + hr = E_FAIL; +#else hr = m_dxgi.createSwapChain( getDeviceForSwapChain() , m_scd , &m_swapChain ); +#endif // BX_PLATFORM_LINUX BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain."); } @@ -3352,7 +3398,10 @@ namespace bgfx { namespace d3d12 m_commandList = _alloc ? m_cmd.alloc() : NULL; } +#if !BX_PLATFORM_LINUX Dxgi m_dxgi; +#endif // !BX_PLATFORM_LINUX + NvApi m_nvapi; void* m_kernel32Dll; @@ -3835,7 +3884,11 @@ namespace bgfx { namespace d3d12 ID3D12CommandList* commandLists[] = { commandList.m_commandList }; m_commandQueue->ExecuteCommandLists(BX_COUNTOF(commandLists), commandLists); +#if BX_PLATFORM_LINUX + commandList.m_event = NULL; +#else commandList.m_event = CreateEventExA(NULL, NULL, 0, EVENT_ALL_ACCESS); +#endif // BX_PLATFORM_LINUX const uint64_t fence = m_currentFence++; m_commandQueue->Signal(m_fence, fence); m_fence->SetEventOnCompletion(fence, commandList.m_event); @@ -3883,6 +3936,7 @@ namespace bgfx { namespace d3d12 bool CommandQueueD3D12::consume(uint32_t _ms) { CommandList& commandList = m_commandList[m_control.m_read]; +#if !BX_PLATFORM_LINUX if (WAIT_OBJECT_0 == WaitForSingleObject(commandList.m_event, _ms) ) { CloseHandle(commandList.m_event); @@ -3903,6 +3957,7 @@ namespace bgfx { namespace d3d12 return true; } +#endif // !BX_PLATFORM_LINUX return false; } @@ -7048,7 +7103,11 @@ namespace bgfx { namespace d3d12 , BGFX_REV_NUMBER ); +#if BX_PLATFORM_LINUX + const DXGI_ADAPTER_DESC desc = {}; +#else const DXGI_ADAPTER_DESC& desc = m_dxgi.m_adapterDesc; +#endif // BX_PLATFORM_LINUX char description[BX_COUNTOF(desc.Description)]; wcstombs(description, desc.Description, BX_COUNTOF(desc.Description) ); tvm.printf(0, pos++, 0x8f, " Device: %s", description); diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 84ee20a2b..cf30babd8 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -8,8 +8,13 @@ #define USE_D3D12_DYNAMIC_LIB (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX) -#include -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_LINUX +#if BX_PLATFORM_LINUX +# include +#else +# include +#endif // BX_PLATFORM_LINUX + +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT # include #else # if !BGFX_CONFIG_DEBUG @@ -45,7 +50,7 @@ extern "C++" { #include "nvapi.h" #include "dxgi.h" -#if BGFX_CONFIG_DEBUG_ANNOTATION +#if BGFX_CONFIG_DEBUG_ANNOTATION && !BX_PLATFORM_LINUX # if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT typedef struct PIXEventsThreadInfo* (WINAPI* PFN_PIX_GET_THREAD_INFO)(); typedef uint64_t (WINAPI* PFN_PIX_EVENTS_REPLACE_BLOCK)(bool _getEarliestTime);