mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Added missing files
This commit is contained in:
parent
c37dc4e04e
commit
9b4b93e8ef
7 changed files with 944 additions and 3 deletions
|
@ -480,6 +480,30 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(USE_NVRHI)
|
||||
set(NVRHI_WITH_DX11 "${USE_DX11}" CACHE BOOL "" FORCE)
|
||||
set(NVRHI_WITH_DX12 "${USE_DX12}" CACHE BOOL "" FORCE)
|
||||
set(NVRHI_WITH_VULKAN "${USE_NVRHI_VULKAN}" CACHE BOOL "" FORCE)
|
||||
|
||||
set(NVRHI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/nvrhi)
|
||||
add_subdirectory(${NVRHI_DIR})
|
||||
|
||||
if(USE_DX11)
|
||||
find_package(FXC REQUIRED)
|
||||
endif()
|
||||
|
||||
if(USE_DX12)
|
||||
find_package(DXCdxil REQUIRED)
|
||||
set(USE_DXIL_ON_DX12 TRUE CACHE BOOL "Use DXC to compile DXIL shaders on DX12 - otherwise FXC and DXBC")
|
||||
endif()
|
||||
|
||||
if(USE_NVRHI_VULKAN)
|
||||
find_package(DXCspirv REQUIRED)
|
||||
endif()
|
||||
|
||||
include_directories(${NVRHI_DIR}/include)
|
||||
endif(USE_NVRHI)
|
||||
|
||||
if(USE_SYSTEM_RAPIDJSON)
|
||||
find_package(rapidjson REQUIRED)
|
||||
endif(USE_SYSTEM_RAPIDJSON)
|
||||
|
@ -1645,9 +1669,9 @@ if(MSVC)
|
|||
#list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES d3xp/gamesys/Class.cpp)
|
||||
list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/framework/precompiled.cpp)
|
||||
|
||||
foreach( src_file ${RBDOOM3_PRECOMPILED_SOURCES} )
|
||||
message(STATUS "-include precompiled.h for ${src_file}")
|
||||
endforeach()
|
||||
#foreach( src_file ${RBDOOM3_PRECOMPILED_SOURCES} )
|
||||
# message(STATUS "-include precompiled.h for ${src_file}")
|
||||
#endforeach()
|
||||
|
||||
set_source_files_properties(
|
||||
${RBDOOM3_PRECOMPILED_SOURCES}
|
||||
|
|
56
neo/cmake/FindDXCdxil.cmake
Normal file
56
neo/cmake/FindDXCdxil.cmake
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
find_package(PackageHandleStandardArgs)
|
||||
|
||||
if (WIN32 AND NOT DEFINED DXC_DXIL_EXECUTABLE)
|
||||
|
||||
# locate Win 10 kits
|
||||
get_filename_component(kit10_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" REALPATH)
|
||||
file(GLOB W10SDK_VERSIONS RELATIVE ${kit10_dir}/Include ${kit10_dir}/Include/10.*) # enumerate pre-release and not yet known release versions
|
||||
list(APPEND W10SDK_VERSIONS "10.0.18362.0" "10.0.19041.0") # enumerate well known release versions
|
||||
list(REMOVE_DUPLICATES W10SDK_VERSIONS)
|
||||
list(SORT W10SDK_VERSIONS) # sort from low to high
|
||||
list(REVERSE W10SDK_VERSIONS) # reverse to start from high
|
||||
|
||||
foreach(W10SDK_VER ${W10SDK_VERSIONS})
|
||||
|
||||
set(WINSDK_PATHS "${kit10_dir}/bin/${W10SDK_VER}/x64" "C:/Program Files (x86)/Windows Kits/10/bin/${W10SDK_VER}/x64" "C:/Program Files/Windows Kits/10/bin/${W10SDK_VER}/x64")
|
||||
|
||||
find_program(DXC_DXIL_EXECUTABLE dxc PATHS ${WINSDK_PATHS} NO_DEFAULT_PATH)
|
||||
|
||||
if (EXISTS ${DXC_DXIL_EXECUTABLE})
|
||||
|
||||
set(DXC_DXIL_VERSION "${W10SDK_VER}")
|
||||
break()
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(DXCdxil
|
||||
REQUIRED_VARS
|
||||
DXC_DXIL_EXECUTABLE
|
||||
VERSION_VAR
|
||||
DXC_DXIL_VERSION
|
||||
)
|
45
neo/cmake/FindDXCspirv.cmake
Normal file
45
neo/cmake/FindDXCspirv.cmake
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
find_package(PackageHandleStandardArgs)
|
||||
|
||||
if (NOT DXC_SPIRV_EXECUTABLE)
|
||||
if (WIN32)
|
||||
find_program(DXC_SPIRV_EXECUTABLE dxc PATHS
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_program(DXC_SPIRV_EXECUTABLE dxc PATHS
|
||||
/usr/bin
|
||||
/usr/local/bin)
|
||||
endif()
|
||||
|
||||
if (DXC_SPIRV_EXECUTABLE)
|
||||
message(STATUS "Found DXC for SPIR-V generation: ${DXC_SPIRV_EXECUTABLE}.")
|
||||
message(STATUS "Please note that older versions of the compiler may result in shader compilation errors.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package_handle_standard_args(DXCspirv
|
||||
REQUIRED_VARS DXC_SPIRV_EXECUTABLE
|
||||
VERSION_VAR DXC_SPIRV_VERSION
|
||||
FAIL_MESSAGE "Cannot find a SPIR-V capable DXC executable. Please provide a valid path through the DXC_SPIRV_EXECUTABLE variable."
|
||||
)
|
57
neo/cmake/FindFXC.cmake
Normal file
57
neo/cmake/FindFXC.cmake
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
find_package(PackageHandleStandardArgs)
|
||||
|
||||
if (WIN32 AND NOT DEFINED FXC_EXECUTABLE)
|
||||
|
||||
# locate Win 10 kits
|
||||
get_filename_component(kit10_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" REALPATH)
|
||||
file(GLOB W10SDK_VERSIONS RELATIVE ${kit10_dir}/Include ${kit10_dir}/Include/10.*) # enumerate pre-release and not yet known release versions
|
||||
list(APPEND W10SDK_VERSIONS "10.0.15063.0" "10.0.16299.0" "10.0.17134.0") # enumerate well known release versions
|
||||
list(REMOVE_DUPLICATES W10SDK_VERSIONS)
|
||||
list(SORT W10SDK_VERSIONS) # sort from low to high
|
||||
list(REVERSE W10SDK_VERSIONS) # reverse to start from high
|
||||
|
||||
foreach(W10SDK_VER ${W10SDK_VERSIONS})
|
||||
|
||||
set(WINSDK_PATHS "${kit10_dir}/bin/${W10SDK_VER}/x64" "C:/Program Files (x86)/Windows Kits/10/bin/${W10SDK_VER}/x64" "C:/Program Files/Windows Kits/10/bin/${W10SDK_VER}/x64")
|
||||
|
||||
find_program(FXC_EXECUTABLE fxc PATHS ${WINSDK_PATHS} NO_DEFAULT_PATH)
|
||||
|
||||
if (EXISTS ${FXC_EXECUTABLE})
|
||||
|
||||
set(FXC_VERSION "${W10SDK_VER}")
|
||||
break()
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(FXC
|
||||
REQUIRED_VARS
|
||||
FXC_EXECUTABLE
|
||||
VERSION_VAR
|
||||
FXC_VERSION
|
||||
)
|
||||
|
161
neo/compileshaders.cmake
Normal file
161
neo/compileshaders.cmake
Normal file
|
@ -0,0 +1,161 @@
|
|||
#
|
||||
# Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# generates a build target that will compile shaders for a given config file
|
||||
#
|
||||
# usage: compile_shaders(TARGET <generated build target name>
|
||||
# CONFIG <shader-config-file>
|
||||
# [DXIL <dxil-output-path>]
|
||||
# [DXBC <dxbc-output-path>]
|
||||
# [SPIRV_DXC <spirv-output-path>])
|
||||
|
||||
function(compile_shaders)
|
||||
set(options "")
|
||||
set(oneValueArgs TARGET CONFIG FOLDER DXIL DXBC SPIRV_DXC CFLAGS SHADER_INCLUDE_DIR)
|
||||
set(multiValueArgs SOURCES)
|
||||
cmake_parse_arguments(params "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (NOT params_TARGET)
|
||||
message(FATAL_ERROR "compile_shaders: TARGET argument missing")
|
||||
endif()
|
||||
if (NOT params_CONFIG)
|
||||
message(FATAL_ERROR "compile_shaders: CONFIG argument missing")
|
||||
endif()
|
||||
|
||||
if (NOT params_SHADER_INCLUDE_DIR)
|
||||
set(SHADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
else()
|
||||
set(SHADER_INCLUDE_DIR ${params_SHADER_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
message( STATUS "Shader include path ${SHADER_INCLUDE_DIR}" )
|
||||
|
||||
# just add the source files to the project as documents, they are built by the script
|
||||
set_source_files_properties(${params_SOURCES} PROPERTIES VS_TOOL_OVERRIDE "None")
|
||||
|
||||
add_custom_target(${params_TARGET}
|
||||
DEPENDS shaderCompiler
|
||||
SOURCES ${params_SOURCES})
|
||||
|
||||
if (params_DXIL AND (USE_DX12 AND USE_DXIL_ON_DX12))
|
||||
if (NOT DXC_DXIL_EXECUTABLE)
|
||||
message(FATAL_ERROR "compile_shaders: DXC not found --- please set DXC_DXIL_EXECUTABLE to the full path to the DXC binary")
|
||||
endif()
|
||||
|
||||
if (NOT params_CFLAGS)
|
||||
set(CFLAGS "$<IF:$<CONFIG:Debug>,-Zi -Qembed_debug,-Qstrip_debug -Qstrip_reflect> -O3 -WX -Zpr")
|
||||
else()
|
||||
set(CFLAGS ${params_CFLAGS})
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${params_TARGET} PRE_BUILD
|
||||
COMMAND shaderCompiler
|
||||
--infile ${params_CONFIG}
|
||||
--parallel
|
||||
--out ${params_DXIL}
|
||||
--platform dxil
|
||||
--cflags "${CFLAGS}"
|
||||
-I ${SHADER_INCLUDE_DIR}
|
||||
--compiler ${DXC_DXIL_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
if (params_DXBC AND (USE_DX11 OR (USE_DX12 AND NOT USE_DXIL_ON_DX12)))
|
||||
if (NOT FXC_EXECUTABLE)
|
||||
message(FATAL_ERROR "compile_shaders: FXC not found --- please set FXC_EXECUTABLE to the full path to the FXC binary")
|
||||
endif()
|
||||
|
||||
if (NOT params_CFLAGS)
|
||||
set(CFLAGS "$<IF:$<CONFIG:Debug>,-Zi,-Qstrip_priv -Qstrip_debug -Qstrip_reflect> -O3 -WX -Zpr")
|
||||
else()
|
||||
set(CFLAGS ${params_CFLAGS})
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${params_TARGET} PRE_BUILD
|
||||
COMMAND shaderCompiler
|
||||
--infile ${params_CONFIG}
|
||||
--parallel
|
||||
--out ${params_DXBC}
|
||||
--platform dxbc
|
||||
--cflags "${CFLAGS}"
|
||||
-I ${SHADER_INCLUDE_DIR}
|
||||
--compiler ${FXC_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
if (params_SPIRV_DXC AND USE_NVRHI_VULKAN)
|
||||
if (NOT DXC_SPIRV_EXECUTABLE)
|
||||
message(FATAL_ERROR "compile_shaders: DXC for SPIR-V not found --- please set DXC_SPIRV_EXECUTABLE to the full path to the DXC binary")
|
||||
endif()
|
||||
|
||||
if (NOT params_CFLAGS)
|
||||
set(CFLAGS "$<IF:$<CONFIG:Debug>,-Zi,> -fspv-target-env=vulkan1.2 -O3 -WX -Zpr")
|
||||
else()
|
||||
set(CFLAGS ${params_CFLAGS})
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${params_TARGET} PRE_BUILD
|
||||
COMMAND shaderCompiler
|
||||
--infile ${params_CONFIG}
|
||||
--parallel
|
||||
--out ${params_SPIRV_DXC}
|
||||
--platform spirv
|
||||
-I ${SHADER_INCLUDE_DIR}
|
||||
-D SPIRV
|
||||
--cflags "${CFLAGS}"
|
||||
--compiler ${DXC_SPIRV_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
if(params_FOLDER)
|
||||
set_target_properties(${params_TARGET} PROPERTIES FOLDER ${params_FOLDER})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Generates a build target that will compile shaders for a given config file for all enabled Donut platforms.
|
||||
#
|
||||
# The shaders will be placed into subdirectories of ${OUTPUT_BASE}, with names compatible with
|
||||
# the FindDirectoryWithShaderBin framework function.
|
||||
|
||||
function(compile_shaders_all_platforms)
|
||||
set(options "")
|
||||
set(oneValueArgs TARGET CONFIG FOLDER OUTPUT_BASE CFLAGS)
|
||||
set(multiValueArgs SOURCES)
|
||||
cmake_parse_arguments(params "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (NOT params_TARGET)
|
||||
message(FATAL_ERROR "compile_shaders_all_platforms: TARGET argument missing")
|
||||
endif()
|
||||
if (NOT params_CONFIG)
|
||||
message(FATAL_ERROR "compile_shaders_all_platforms: CONFIG argument missing")
|
||||
endif()
|
||||
if (NOT params_OUTPUT_BASE)
|
||||
message(FATAL_ERROR "compile_shaders_all_platforms: OUTPUT_BASE argument missing")
|
||||
endif()
|
||||
|
||||
compile_shaders(TARGET ${params_TARGET}
|
||||
CONFIG ${params_CONFIG}
|
||||
FOLDER ${params_FOLDER}
|
||||
CFLAGS ${params_CFLAGS}
|
||||
DXBC ${params_OUTPUT_BASE}/dxbc
|
||||
DXIL ${params_OUTPUT_BASE}/dxil
|
||||
SPIRV_DXC ${params_OUTPUT_BASE}/spirv
|
||||
SOURCES ${params_SOURCES})
|
||||
|
||||
endfunction()
|
1
neo/extern/nvrhi
vendored
Submodule
1
neo/extern/nvrhi
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 997ee5a9f3972d586f9d2474f5c2f05391952a0b
|
597
neo/sys/win32/DeviceManager_DX12.cpp
Normal file
597
neo/sys/win32/DeviceManager_DX12.cpp
Normal file
|
@ -0,0 +1,597 @@
|
|||
#include "precompiled.h"
|
||||
|
||||
#include "renderer/RenderCommon.h"
|
||||
#include "renderer/RenderSystem.h"
|
||||
#include "../DeviceManager.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <dxgi1_5.h>
|
||||
#include <dxgidebug.h>
|
||||
|
||||
#include <nvrhi/d3d12.h>
|
||||
#include <nvrhi/validation.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#pragma comment(lib, "d3d12.lib")
|
||||
#pragma comment(lib, "dxgi.lib")
|
||||
|
||||
using nvrhi::RefCountPtr;
|
||||
|
||||
#define HR_RETURN(hr) if(FAILED(hr)) return false
|
||||
|
||||
class DeviceManager_DX12 : public DeviceManager
|
||||
{
|
||||
RefCountPtr<ID3D12Device> m_Device12;
|
||||
RefCountPtr<ID3D12CommandQueue> m_GraphicsQueue;
|
||||
RefCountPtr<ID3D12CommandQueue> m_ComputeQueue;
|
||||
RefCountPtr<ID3D12CommandQueue> m_CopyQueue;
|
||||
RefCountPtr<IDXGISwapChain3> m_SwapChain;
|
||||
DXGI_SWAP_CHAIN_DESC1 m_SwapChainDesc{};
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullScreenDesc{};
|
||||
RefCountPtr<IDXGIAdapter> m_DxgiAdapter;
|
||||
bool m_TearingSupported = false;
|
||||
|
||||
std::vector<RefCountPtr<ID3D12Resource>> m_SwapChainBuffers;
|
||||
std::vector<nvrhi::TextureHandle> m_RhiSwapChainBuffers;
|
||||
RefCountPtr<ID3D12Fence> m_FrameFence;
|
||||
std::vector<HANDLE> m_FrameFenceEvents;
|
||||
|
||||
UINT64 m_FrameCount = 1;
|
||||
|
||||
nvrhi::DeviceHandle nvrhiDevice;
|
||||
|
||||
std::string renderString;
|
||||
|
||||
public:
|
||||
const char* GetRendererString() const override
|
||||
{
|
||||
return renderString.c_str();
|
||||
}
|
||||
|
||||
nvrhi::IDevice* GetDevice() const override
|
||||
{
|
||||
return nvrhiDevice;
|
||||
}
|
||||
|
||||
void ReportLiveObjects() override;
|
||||
|
||||
nvrhi::GraphicsAPI GetGraphicsAPI() const override
|
||||
{
|
||||
return nvrhi::GraphicsAPI::D3D12;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool CreateDeviceAndSwapChain() override;
|
||||
void DestroyDeviceAndSwapChain() override;
|
||||
void ResizeSwapChain() override;
|
||||
nvrhi::ITexture* GetCurrentBackBuffer() override;
|
||||
nvrhi::ITexture* GetBackBuffer( uint32_t index ) override;
|
||||
uint32_t GetCurrentBackBufferIndex() override;
|
||||
uint32_t GetBackBufferCount() override;
|
||||
void BeginFrame() override;
|
||||
void Present() override;
|
||||
|
||||
private:
|
||||
bool CreateRenderTargets();
|
||||
void ReleaseRenderTargets();
|
||||
|
||||
glconfig_t config;
|
||||
};
|
||||
|
||||
static bool IsNvDeviceID( UINT id )
|
||||
{
|
||||
return id == 0x10DE;
|
||||
}
|
||||
|
||||
// Find an adapter whose name contains the given string.
|
||||
static RefCountPtr<IDXGIAdapter> FindAdapter( const std::wstring& targetName )
|
||||
{
|
||||
RefCountPtr<IDXGIAdapter> targetAdapter;
|
||||
RefCountPtr<IDXGIFactory1> DXGIFactory;
|
||||
HRESULT hres = CreateDXGIFactory1( IID_PPV_ARGS( &DXGIFactory ) );
|
||||
if( hres != S_OK )
|
||||
{
|
||||
common->FatalError( "ERROR in CreateDXGIFactory.\n"
|
||||
"For more info, get log from debug D3D runtime: (1) Install DX SDK, and enable Debug D3D from DX Control Panel Utility. (2) Install and start DbgView. (3) Try running the program again.\n" );
|
||||
return targetAdapter;
|
||||
}
|
||||
|
||||
unsigned int adapterNo = 0;
|
||||
while( SUCCEEDED( hres ) )
|
||||
{
|
||||
RefCountPtr<IDXGIAdapter> pAdapter;
|
||||
hres = DXGIFactory->EnumAdapters( adapterNo, &pAdapter );
|
||||
|
||||
if( SUCCEEDED( hres ) )
|
||||
{
|
||||
DXGI_ADAPTER_DESC aDesc;
|
||||
pAdapter->GetDesc( &aDesc );
|
||||
|
||||
// If no name is specified, return the first adapater. This is the same behaviour as the
|
||||
// default specified for D3D11CreateDevice when no adapter is specified.
|
||||
if( targetName.length() == 0 )
|
||||
{
|
||||
targetAdapter = pAdapter;
|
||||
break;
|
||||
}
|
||||
|
||||
std::wstring aName = aDesc.Description;
|
||||
|
||||
if( aName.find( targetName ) != std::string::npos )
|
||||
{
|
||||
targetAdapter = pAdapter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
adapterNo++;
|
||||
}
|
||||
|
||||
return targetAdapter;
|
||||
}
|
||||
|
||||
// Adjust window rect so that it is centred on the given adapter. Clamps to fit if it's too big.
|
||||
static bool MoveWindowOntoAdapter( IDXGIAdapter* targetAdapter, RECT& rect )
|
||||
{
|
||||
assert( targetAdapter != NULL );
|
||||
|
||||
HRESULT hres = S_OK;
|
||||
unsigned int outputNo = 0;
|
||||
while( SUCCEEDED( hres ) )
|
||||
{
|
||||
IDXGIOutput* pOutput = nullptr;
|
||||
hres = targetAdapter->EnumOutputs( outputNo++, &pOutput );
|
||||
|
||||
if( SUCCEEDED( hres ) && pOutput )
|
||||
{
|
||||
DXGI_OUTPUT_DESC OutputDesc;
|
||||
pOutput->GetDesc( &OutputDesc );
|
||||
const RECT desktop = OutputDesc.DesktopCoordinates;
|
||||
const int centreX = ( int )desktop.left + ( int )( desktop.right - desktop.left ) / 2;
|
||||
const int centreY = ( int )desktop.top + ( int )( desktop.bottom - desktop.top ) / 2;
|
||||
const int winW = rect.right - rect.left;
|
||||
const int winH = rect.bottom - rect.top;
|
||||
const int left = centreX - winW / 2;
|
||||
const int right = left + winW;
|
||||
const int top = centreY - winH / 2;
|
||||
const int bottom = top + winH;
|
||||
rect.left = std::max( left, ( int )desktop.left );
|
||||
rect.right = std::min( right, ( int )desktop.right );
|
||||
rect.bottom = std::min( bottom, ( int )desktop.bottom );
|
||||
rect.top = std::max( top, ( int )desktop.top );
|
||||
|
||||
// If there is more than one output, go with the first found. Multi-monitor support could go here.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::ReportLiveObjects()
|
||||
{
|
||||
nvrhi::RefCountPtr<IDXGIDebug> pDebug;
|
||||
DXGIGetDebugInterface1( 0, IID_PPV_ARGS( &pDebug ) );
|
||||
|
||||
if( pDebug )
|
||||
{
|
||||
pDebug->ReportLiveObjects( DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_IGNORE_INTERNAL );
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceManager_DX12::CreateDeviceAndSwapChain()
|
||||
{
|
||||
UINT windowStyle = deviceParms.startFullscreen
|
||||
? ( WS_POPUP | WS_SYSMENU | WS_VISIBLE )
|
||||
: deviceParms.startMaximized
|
||||
? ( WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE )
|
||||
: ( WS_OVERLAPPEDWINDOW | WS_VISIBLE );
|
||||
|
||||
RECT rect = { 0, 0, LONG( deviceParms.backBufferWidth ), LONG( deviceParms.backBufferHeight ) };
|
||||
AdjustWindowRect( &rect, windowStyle, FALSE );
|
||||
|
||||
RefCountPtr<IDXGIAdapter> targetAdapter;
|
||||
|
||||
if( deviceParms.adapter )
|
||||
{
|
||||
targetAdapter = deviceParms.adapter;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetAdapter = FindAdapter( deviceParms.adapterNameSubstring );
|
||||
|
||||
if( !targetAdapter )
|
||||
{
|
||||
std::wstring adapterNameStr( deviceParms.adapterNameSubstring.begin(), deviceParms.adapterNameSubstring.end() );
|
||||
common->FatalError( "Could not find an adapter matching %s\n", adapterNameStr.c_str() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
DXGI_ADAPTER_DESC aDesc;
|
||||
targetAdapter->GetDesc( &aDesc );
|
||||
|
||||
std::wstring adapterName = aDesc.Description;
|
||||
|
||||
// A stupid but non-deprecated and portable way of converting a wstring to a string
|
||||
std::stringstream ss;
|
||||
std::wstringstream wss;
|
||||
for( auto c : adapterName )
|
||||
{
|
||||
ss << wss.narrow( c, '?' );
|
||||
}
|
||||
renderString = ss.str();
|
||||
|
||||
isNvidia = IsNvDeviceID( aDesc.VendorId );
|
||||
}
|
||||
|
||||
if( MoveWindowOntoAdapter( targetAdapter, rect ) )
|
||||
{
|
||||
SetWindowPos( ( HWND )windowHandle, deviceParms.startFullscreen ? HWND_TOPMOST : HWND_NOTOPMOST,
|
||||
rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE );
|
||||
}
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect( ( HWND )windowHandle, &clientRect );
|
||||
UINT width = clientRect.right - clientRect.left;
|
||||
UINT height = clientRect.bottom - clientRect.top;
|
||||
|
||||
ZeroMemory( &m_SwapChainDesc, sizeof( m_SwapChainDesc ) );
|
||||
m_SwapChainDesc.Width = width;
|
||||
m_SwapChainDesc.Height = height;
|
||||
m_SwapChainDesc.SampleDesc.Count = deviceParms.swapChainSampleCount;
|
||||
m_SwapChainDesc.SampleDesc.Quality = 0;
|
||||
m_SwapChainDesc.BufferUsage = deviceParms.swapChainUsage;
|
||||
m_SwapChainDesc.BufferCount = deviceParms.swapChainBufferCount;
|
||||
m_SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
m_SwapChainDesc.Flags = deviceParms.allowModeSwitch ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
|
||||
|
||||
// Special processing for sRGB swap chain formats.
|
||||
// DXGI will not create a swap chain with an sRGB format, but its contents will be interpreted as sRGB.
|
||||
// So we need to use a non-sRGB format here, but store the true sRGB format for later framebuffer creation.
|
||||
switch( deviceParms.swapChainFormat ) // NOLINT(clang-diagnostic-switch-enum)
|
||||
{
|
||||
case nvrhi::Format::SRGBA8_UNORM:
|
||||
m_SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
case nvrhi::Format::SBGRA8_UNORM:
|
||||
m_SwapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
m_SwapChainDesc.Format = nvrhi::d3d12::convertFormat( deviceParms.swapChainFormat );
|
||||
break;
|
||||
}
|
||||
|
||||
if( deviceParms.enableDebugRuntime )
|
||||
{
|
||||
RefCountPtr<ID3D12Debug> pDebug;
|
||||
hr = D3D12GetDebugInterface( IID_PPV_ARGS( &pDebug ) );
|
||||
HR_RETURN( hr );
|
||||
pDebug->EnableDebugLayer();
|
||||
}
|
||||
|
||||
RefCountPtr<IDXGIFactory2> pDxgiFactory;
|
||||
UINT dxgiFactoryFlags = deviceParms.enableDebugRuntime ? DXGI_CREATE_FACTORY_DEBUG : 0;
|
||||
hr = CreateDXGIFactory2( dxgiFactoryFlags, IID_PPV_ARGS( &pDxgiFactory ) );
|
||||
HR_RETURN( hr );
|
||||
|
||||
RefCountPtr<IDXGIFactory5> pDxgiFactory5;
|
||||
if( SUCCEEDED( pDxgiFactory->QueryInterface( IID_PPV_ARGS( &pDxgiFactory5 ) ) ) )
|
||||
{
|
||||
BOOL supported = 0;
|
||||
if( SUCCEEDED( pDxgiFactory5->CheckFeatureSupport( DXGI_FEATURE_PRESENT_ALLOW_TEARING, &supported, sizeof( supported ) ) ) )
|
||||
{
|
||||
m_TearingSupported = ( supported != 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_TearingSupported )
|
||||
{
|
||||
m_SwapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
}
|
||||
|
||||
hr = D3D12CreateDevice(
|
||||
targetAdapter,
|
||||
deviceParms.featureLevel,
|
||||
IID_PPV_ARGS( &m_Device12 ) );
|
||||
HR_RETURN( hr );
|
||||
|
||||
if( deviceParms.enableDebugRuntime )
|
||||
{
|
||||
RefCountPtr<ID3D12InfoQueue> pInfoQueue;
|
||||
m_Device12->QueryInterface( &pInfoQueue );
|
||||
|
||||
if( pInfoQueue )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
pInfoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_CORRUPTION, true );
|
||||
pInfoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_ERROR, true );
|
||||
#endif
|
||||
|
||||
D3D12_MESSAGE_ID disableMessageIDs[] =
|
||||
{
|
||||
D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE,
|
||||
D3D12_MESSAGE_ID_COMMAND_LIST_STATIC_DESCRIPTOR_RESOURCE_DIMENSION_MISMATCH, // descriptor validation doesn't understand acceleration structures
|
||||
};
|
||||
|
||||
D3D12_INFO_QUEUE_FILTER filter = {};
|
||||
filter.DenyList.pIDList = disableMessageIDs;
|
||||
filter.DenyList.NumIDs = sizeof( disableMessageIDs ) / sizeof( disableMessageIDs[0] );
|
||||
pInfoQueue->AddStorageFilterEntries( &filter );
|
||||
}
|
||||
}
|
||||
|
||||
m_DxgiAdapter = targetAdapter;
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc;
|
||||
ZeroMemory( &queueDesc, sizeof( queueDesc ) );
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.NodeMask = 1;
|
||||
hr = m_Device12->CreateCommandQueue( &queueDesc, IID_PPV_ARGS( &m_GraphicsQueue ) );
|
||||
HR_RETURN( hr );
|
||||
m_GraphicsQueue->SetName( L"Graphics Queue" );
|
||||
|
||||
if( deviceParms.enableComputeQueue )
|
||||
{
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
|
||||
hr = m_Device12->CreateCommandQueue( &queueDesc, IID_PPV_ARGS( &m_ComputeQueue ) );
|
||||
HR_RETURN( hr );
|
||||
m_ComputeQueue->SetName( L"Compute Queue" );
|
||||
}
|
||||
|
||||
if( deviceParms.enableCopyQueue )
|
||||
{
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
|
||||
hr = m_Device12->CreateCommandQueue( &queueDesc, IID_PPV_ARGS( &m_CopyQueue ) );
|
||||
HR_RETURN( hr );
|
||||
m_CopyQueue->SetName( L"Copy Queue" );
|
||||
}
|
||||
|
||||
fullScreenDesc = {};
|
||||
fullScreenDesc.RefreshRate.Numerator = deviceParms.refreshRate;
|
||||
fullScreenDesc.RefreshRate.Denominator = 1;
|
||||
fullScreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
|
||||
fullScreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
fullScreenDesc.Windowed = !deviceParms.startFullscreen;
|
||||
|
||||
RefCountPtr<IDXGISwapChain1> pSwapChain1;
|
||||
hr = pDxgiFactory->CreateSwapChainForHwnd( m_GraphicsQueue, ( HWND )windowHandle, &m_SwapChainDesc, &fullScreenDesc, nullptr, &pSwapChain1 );
|
||||
HR_RETURN( hr );
|
||||
|
||||
hr = pSwapChain1->QueryInterface( IID_PPV_ARGS( &m_SwapChain ) );
|
||||
HR_RETURN( hr );
|
||||
|
||||
nvrhi::d3d12::DeviceDesc deviceDesc;
|
||||
deviceDesc.errorCB = &DefaultMessageCallback::GetInstance();
|
||||
deviceDesc.pDevice = m_Device12;
|
||||
deviceDesc.pGraphicsCommandQueue = m_GraphicsQueue;
|
||||
deviceDesc.pComputeCommandQueue = m_ComputeQueue;
|
||||
deviceDesc.pCopyCommandQueue = m_CopyQueue;
|
||||
|
||||
nvrhiDevice = nvrhi::d3d12::createDevice( deviceDesc );
|
||||
|
||||
deviceParms.enableNvrhiValidationLayer = true;
|
||||
|
||||
if( deviceParms.enableNvrhiValidationLayer )
|
||||
{
|
||||
nvrhiDevice = nvrhi::validation::createValidationLayer( nvrhiDevice );
|
||||
}
|
||||
|
||||
if( !CreateRenderTargets() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = m_Device12->CreateFence( 0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS( &m_FrameFence ) );
|
||||
HR_RETURN( hr );
|
||||
|
||||
for( UINT bufferIndex = 0; bufferIndex < m_SwapChainDesc.BufferCount; bufferIndex++ )
|
||||
{
|
||||
m_FrameFenceEvents.push_back( CreateEvent( nullptr, false, true, NULL ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::DestroyDeviceAndSwapChain()
|
||||
{
|
||||
m_RhiSwapChainBuffers.clear();
|
||||
renderString.clear();
|
||||
|
||||
ReleaseRenderTargets();
|
||||
|
||||
nvrhiDevice = nullptr;
|
||||
|
||||
for( auto fenceEvent : m_FrameFenceEvents )
|
||||
{
|
||||
WaitForSingleObject( fenceEvent, INFINITE );
|
||||
CloseHandle( fenceEvent );
|
||||
}
|
||||
|
||||
m_FrameFenceEvents.clear();
|
||||
|
||||
if( m_SwapChain )
|
||||
{
|
||||
m_SwapChain->SetFullscreenState( false, nullptr );
|
||||
}
|
||||
|
||||
m_SwapChainBuffers.clear();
|
||||
|
||||
m_FrameFence = nullptr;
|
||||
m_SwapChain = nullptr;
|
||||
m_GraphicsQueue = nullptr;
|
||||
m_ComputeQueue = nullptr;
|
||||
m_CopyQueue = nullptr;
|
||||
m_Device12 = nullptr;
|
||||
m_DxgiAdapter = nullptr;
|
||||
}
|
||||
|
||||
bool DeviceManager_DX12::CreateRenderTargets()
|
||||
{
|
||||
m_SwapChainBuffers.resize( m_SwapChainDesc.BufferCount );
|
||||
m_RhiSwapChainBuffers.resize( m_SwapChainDesc.BufferCount );
|
||||
|
||||
for( UINT n = 0; n < m_SwapChainDesc.BufferCount; n++ )
|
||||
{
|
||||
const HRESULT hr = m_SwapChain->GetBuffer( n, IID_PPV_ARGS( &m_SwapChainBuffers[n] ) );
|
||||
HR_RETURN( hr );
|
||||
|
||||
nvrhi::TextureDesc textureDesc;
|
||||
textureDesc.width = deviceParms.backBufferWidth;
|
||||
textureDesc.height = deviceParms.backBufferHeight;
|
||||
textureDesc.sampleCount = deviceParms.swapChainSampleCount;
|
||||
textureDesc.sampleQuality = deviceParms.swapChainSampleQuality;
|
||||
textureDesc.format = deviceParms.swapChainFormat;
|
||||
textureDesc.debugName = "SwapChainBuffer";
|
||||
textureDesc.isRenderTarget = true;
|
||||
textureDesc.isUAV = false;
|
||||
textureDesc.initialState = nvrhi::ResourceStates::Present;
|
||||
textureDesc.keepInitialState = true;
|
||||
|
||||
m_RhiSwapChainBuffers[n] = nvrhiDevice->createHandleForNativeTexture( nvrhi::ObjectTypes::D3D12_Resource, nvrhi::Object( m_SwapChainBuffers[n] ), textureDesc );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::ReleaseRenderTargets()
|
||||
{
|
||||
if( !nvrhiDevice )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that all frames have finished rendering
|
||||
nvrhiDevice->waitForIdle();
|
||||
|
||||
// Release all in-flight references to the render targets
|
||||
nvrhiDevice->runGarbageCollection();
|
||||
|
||||
// Set the events so that WaitForSingleObject in OneFrame will not hang later
|
||||
for( auto e : m_FrameFenceEvents )
|
||||
{
|
||||
SetEvent( e );
|
||||
}
|
||||
|
||||
// Release the old buffers because ResizeBuffers requires that
|
||||
m_RhiSwapChainBuffers.clear();
|
||||
m_SwapChainBuffers.clear();
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::ResizeSwapChain()
|
||||
{
|
||||
ReleaseRenderTargets();
|
||||
|
||||
if( !nvrhiDevice )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_SwapChain )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const HRESULT hr = m_SwapChain->ResizeBuffers( deviceParms.swapChainBufferCount,
|
||||
deviceParms.backBufferWidth,
|
||||
deviceParms.backBufferHeight,
|
||||
m_SwapChainDesc.Format,
|
||||
m_SwapChainDesc.Flags );
|
||||
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
common->FatalError( "ResizeBuffers failed" );
|
||||
}
|
||||
|
||||
bool ret = CreateRenderTargets();
|
||||
if( !ret )
|
||||
{
|
||||
common->FatalError( "CreateRenderTarget failed" );
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::BeginFrame()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 newSwapChainDesc;
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC newFullScreenDesc;
|
||||
if( SUCCEEDED( m_SwapChain->GetDesc1( &newSwapChainDesc ) ) && SUCCEEDED( m_SwapChain->GetFullscreenDesc( &newFullScreenDesc ) ) )
|
||||
{
|
||||
if( fullScreenDesc.Windowed != newFullScreenDesc.Windowed )
|
||||
{
|
||||
BackBufferResizing();
|
||||
|
||||
fullScreenDesc = newFullScreenDesc;
|
||||
m_SwapChainDesc = newSwapChainDesc;
|
||||
deviceParms.backBufferWidth = newSwapChainDesc.Width;
|
||||
deviceParms.backBufferHeight = newSwapChainDesc.Height;
|
||||
|
||||
if( newFullScreenDesc.Windowed )
|
||||
{
|
||||
//glfwSetWindowMonitor( m_Window, nullptr, 50, 50, newSwapChainDesc.Width, newSwapChainDesc.Height, 0 );
|
||||
}
|
||||
|
||||
ResizeSwapChain();
|
||||
BackBufferResized();
|
||||
}
|
||||
}
|
||||
|
||||
auto bufferIndex = m_SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
WaitForSingleObject( m_FrameFenceEvents[bufferIndex], INFINITE );
|
||||
}
|
||||
|
||||
nvrhi::ITexture* DeviceManager_DX12::GetCurrentBackBuffer()
|
||||
{
|
||||
return m_RhiSwapChainBuffers[m_SwapChain->GetCurrentBackBufferIndex()];
|
||||
}
|
||||
|
||||
nvrhi::ITexture* DeviceManager_DX12::GetBackBuffer( uint32_t index )
|
||||
{
|
||||
if( index < m_RhiSwapChainBuffers.size() )
|
||||
{
|
||||
return m_RhiSwapChainBuffers[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t DeviceManager_DX12::GetCurrentBackBufferIndex()
|
||||
{
|
||||
return m_SwapChain->GetCurrentBackBufferIndex();
|
||||
}
|
||||
|
||||
uint32_t DeviceManager_DX12::GetBackBufferCount()
|
||||
{
|
||||
return m_SwapChainDesc.BufferCount;
|
||||
}
|
||||
|
||||
void DeviceManager_DX12::Present()
|
||||
{
|
||||
if( !windowVisible )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto bufferIndex = m_SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
UINT presentFlags = 0;
|
||||
if( !deviceParms.vsyncEnabled && !glConfig.isFullscreen && glConfig.swapControlTearAvailable )
|
||||
{
|
||||
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
|
||||
m_SwapChain->Present( deviceParms.vsyncEnabled ? 1 : 0, presentFlags );
|
||||
|
||||
m_FrameFence->SetEventOnCompletion( m_FrameCount, m_FrameFenceEvents[bufferIndex] );
|
||||
m_GraphicsQueue->Signal( m_FrameFence, m_FrameCount );
|
||||
m_FrameCount++;
|
||||
}
|
||||
|
||||
DeviceManager* DeviceManager::CreateD3D12()
|
||||
{
|
||||
return new DeviceManager_DX12();
|
||||
}
|
Loading…
Reference in a new issue