2022-02-21 16:59:13 +00:00
|
|
|
/*
|
2023-03-06 16:05:43 +00:00
|
|
|
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
2023-03-06 19:06:15 +00:00
|
|
|
* Copyright (C) 2022 Stephen Pridham (id Tech 4x integration)
|
|
|
|
* Copyright (C) 2023 Stephen Saunders (id Tech 4x integration)
|
|
|
|
* Copyright (C) 2023 Robert Beckebans (id Tech 4x integration)
|
2023-03-06 16:05:43 +00:00
|
|
|
*
|
|
|
|
* 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.
|
2022-02-21 16:59:13 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SYS_DEVICE_MANAGER_H_
|
|
|
|
#define SYS_DEVICE_MANAGER_H_
|
|
|
|
|
2022-12-24 19:10:55 +00:00
|
|
|
#if USE_DX11 || USE_DX12
|
|
|
|
#include <DXGI.h>
|
2023-04-02 10:31:22 +00:00
|
|
|
#include <dxgi1_6.h>
|
2022-12-24 19:10:55 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_DX11
|
|
|
|
#include <d3d11.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_DX12
|
|
|
|
#include <d3d12.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_VK
|
|
|
|
#include <nvrhi/vulkan.h>
|
|
|
|
#endif
|
2022-02-21 16:59:13 +00:00
|
|
|
|
|
|
|
struct DeviceCreationParameters
|
|
|
|
{
|
|
|
|
bool startMaximized = false;
|
|
|
|
bool startFullscreen = false;
|
2023-05-12 18:43:07 +00:00
|
|
|
bool allowModeSwitch = false;
|
2022-02-21 16:59:13 +00:00
|
|
|
int windowPosX = -1; // -1 means use default placement
|
|
|
|
int windowPosY = -1;
|
|
|
|
uint32_t backBufferWidth = 1280;
|
|
|
|
uint32_t backBufferHeight = 720;
|
2022-04-13 20:05:05 +00:00
|
|
|
uint32_t backBufferSampleCount = 1; // optional HDR Framebuffer MSAA
|
2022-02-21 16:59:13 +00:00
|
|
|
uint32_t refreshRate = 0;
|
2023-06-06 15:42:22 +00:00
|
|
|
uint32_t swapChainBufferCount = NUM_FRAME_DATA; // SRS - default matches GPU frames, can be overridden by renderer
|
2022-03-11 10:44:07 +00:00
|
|
|
nvrhi::Format swapChainFormat = nvrhi::Format::RGBA8_UNORM; // RB: don't do the sRGB gamma ramp with the swapchain
|
2022-02-21 16:59:13 +00:00
|
|
|
uint32_t swapChainSampleCount = 1;
|
|
|
|
uint32_t swapChainSampleQuality = 0;
|
|
|
|
bool enableDebugRuntime = false;
|
|
|
|
bool enableNvrhiValidationLayer = false;
|
2023-03-24 14:04:34 +00:00
|
|
|
int vsyncEnabled = 0;
|
2022-02-21 16:59:13 +00:00
|
|
|
bool enableRayTracingExtensions = false; // for vulkan
|
|
|
|
bool enableComputeQueue = false;
|
|
|
|
bool enableCopyQueue = false;
|
|
|
|
|
2022-03-22 10:16:44 +00:00
|
|
|
#if _WIN32
|
|
|
|
HINSTANCE hInstance;
|
|
|
|
HWND hWnd;
|
|
|
|
#endif
|
|
|
|
|
2022-02-21 16:59:13 +00:00
|
|
|
#if USE_DX11 || USE_DX12
|
|
|
|
// Adapter to create the device on. Setting this to non-null overrides adapterNameSubstring.
|
|
|
|
// If device creation fails on the specified adapter, it will *not* try any other adapters.
|
|
|
|
IDXGIAdapter* adapter = nullptr;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// For use in the case of multiple adapters; only effective if 'adapter' is null. If this is non-null, device creation will try to match
|
|
|
|
// the given string against an adapter name. If the specified string exists as a sub-string of the
|
|
|
|
// adapter name, the device and window will be created on that adapter. Case sensitive.
|
|
|
|
std::wstring adapterNameSubstring = L"";
|
|
|
|
|
|
|
|
// set to true to enable DPI scale factors to be computed per monitor
|
|
|
|
// this will keep the on-screen window size in pixels constant
|
|
|
|
//
|
|
|
|
// if set to false, the DPI scale factors will be constant but the system
|
|
|
|
// may scale the contents of the window based on DPI
|
|
|
|
//
|
|
|
|
// note that the backbuffer size is never updated automatically; if the app
|
|
|
|
// wishes to scale up rendering based on DPI, then it must set this to true
|
|
|
|
// and respond to DPI scale factor changes by resizing the backbuffer explicitly
|
|
|
|
bool enablePerMonitorDPI = false;
|
|
|
|
|
|
|
|
#if USE_DX11 || USE_DX12
|
|
|
|
DXGI_USAGE swapChainUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
|
|
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_VK
|
|
|
|
std::vector<std::string> requiredVulkanInstanceExtensions;
|
|
|
|
std::vector<std::string> requiredVulkanDeviceExtensions;
|
|
|
|
std::vector<std::string> requiredVulkanLayers;
|
|
|
|
std::vector<std::string> optionalVulkanInstanceExtensions;
|
|
|
|
std::vector<std::string> optionalVulkanDeviceExtensions;
|
|
|
|
std::vector<std::string> optionalVulkanLayers;
|
|
|
|
std::vector<size_t> ignoredVulkanValidationMessageLocations;
|
|
|
|
#endif
|
2022-11-10 19:50:09 +00:00
|
|
|
|
|
|
|
// SRS - Used by idImage::AllocImage() to determine if format D24S8 is supported by device (default = true)
|
|
|
|
bool enableImageFormatD24S8 = true;
|
2022-02-21 16:59:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DefaultMessageCallback : public nvrhi::IMessageCallback
|
|
|
|
{
|
|
|
|
static DefaultMessageCallback& GetInstance();
|
|
|
|
|
|
|
|
void message( nvrhi::MessageSeverity severity, const char* messageText ) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class idRenderBackend;
|
|
|
|
|
|
|
|
/// Initialize the window and graphics device.
|
|
|
|
class DeviceManager
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static DeviceManager* Create( nvrhi::GraphicsAPI api );
|
|
|
|
|
2023-01-09 18:41:23 +00:00
|
|
|
#if USE_VK && defined( VULKAN_USE_PLATFORM_SDL )
|
2022-12-24 19:10:55 +00:00
|
|
|
// SRS - Helper method for creating SDL Vulkan surface within DeviceManager_VK()
|
2024-02-04 06:41:33 +00:00
|
|
|
VkResult CreateSDLWindowSurface( VkInstance instance, VkSurfaceKHR* surface );
|
2022-12-24 19:10:55 +00:00
|
|
|
#endif
|
|
|
|
|
2022-02-21 16:59:13 +00:00
|
|
|
bool CreateWindowDeviceAndSwapChain( const glimpParms_t& params, const char* windowTitle );
|
|
|
|
|
|
|
|
// returns the size of the window in screen coordinates
|
|
|
|
void GetWindowDimensions( int& width, int& height );
|
|
|
|
|
|
|
|
// returns the screen coordinate to pixel coordinate scale factor
|
|
|
|
void GetDPIScaleInfo( float& x, float& y ) const
|
|
|
|
{
|
2023-03-06 16:05:43 +00:00
|
|
|
x = m_DPIScaleFactorX;
|
|
|
|
y = m_DPIScaleFactorY;
|
2022-02-21 16:59:13 +00:00
|
|
|
}
|
|
|
|
|
2022-03-15 10:41:56 +00:00
|
|
|
void UpdateWindowSize( const glimpParms_t& params );
|
2022-02-21 16:59:13 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
friend class idRenderBackend;
|
2022-11-10 19:50:09 +00:00
|
|
|
friend class idImage;
|
2022-02-21 16:59:13 +00:00
|
|
|
|
2022-03-22 10:16:44 +00:00
|
|
|
void* windowInstance;
|
2022-02-21 16:59:13 +00:00
|
|
|
void* windowHandle;
|
2023-03-06 16:05:43 +00:00
|
|
|
bool m_windowVisible = false;
|
2022-02-21 16:59:13 +00:00
|
|
|
bool isNvidia = false;
|
|
|
|
|
2023-03-06 16:05:43 +00:00
|
|
|
DeviceCreationParameters m_DeviceParams;
|
2022-02-21 16:59:13 +00:00
|
|
|
|
2023-03-06 16:05:43 +00:00
|
|
|
float m_DPIScaleFactorX = 1.f;
|
|
|
|
float m_DPIScaleFactorY = 1.f;
|
2023-03-24 14:04:34 +00:00
|
|
|
int m_RequestedVSync = 0;
|
2022-02-21 16:59:13 +00:00
|
|
|
|
|
|
|
uint32_t m_FrameIndex = 0;
|
|
|
|
|
|
|
|
DeviceManager() = default;
|
|
|
|
|
|
|
|
void BackBufferResizing();
|
|
|
|
void BackBufferResized();
|
|
|
|
|
|
|
|
// device-specific methods
|
|
|
|
virtual bool CreateDeviceAndSwapChain() = 0;
|
|
|
|
virtual void DestroyDeviceAndSwapChain() = 0;
|
|
|
|
virtual void ResizeSwapChain() = 0;
|
|
|
|
virtual void BeginFrame() = 0;
|
2022-09-22 16:34:07 +00:00
|
|
|
virtual void EndFrame() = 0; // RB: added for BFG edition
|
2022-02-21 16:59:13 +00:00
|
|
|
virtual void Present() = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
[[nodiscard]] virtual nvrhi::IDevice* GetDevice() const = 0;
|
|
|
|
[[nodiscard]] virtual const char* GetRendererString() const = 0;
|
|
|
|
[[nodiscard]] virtual nvrhi::GraphicsAPI GetGraphicsAPI() const = 0;
|
|
|
|
|
|
|
|
const DeviceCreationParameters& GetDeviceParams();
|
2023-03-24 14:04:34 +00:00
|
|
|
virtual void SetVsyncEnabled( int vsyncMode )
|
2022-02-21 16:59:13 +00:00
|
|
|
{
|
2023-03-24 14:04:34 +00:00
|
|
|
m_RequestedVSync = vsyncMode; /* will be processed later */
|
2022-02-21 16:59:13 +00:00
|
|
|
}
|
|
|
|
virtual void ReportLiveObjects() {}
|
|
|
|
|
|
|
|
[[nodiscard]] uint32_t GetFrameIndex() const
|
|
|
|
{
|
|
|
|
return m_FrameIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual nvrhi::ITexture* GetCurrentBackBuffer() = 0;
|
|
|
|
virtual nvrhi::ITexture* GetBackBuffer( uint32_t index ) = 0;
|
|
|
|
virtual uint32_t GetCurrentBackBufferIndex() = 0;
|
|
|
|
virtual uint32_t GetBackBufferCount() = 0;
|
|
|
|
|
|
|
|
nvrhi::IFramebuffer* GetCurrentFramebuffer();
|
|
|
|
nvrhi::IFramebuffer* GetFramebuffer( uint32_t index );
|
|
|
|
|
|
|
|
void Shutdown();
|
|
|
|
virtual ~DeviceManager() = default;
|
|
|
|
|
|
|
|
void SetWindowTitle( const char* title );
|
|
|
|
|
|
|
|
virtual bool IsVulkanInstanceExtensionEnabled( const char* extensionName ) const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual bool IsVulkanDeviceExtensionEnabled( const char* extensionName ) const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual bool IsVulkanLayerEnabled( const char* layerName ) const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual void GetEnabledVulkanInstanceExtensions( std::vector<std::string>& extensions ) const { }
|
|
|
|
virtual void GetEnabledVulkanDeviceExtensions( std::vector<std::string>& extensions ) const { }
|
|
|
|
virtual void GetEnabledVulkanLayers( std::vector<std::string>& layers ) const { }
|
|
|
|
|
|
|
|
private:
|
|
|
|
static DeviceManager* CreateD3D11();
|
|
|
|
static DeviceManager* CreateD3D12();
|
|
|
|
static DeviceManager* CreateVK();
|
|
|
|
|
|
|
|
std::string m_WindowTitle;
|
|
|
|
};
|
|
|
|
|
2022-11-10 19:50:09 +00:00
|
|
|
#endif
|