Merge pull request #725 from SRSaunders/635-nvrhi3-testing

[Vulkan] Solve multiple Vulkan validation issues, NVRHI game now runs without failures on Linux & macOS
This commit is contained in:
Robert Beckebans 2022-11-18 16:45:08 +01:00 committed by GitHub
commit fca592ca73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 351 additions and 1380 deletions

View file

@ -852,6 +852,16 @@ file(GLOB RAPIDJSON_INCLUDES libs/rapidjson/include/rapidjson/*.h)
file(GLOB SYS_INCLUDES sys/*.h)
file(GLOB SYS_SOURCES sys/*.cpp)
if(NOT USE_DX12)
get_filename_component(devicemanager_dx12_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/DeviceManager_DX12.cpp ABSOLUTE)
list(REMOVE_ITEM SYS_SOURCES "${devicemanager_dx12_cpp_full_path}")
endif()
if(NOT USE_NVRHI_VULKAN)
get_filename_component(devicemanager_vk_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/DeviceManager_VK.cpp ABSOLUTE)
list(REMOVE_ITEM SYS_SOURCES "${devicemanager_vk_cpp_full_path}")
endif()
file(GLOB UI_INCLUDES ui/*.h)
file(GLOB UI_SOURCES ui/*.cpp)
@ -1104,14 +1114,6 @@ set(WIN32_SOURCES
sys/win32/win_taskkeyhook.cpp
sys/win32/win_wndproc.cpp)
if(USE_DX12)
list(APPEND WIN32_SOURCES sys/win32/DeviceManager_DX12.cpp)
endif()
if(USE_NVRHI_VULKAN)
list(APPEND WIN32_SOURCES sys/win32/DeviceManager_VK.cpp)
endif()
if(MSVC)
list(APPEND WIN32_SOURCES sys/win32/win_cpu.cpp)
endif()
@ -1206,8 +1208,6 @@ if(UNIX)
list(REMOVE_ITEM SYS_INCLUDES "${devicemanager_h_full_path}")
get_filename_component(devicemanager_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/DeviceManager.cpp ABSOLUTE)
list(REMOVE_ITEM SYS_SOURCES "${devicemanager_cpp_full_path}")
get_filename_component(devicemanager_vk_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/sdl/DeviceManager_VK.cpp ABSOLUTE)
list(REMOVE_ITEM SDL_SOURCES "${devicemanager_vk_cpp_full_path}")
endif()
endif()
@ -1881,7 +1881,7 @@ else()
list(APPEND Vulkan_LIBRARIES glslang-default-resource-limits)
endif()
endif()
elseif(USE_NVRHI)
elseif(USE_NVRHI_VULKAN)
list(APPEND RBDOOM3_INCLUDES ${RENDERER_NVRHI_INCLUDES})
list(APPEND RBDOOM3_SOURCES ${RENDERER_NVRHI_SOURCES})

View file

@ -220,7 +220,7 @@ extern bool R_UseTemporalAA();
#define FPS_FRAMES_HISTORY 90
float idConsoleLocal::DrawFPS( float y )
{
extern idCVar com_smp;
extern idCVar r_swapInterval;
static float previousTimes[FPS_FRAMES];
static float previousTimesNormalized[FPS_FRAMES_HISTORY];
@ -288,8 +288,6 @@ float idConsoleLocal::DrawFPS( float y )
const uint64 rendererBackEndTime = commonLocal.GetRendererBackEndMicroseconds();
const uint64 rendererShadowsTime = commonLocal.GetRendererShadowsMicroseconds();
// SRS - GPU idle time calculation depends on whether game is operating in smp mode or not
const uint64 rendererGPUIdleTime = commonLocal.GetRendererIdleMicroseconds() - ( com_smp.GetInteger() > 0 && com_editors == 0 ? 0 : gameThreadTotalTime );
const uint64 rendererGPUTime = commonLocal.GetRendererGPUMicroseconds();
const uint64 rendererGPUEarlyZTime = commonLocal.GetRendererGpuEarlyZMicroseconds();
const uint64 rendererGPU_SSAOTime = commonLocal.GetRendererGpuSSAOMicroseconds();
@ -300,15 +298,20 @@ float idConsoleLocal::DrawFPS( float y )
const uint64 rendererGPUShaderPassesTime = commonLocal.GetRendererGpuShaderPassMicroseconds();
const uint64 rendererGPU_TAATime = commonLocal.GetRendererGpuTAAMicroseconds();
const uint64 rendererGPUPostProcessingTime = commonLocal.GetRendererGpuPostProcessingMicroseconds();
const int maxTime = int( 1000 / com_engineHz_latched ) * 1000;
// SRS - Get GPU sync time at the start of a frame (com_smp = 1 or 0) and at the end of a frame (com_smp = -1)
const uint64 rendererStartFrameSyncTime = commonLocal.GetRendererStartFrameSyncMicroseconds();
const uint64 rendererEndFrameSyncTime = commonLocal.GetRendererEndFrameSyncMicroseconds();
// SRS - Calculate max fps and max frame time based on glConfig.displayFrequency if vsync enabled and lower than engine Hz, otherwise use com_engineHz_latched
const int max_FPS = ( r_swapInterval.GetInteger() > 0 && glConfig.displayFrequency > 0 ? std::min( glConfig.displayFrequency, int( com_engineHz_latched ) ) : com_engineHz_latched );
const int maxTime = 1000.0 / max_FPS * 1000;
// SRS - Total CPU and Frame time calculations depend on whether game is operating in smp mode or not
const uint64 totalCPUTime = ( com_smp.GetInteger() > 0 && com_editors == 0 ? std::max( gameThreadTotalTime, rendererBackEndTime ) : gameThreadTotalTime + rendererBackEndTime );
const uint64 totalFrameTime = ( com_smp.GetInteger() > 0 && com_editors == 0 ? std::max( gameThreadTotalTime, rendererEndFrameSyncTime ) : gameThreadTotalTime + rendererEndFrameSyncTime ) + rendererStartFrameSyncTime;
// SRS - Frame idle and busy time calculations are based on direct frame-over-frame measurement relative to finishSyncTime
const uint64 frameIdleTime = commonLocal.mainFrameTiming.startGameTime - commonLocal.mainFrameTiming.finishSyncTime;
const uint64 frameBusyTime = commonLocal.frameTiming.finishSyncTime - commonLocal.mainFrameTiming.startGameTime;
// SRS - Frame sync time represents swap buffer synchronization + game thread wait + other time spent outside of rendering
const uint64 frameSyncTime = commonLocal.frameTiming.finishSyncTime - commonLocal.mainFrameTiming.finishRenderTime;
// SRS - GPU idle time is simply the difference between measured frame-over-frame time and GPU busy time (directly from GPU timers)
const uint64 rendererGPUIdleTime = frameBusyTime + frameIdleTime - rendererGPUTime;
#if 1
@ -476,7 +479,7 @@ float idConsoleLocal::DrawFPS( float y )
}
else
{
ImGui::TextColored( fps < com_engineHz_latched ? colorRed : colorYellow, "Average FPS %i", fps );
ImGui::TextColored( fps < max_FPS ? colorRed : colorYellow, "Average FPS %i", fps );
}
ImGui::Spacing();
@ -486,14 +489,13 @@ float idConsoleLocal::DrawFPS( float y )
ImGui::TextColored( gameThreadGameTime > maxTime ? colorRed : colorWhite, "Game: %5llu us SSAO: %5llu us", gameThreadGameTime, rendererGPU_SSAOTime );
ImGui::TextColored( gameThreadRenderTime > maxTime ? colorRed : colorWhite, "RF: %5llu us SSR: %5llu us", gameThreadRenderTime, rendererGPU_SSRTime );
ImGui::TextColored( rendererBackEndTime > maxTime ? colorRed : colorWhite, "RB: %5llu us Ambient Pass: %5llu us", rendererBackEndTime, rendererGPUAmbientPassTime );
ImGui::TextColored( rendererGPUShadowAtlasTime > maxTime ? colorRed : colorWhite, " Shadow Atlas: %5llu us", rendererGPUShadowAtlasTime );
ImGui::TextColored( rendererShadowsTime > maxTime ? colorRed : colorWhite, "Shadows: %5llu us Interactions: %5llu us", rendererShadowsTime, rendererGPUInteractionsTime );
ImGui::TextColored( rendererGPUShadowAtlasTime > maxTime ? colorRed : colorWhite, "Shadows: %5llu us Shadow Atlas: %5llu us", rendererShadowsTime, rendererGPUShadowAtlasTime );
ImGui::TextColored( rendererGPUInteractionsTime > maxTime ? colorRed : colorWhite, "Sync: %5llu us Interactions: %5llu us", frameSyncTime, rendererGPUInteractionsTime );
ImGui::TextColored( rendererGPUShaderPassesTime > maxTime ? colorRed : colorWhite, " Shader Pass: %5llu us", rendererGPUShaderPassesTime );
ImGui::TextColored( rendererGPU_TAATime > maxTime ? colorRed : colorWhite, " TAA: %5llu us", rendererGPU_TAATime );
ImGui::TextColored( rendererGPUPostProcessingTime > maxTime ? colorRed : colorWhite, " PostFX: %5llu us", rendererGPUPostProcessingTime );
ImGui::TextColored( totalCPUTime > maxTime || rendererGPUTime > maxTime ? colorRed : colorWhite,
"Total: %5llu us Total: %5llu us", totalCPUTime, rendererGPUTime );
ImGui::TextColored( totalFrameTime > maxTime ? colorRed : colorWhite, "Frame: %5llu us Idle: %5llu us", totalFrameTime, rendererGPUIdleTime );
ImGui::TextColored( frameBusyTime > maxTime || rendererGPUTime > maxTime ? colorRed : colorWhite, "Total: %5llu us Total: %5llu us", frameBusyTime, rendererGPUTime );
ImGui::TextColored( colorWhite, "Idle: %5llu us Idle: %5llu us", frameIdleTime, rendererGPUIdleTime );
ImGui::End();
}

View file

@ -286,7 +286,15 @@ void idImage::AllocImage()
break;
case FMT_DEPTH_STENCIL:
format = nvrhi::Format::D24S8;
// SRS - Check if D24S8 is supported, otherwise fall back to D32S8
if( deviceManager->deviceParms.enableImageFormatD24S8 )
{
format = nvrhi::Format::D24S8;
}
else
{
format = nvrhi::Format::D32S8;
}
break;
case FMT_SHADOW_ARRAY:

View file

@ -192,7 +192,6 @@ void idRenderBackend::Init()
// RB: FIXME but for now disable it to avoid validation errors
if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN )
{
glConfig.timerQueryAvailable = false;
r_useSSAO.SetBool( false );
}
}
@ -1711,6 +1710,13 @@ void idRenderBackend::CheckCVars()
R_SetColorMappings();
}
// SRS - support dynamic changes to vsync setting
if( r_swapInterval.IsModified() )
{
r_swapInterval.ClearModified();
deviceManager->SetVsyncEnabled( r_swapInterval.GetBool() );
}
// filtering
/*if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() )
{
@ -2145,6 +2151,13 @@ idRenderBackend::ResizeImages
*/
void idRenderBackend::ResizeImages()
{
glimpParms_t parms;
parms.width = glConfig.nativeScreenWidth;
parms.height = glConfig.nativeScreenHeight;
parms.multiSamples = glConfig.multisamples;
deviceManager->UpdateWindowSize( parms );
}
void idRenderBackend::SetCurrentImage( idImage* image )

View file

@ -6664,7 +6664,7 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
// SRS - Restore timestamp capture state after overlay GUI rendering is finished
glConfig.timerQueryAvailable = timerQueryAvailable;
renderLog.CloseBlock();
renderLog.CloseMainBlock();
renderLog.CloseMainBlock( MRB_DRAW_GUI );
}
else
{

View file

@ -324,7 +324,7 @@ idRenderLog::idRenderLog()
void idRenderLog::Init()
{
#if defined( USE_NVRHI )
for( int i = 0; i < MRB_TOTAL_QUERIES; i++ )
for( int i = 0; i < MRB_TOTAL * NUM_FRAME_DATA; i++ )
{
timerQueries.Append( deviceManager->GetDevice()->createTimerQuery() );
timerUsed.Append( false );
@ -335,12 +335,7 @@ void idRenderLog::Init()
void idRenderLog::Shutdown()
{
#if defined( USE_NVRHI )
if( commandList )
{
commandList.Reset();
}
for( int i = 0; i < MRB_TOTAL_QUERIES; i++ )
for( int i = 0; i < MRB_TOTAL * NUM_FRAME_DATA; i++ )
{
timerQueries[i].Reset();
}
@ -356,6 +351,9 @@ void idRenderLog::StartFrame( nvrhi::ICommandList* _commandList )
void idRenderLog::EndFrame()
{
#if defined( USE_NVRHI )
commandList = nullptr;
#endif
}
@ -376,8 +374,11 @@ void idRenderLog::OpenMainBlock( renderLogMainBlock_t block )
int timerIndex = mainBlock + frameParity * MRB_TOTAL;
commandList->beginTimerQuery( timerQueries[ timerIndex ] );
timerUsed[ timerIndex ] = true;
// SRS - Only issue a new start timer query if timer slot unused
if( !timerUsed[ timerIndex ] )
{
commandList->beginTimerQuery( timerQueries[ timerIndex ] );
}
#elif defined( USE_VULKAN )
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
@ -437,7 +438,12 @@ void idRenderLog::CloseMainBlock( int _block )
int timerIndex = block + frameParity * MRB_TOTAL;
commandList->endTimerQuery( timerQueries[ timerIndex ] );
// SRS - Only issue a new end timer query if timer slot unused
if( !timerUsed[ timerIndex ] )
{
commandList->endTimerQuery( timerQueries[ timerIndex ] );
timerUsed[ timerIndex ] = true;
}
#elif defined( USE_VULKAN )
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
@ -448,7 +454,7 @@ void idRenderLog::CloseMainBlock( int _block )
VkCommandBuffer commandBuffer = vkcontext.commandBuffer[ vkcontext.frameParity ];
VkQueryPool queryPool = vkcontext.queryPools[ vkcontext.frameParity ];
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ block * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, queryIndex );
#elif defined(__APPLE__)
@ -457,12 +463,12 @@ void idRenderLog::CloseMainBlock( int _block )
if( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() )
{
glEndQuery( GL_TIME_ELAPSED_EXT );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ block * 2 + 1 ]++;
}
#else
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ block * 2 + 1 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ block * 2 + 1 ]++;
#endif
}
}
@ -475,7 +481,7 @@ idRenderLog::FetchGPUTimers
void idRenderLog::FetchGPUTimers( backEndCounters_t& pc )
{
frameCounter++;
frameParity ^= 1;
frameParity = ( frameParity + 1 ) % NUM_FRAME_DATA;
#if defined( USE_NVRHI )

View file

@ -82,8 +82,8 @@ private:
uint64 frameCounter;
uint32 frameParity;
idStaticList<nvrhi::TimerQueryHandle, MRB_TOTAL_QUERIES> timerQueries;
idStaticList<bool, MRB_TOTAL_QUERIES> timerUsed;
idStaticList<nvrhi::TimerQueryHandle, MRB_TOTAL * NUM_FRAME_DATA> timerQueries;
idStaticList<bool, MRB_TOTAL * NUM_FRAME_DATA> timerUsed;
#endif
public:

View file

@ -107,7 +107,7 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
// RB: FIXME this is ugly - DOUBLECHECK this
constantBuffer = device->createBuffer(
nvrhi::utils::CreateVolatileConstantBufferDesc( uniforms.Allocated(),
"RenderParams", 1024 ) );
"RenderParams", 4096 ) );
}
else
{

View file

@ -2245,6 +2245,8 @@ idRenderSystemLocal::Shutdown
*/
void idRenderSystemLocal::Shutdown()
{
extern idCVar com_smp;
common->Printf( "idRenderSystem::Shutdown()\n" );
fonts.DeleteContents();
@ -2270,7 +2272,11 @@ void idRenderSystemLocal::Shutdown()
UnbindBufferObjects();
// SRS - wait for fence to hit before freeing any resources the GPU may be using, otherwise get Vulkan validation layer errors on shutdown
backend.GL_BlockingSwapBuffers();
// SRS - skip this step if we are in Doom 3 mode (com_smp = -1) which has already finished and presented
if( com_smp.GetInteger() != -1 )
{
backend.GL_BlockingSwapBuffers();
}
// free the vertex cache, which should have nothing allocated now
vertexCache.Shutdown();

View file

@ -96,6 +96,9 @@ struct DeviceCreationParameters
std::vector<std::string> optionalVulkanLayers;
std::vector<size_t> ignoredVulkanValidationMessageLocations;
#endif
// SRS - Used by idImage::AllocImage() to determine if format D24S8 is supported by device (default = true)
bool enableImageFormatD24S8 = true;
};
struct DefaultMessageCallback : public nvrhi::IMessageCallback
@ -131,6 +134,7 @@ public:
protected:
friend class idRenderBackend;
friend class idImage;
void* windowInstance;
void* windowHandle;
@ -216,4 +220,4 @@ private:
std::string m_WindowTitle;
};
#endif
#endif

View file

@ -24,7 +24,7 @@
#include "renderer/RenderCommon.h"
#include "renderer/RenderSystem.h"
#include "../DeviceManager.h"
#include <sys/DeviceManager.h>
#include <Windows.h>
#include <dxgi1_5.h>
@ -204,15 +204,6 @@ void DeviceManager_DX12::ReportLiveObjects()
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 )
@ -248,12 +239,25 @@ bool DeviceManager_DX12::CreateDeviceAndSwapChain()
isNvidia = IsNvDeviceID( aDesc.VendorId );
}
/*
// SRS - Don't center window here for DX12 only, instead use portable initialization in CreateWindowDeviceAndSwapChain() within win_glimp.cpp
// - Also, calling SetWindowPos() triggers a window mgr event that overwrites r_windowX / r_windowY, which may be undesirable to the user
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 );
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;
@ -539,6 +543,8 @@ void DeviceManager_DX12::ResizeSwapChain()
void DeviceManager_DX12::BeginFrame()
{
/* SRS - This code not needed: framebuffer/swapchain resizing & fullscreen are handled by idRenderBackend::ResizeImages() and DeviceManager::UpdateWindowSize()
DXGI_SWAP_CHAIN_DESC1 newSwapChainDesc;
DXGI_SWAP_CHAIN_FULLSCREEN_DESC newFullScreenDesc;
if( SUCCEEDED( m_SwapChain->GetDesc1( &newSwapChainDesc ) ) && SUCCEEDED( m_SwapChain->GetFullscreenDesc( &newFullScreenDesc ) ) )
@ -561,7 +567,7 @@ void DeviceManager_DX12::BeginFrame()
BackBufferResized();
}
}
*/
auto bufferIndex = m_SwapChain->GetCurrentBackBufferIndex();
WaitForSingleObject( m_FrameFenceEvents[bufferIndex], INFINITE );
@ -607,21 +613,14 @@ void DeviceManager_DX12::Present()
UINT presentFlags = 0;
if( r_swapInterval.GetInteger() == 1 )
{
SetVsyncEnabled( false );
}
else if( r_swapInterval.GetInteger() == 2 )
{
SetVsyncEnabled( true );
}
if( !deviceParms.vsyncEnabled && !glConfig.isFullscreen && m_TearingSupported && r_swapInterval.GetInteger() == 0 )
// SRS - DXGI docs say fullscreen must be disabled for unlocked fps/tear, but this does not seem to be true
if( !deviceParms.vsyncEnabled && m_TearingSupported ) //&& !glConfig.isFullscreen )
{
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
}
m_SwapChain->Present( deviceParms.vsyncEnabled ? 1 : 0, presentFlags );
// SRS - Don't change deviceParms.vsyncEnabled here, simply test for vsync mode 2 to set DXGI SyncInterval
m_SwapChain->Present( deviceParms.vsyncEnabled && r_swapInterval.GetInteger() == 2 ? 1 : 0, presentFlags );
m_FrameFence->SetEventOnCompletion( m_FrameCount, m_FrameFenceEvents[bufferIndex] );
m_GraphicsQueue->Signal( m_FrameFence, m_FrameCount );
@ -631,4 +630,4 @@ void DeviceManager_DX12::Present()
DeviceManager* DeviceManager::CreateD3D12()
{
return new DeviceManager_DX12();
}
}

View file

@ -164,22 +164,17 @@ private:
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
},
// layers
{
#if defined(__APPLE__) && !defined( USE_MoltenVK )
//"VK_LAYER_KHRONOS_synchronization2" // sync2 not supported natively on MoltenVK, use layer implementation instead
#endif
},
{ },
// device
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_MAINTENANCE1_EXTENSION_NAME,
#if defined(__APPLE__)
#if defined( VK_KHR_portability_subset )
VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
#endif
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME,
#if !defined( USE_MoltenVK )
//VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME
#endif
#endif
},
};
@ -197,14 +192,20 @@ private:
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
},
// layers
{ },
{
#if defined(__APPLE__)
// SRS - synchronization2 not supported natively on MoltenVK, use layer implementation instead
"VK_LAYER_KHRONOS_synchronization2"
#endif
},
// device
{
VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
VK_NV_MESH_SHADER_EXTENSION_NAME,
VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME,
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME
},
};
@ -257,6 +258,9 @@ private:
std::queue<nvrhi::EventQueryHandle> m_FramesInFlight;
std::vector<nvrhi::EventQueryHandle> m_QueryPool;
// SRS - flag indicating support for eFifoRelaxed surface presentation (r_swapInterval = 1) mode
bool enablePModeFifoRelaxed = false;
private:
static VKAPI_ATTR VkBool32 VKAPI_CALL vulkanDebugCallback(
@ -570,6 +574,14 @@ bool DeviceManager_VK::pickPhysicalDevice()
deviceIsGood = false;
}
if( ( find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eImmediate ) == surfacePModes.end() ) ||
( find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eFifo ) == surfacePModes.end() ) )
{
// can't find the required surface present modes
errorStream << std::endl << " - does not support the requested surface present modes";
deviceIsGood = false;
}
if( !findQueueFamilies( dev, m_WindowSurface ) )
{
// device doesn't have all the queue families we need
@ -706,6 +718,7 @@ bool DeviceManager_VK::createDevice()
bool rayQuerySupported = false;
bool meshletsSupported = false;
bool vrsSupported = false;
bool sync2Supported = false;
common->Printf( "Enabled Vulkan device extensions:\n" );
for( const auto& ext : enabledExtensions.device )
@ -737,6 +750,10 @@ bool DeviceManager_VK::createDevice()
{
vrsSupported = true;
}
else if( ext == VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME )
{
sync2Supported = true;
}
}
std::unordered_set<int> uniqueQueueFamilies =
@ -782,7 +799,17 @@ bool DeviceManager_VK::createDevice()
.setPrimitiveFragmentShadingRate( true )
.setAttachmentFragmentShadingRate( true );
auto sync2Features = vk::PhysicalDeviceSynchronization2FeaturesKHR()
.setSynchronization2( true );
#if defined(__APPLE__) && defined( VK_KHR_portability_subset )
auto portabilityFeatures = vk::PhysicalDevicePortabilitySubsetFeaturesKHR()
.setImageViewFormatSwizzle( true );
void* pNext = &portabilityFeatures;
#else
void* pNext = nullptr;
#endif
#define APPEND_EXTENSION(condition, desc) if (condition) { (desc).pNext = pNext; pNext = &(desc); } // NOLINT(cppcoreguidelines-macro-usage)
APPEND_EXTENSION( accelStructSupported, accelStructFeatures )
APPEND_EXTENSION( bufferAddressSupported, bufferAddressFeatures )
@ -790,6 +817,7 @@ bool DeviceManager_VK::createDevice()
APPEND_EXTENSION( rayQuerySupported, rayQueryFeatures )
APPEND_EXTENSION( meshletsSupported, meshletFeatures )
APPEND_EXTENSION( vrsSupported, vrsFeatures )
APPEND_EXTENSION( sync2Supported, sync2Features )
#undef APPEND_EXTENSION
auto deviceFeatures = vk::PhysicalDeviceFeatures()
@ -800,6 +828,7 @@ bool DeviceManager_VK::createDevice()
#if !defined(__APPLE__)
.setGeometryShader( true )
#endif
.setFillModeNonSolid( true )
.setImageCubeArray( true )
.setDualSrcBlend( true );
@ -844,7 +873,21 @@ bool DeviceManager_VK::createDevice()
m_VulkanDevice.getQueue( m_PresentQueueFamily, 0, &m_PresentQueue );
VULKAN_HPP_DEFAULT_DISPATCHER.init( m_VulkanDevice );
// SRS - Determine if preferred image depth/stencil format D24S8 is supported (issue with Vulkan on AMD GPUs)
vk::ImageFormatProperties imageFormatProperties;
const vk::Result ret = m_VulkanPhysicalDevice.getImageFormatProperties( vk::Format::eD24UnormS8Uint,
vk::ImageType::e2D,
vk::ImageTiling::eOptimal,
vk::ImageUsageFlags( vk::ImageUsageFlagBits::eDepthStencilAttachment ),
vk::ImageCreateFlags( 0 ),
&imageFormatProperties );
deviceParms.enableImageFormatD24S8 = ( ret == vk::Result::eSuccess );
// SRS - Determine if "smart" (r_swapInterval = 1) vsync mode eFifoRelaxed is supported by device and surface
auto surfacePModes = m_VulkanPhysicalDevice.getSurfacePresentModesKHR( m_WindowSurface );
enablePModeFifoRelaxed = find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eFifoRelaxed ) != surfacePModes.end();
// stash the renderer string
auto prop = m_VulkanPhysicalDevice.getProperties();
m_RendererString = std::string( prop.deviceName.data() );
@ -896,19 +939,22 @@ void DeviceManager_VK::destroySwapChain()
m_VulkanDevice.waitIdle();
}
while( !m_SwapChainImages.empty() )
{
auto sci = m_SwapChainImages.back();
m_SwapChainImages.pop_back();
sci.rhiHandle = nullptr;
}
if( m_SwapChain )
{
m_VulkanDevice.destroySwapchainKHR( m_SwapChain );
m_SwapChain = nullptr;
}
m_SwapChainImages.clear();
}
bool DeviceManager_VK::createSwapChain()
{
destroySwapChain();
m_SwapChainFormat =
{
vk::Format( nvrhi::vulkan::convertFormat( deviceParms.swapChainFormat ) ),
@ -940,7 +986,7 @@ bool DeviceManager_VK::createSwapChain()
.setPQueueFamilyIndices( enableSwapChainSharing ? queues.data() : nullptr )
.setPreTransform( vk::SurfaceTransformFlagBitsKHR::eIdentity )
.setCompositeAlpha( vk::CompositeAlphaFlagBitsKHR::eOpaque )
.setPresentMode( deviceParms.vsyncEnabled ? vk::PresentModeKHR::eFifo : vk::PresentModeKHR::eImmediate )
.setPresentMode( deviceParms.vsyncEnabled ? ( r_swapInterval.GetInteger() == 2 || !enablePModeFifoRelaxed ? vk::PresentModeKHR::eFifo : vk::PresentModeKHR::eFifoRelaxed ) : vk::PresentModeKHR::eImmediate )
.setClipped( true )
.setOldSwapchain( nullptr );
@ -1134,7 +1180,7 @@ void DeviceManager_VK::BeginFrame()
vk::Fence(),
&m_SwapChainIndex );
assert( res == vk::Result::eSuccess );
assert( res == vk::Result::eSuccess || res == vk::Result::eSuboptimalKHR );
m_NvrhiDevice->queueWaitForSemaphore( nvrhi::CommandQueue::Graphics, m_PresentSemaphore, 0 );
}
@ -1158,7 +1204,7 @@ void DeviceManager_VK::Present()
.setPImageIndices( &m_SwapChainIndex );
const vk::Result res = m_PresentQueue.presentKHR( &info );
assert( res == vk::Result::eSuccess || res == vk::Result::eErrorOutOfDateKHR );
assert( res == vk::Result::eSuccess || res == vk::Result::eErrorOutOfDateKHR || res == vk::Result::eSuboptimalKHR );
if( deviceParms.enableDebugRuntime )
{

View file

@ -970,11 +970,19 @@ sysEvent_t Sys_GetEvent()
{
int w = ev.window.data1;
int h = ev.window.data2;
r_windowWidth.SetInteger( w );
r_windowHeight.SetInteger( h );
// SRS - Only save window resized events when in windowed modes
if( !renderSystem->IsFullScreen() )
{
r_windowWidth.SetInteger( w );
r_windowHeight.SetInteger( h );
}
glConfig.nativeScreenWidth = w;
glConfig.nativeScreenHeight = h;
// SRS - Make sure ImGui gets new window boundaries
ImGuiHook::NotifyDisplaySizeChanged( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
break;
}
@ -982,8 +990,13 @@ sysEvent_t Sys_GetEvent()
{
int x = ev.window.data1;
int y = ev.window.data2;
r_windowX.SetInteger( x );
r_windowY.SetInteger( y );
// SRS - Only save window moved events when in windowed modes
if( !renderSystem->IsFullScreen() )
{
r_windowX.SetInteger( x );
r_windowY.SetInteger( y );
}
break;
}
}
@ -1049,7 +1062,7 @@ sysEvent_t Sys_GetEvent()
case SDL_KEYDOWN:
if( ev.key.keysym.sym == SDLK_RETURN && ( ev.key.keysym.mod & KMOD_ALT ) > 0 )
{
// DG: go to fullscreen on current display, instead of always first display
/* DG: go to fullscreen on current display, instead of always first display
int fullscreen = 0;
if( ! renderSystem->IsFullScreen() )
{
@ -1058,7 +1071,10 @@ sysEvent_t Sys_GetEvent()
fullscreen = -2;
}
cvarSystem->SetCVarInteger( "r_fullscreen", fullscreen );
// DG end
// DG end */
// SRS - Until Borderless Fullscreen is implemented properly, use same implementation as on Windows
cvarSystem->SetCVarBool( "r_fullscreen", !renderSystem->IsFullScreen() );
// SRS end
PushConsoleEvent( "vid_restart" );
continue; // handle next event
}

View file

@ -135,21 +135,17 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
return false;
}
glConfig.isFullscreen = parms.fullScreen;
UpdateWindowSize( parms );
return true;
}
void DeviceManager::UpdateWindowSize( const glimpParms_t& params )
void DeviceManager::UpdateWindowSize( const glimpParms_t& parms )
{
windowVisible = true;
if( int( deviceParms.backBufferWidth ) != params.width ||
int( deviceParms.backBufferHeight ) != params.height ||
if( int( deviceParms.backBufferWidth ) != parms.width ||
int( deviceParms.backBufferHeight ) != parms.height ||
#if ID_MSAA
int( deviceParms.backBufferSampleCount ) != params.multiSamples ||
int( deviceParms.backBufferSampleCount ) != parms.multiSamples ||
#endif
( deviceParms.vsyncEnabled != requestedVSync && GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) )
{
@ -157,16 +153,18 @@ void DeviceManager::UpdateWindowSize( const glimpParms_t& params )
BackBufferResizing();
deviceParms.backBufferWidth = params.width;
deviceParms.backBufferHeight = params.height;
deviceParms.backBufferSampleCount = params.multiSamples;
deviceParms.backBufferWidth = parms.width;
deviceParms.backBufferHeight = parms.height;
deviceParms.backBufferSampleCount = parms.multiSamples;
deviceParms.vsyncEnabled = requestedVSync;
ResizeSwapChain();
BackBufferResized();
}
deviceParms.vsyncEnabled = requestedVSync;
else
{
deviceParms.vsyncEnabled = requestedVSync;
}
}
#endif
@ -190,6 +188,18 @@ void VKimp_PreInit() // DG: added this function for SDL compatibility
}
}
// SRS - Function to get display frequency of monitor hosting the current window
static int GetDisplayFrequency( glimpParms_t parms )
{
SDL_DisplayMode m = {0};
if( SDL_GetWindowDisplayMode( window, &m ) < 0 )
{
common->Warning( "Couldn't get display refresh rate, reason: %s", SDL_GetError() );
return parms.displayHz;
}
return m.refresh_rate;
}
/* Eric: Is the majority of this function not needed since switching from GL to Vulkan?
===================
@ -346,6 +356,19 @@ bool VKimp_Init( glimpParms_t parms )
continue;
}
// SRS - Make sure display is set to requested refresh rate from the start
if( parms.displayHz > 0 && parms.displayHz != GetDisplayFrequency( parms ) )
{
SDL_DisplayMode m = {0};
SDL_GetWindowDisplayMode( window, &m );
m.refresh_rate = parms.displayHz;
if( SDL_SetWindowDisplayMode( window, &m ) < 0 )
{
common->Warning( "Couldn't set display refresh rate to %i Hz", parms.displayHz );
}
}
// RB begin
SDL_GetWindowSize( window, &glConfig.nativeScreenWidth, &glConfig.nativeScreenHeight );
// RB end
@ -362,7 +385,7 @@ bool VKimp_Init( glimpParms_t parms )
#endif
// RB begin
glConfig.displayFrequency = 60;
glConfig.displayFrequency = GetDisplayFrequency( parms );
glConfig.isStereoPixelFormat = parms.stereo;
glConfig.multisamples = parms.multiSamples;
@ -451,7 +474,7 @@ static bool SetScreenParmsFullscreen( glimpParms_t parms )
// change settings in that display mode according to parms
// FIXME: check if refreshrate, width and height are supported?
// m.refresh_rate = parms.displayHz;
m.refresh_rate = parms.displayHz;
m.w = parms.width;
m.h = parms.height;
@ -476,8 +499,10 @@ static bool SetScreenParmsFullscreen( glimpParms_t parms )
static bool SetScreenParmsWindowed( glimpParms_t parms )
{
SDL_SetWindowSize( window, parms.width, parms.height );
// SRS - handle differences in WM behaviour: for macOS set position first, for linux set it last
#if defined(__APPLE__)
SDL_SetWindowPosition( window, parms.x, parms.y );
#endif
// if we're currently in fullscreen mode, we need to disable that
if( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN )
@ -488,6 +513,17 @@ static bool SetScreenParmsWindowed( glimpParms_t parms )
return false;
}
}
SDL_SetWindowSize( window, parms.width, parms.height );
// SRS - this logic prevents window position drift on linux when coming in and out of fullscreen
#if !defined(__APPLE__)
SDL_bool borderState = SDL_GetWindowFlags( window ) & SDL_WINDOW_BORDERLESS ? SDL_FALSE : SDL_TRUE;
SDL_SetWindowBordered( window, SDL_FALSE );
SDL_SetWindowPosition( window, parms.x, parms.y );
SDL_SetWindowBordered( window, borderState );
#endif
return true;
}
@ -524,7 +560,7 @@ bool VKimp_SetScreenParms( glimpParms_t parms )
glConfig.isStereoPixelFormat = parms.stereo;
glConfig.nativeScreenWidth = parms.width;
glConfig.nativeScreenHeight = parms.height;
glConfig.displayFrequency = parms.displayHz;
glConfig.displayFrequency = GetDisplayFrequency( parms );
glConfig.multisamples = parms.multiSamples;
return true;

File diff suppressed because it is too large Load diff

View file

@ -694,6 +694,8 @@ GetDisplayCoordinates
*/
static bool GetDisplayCoordinates( const int deviceNum, int& x, int& y, int& width, int& height, int& displayHz )
{
bool verbose = false;
idStr deviceName = GetDeviceName( deviceNum );
if( deviceName.Length() == 0 )
{
@ -729,24 +731,27 @@ static bool GetDisplayCoordinates( const int deviceNum, int& x, int& y, int& wid
return false;
}
common->Printf( "display device: %i\n", deviceNum );
common->Printf( " DeviceName : %s\n", device.DeviceName );
common->Printf( " DeviceString: %s\n", device.DeviceString );
common->Printf( " StateFlags : 0x%x\n", device.StateFlags );
common->Printf( " DeviceID : %s\n", device.DeviceID );
common->Printf( " DeviceKey : %s\n", device.DeviceKey );
common->Printf( " DeviceName : %s\n", monitor.DeviceName );
common->Printf( " DeviceString: %s\n", monitor.DeviceString );
common->Printf( " StateFlags : 0x%x\n", monitor.StateFlags );
common->Printf( " DeviceID : %s\n", monitor.DeviceID );
common->Printf( " DeviceKey : %s\n", monitor.DeviceKey );
common->Printf( " dmPosition.x : %i\n", devmode.dmPosition.x );
common->Printf( " dmPosition.y : %i\n", devmode.dmPosition.y );
common->Printf( " dmBitsPerPel : %i\n", devmode.dmBitsPerPel );
common->Printf( " dmPelsWidth : %i\n", devmode.dmPelsWidth );
common->Printf( " dmPelsHeight : %i\n", devmode.dmPelsHeight );
common->Printf( " dmDisplayFlags : 0x%x\n", devmode.dmDisplayFlags );
common->Printf( " dmDisplayFrequency: %i\n", devmode.dmDisplayFrequency );
if( verbose )
{
common->Printf("display device: %i\n", deviceNum);
common->Printf(" DeviceName : %s\n", device.DeviceName);
common->Printf(" DeviceString: %s\n", device.DeviceString);
common->Printf(" StateFlags : 0x%x\n", device.StateFlags);
common->Printf(" DeviceID : %s\n", device.DeviceID);
common->Printf(" DeviceKey : %s\n", device.DeviceKey);
common->Printf(" DeviceName : %s\n", monitor.DeviceName);
common->Printf(" DeviceString: %s\n", monitor.DeviceString);
common->Printf(" StateFlags : 0x%x\n", monitor.StateFlags);
common->Printf(" DeviceID : %s\n", monitor.DeviceID);
common->Printf(" DeviceKey : %s\n", monitor.DeviceKey);
common->Printf(" dmPosition.x : %i\n", devmode.dmPosition.x);
common->Printf(" dmPosition.y : %i\n", devmode.dmPosition.y);
common->Printf(" dmBitsPerPel : %i\n", devmode.dmBitsPerPel);
common->Printf(" dmPelsWidth : %i\n", devmode.dmPelsWidth);
common->Printf(" dmPelsHeight : %i\n", devmode.dmPelsHeight);
common->Printf(" dmDisplayFlags : 0x%x\n", devmode.dmDisplayFlags);
common->Printf(" dmDisplayFrequency: %i\n", devmode.dmDisplayFrequency);
}
x = devmode.dmPosition.x;
y = devmode.dmPosition.y;
@ -1065,6 +1070,29 @@ static bool GLW_GetWindowDimensions( const glimpParms_t parms, int& x, int& y, i
return true;
}
static bool GetCenteredWindowDimensions( int& x, int& y, int& w, int& h )
{
// get position and size of default display for windowed mode (parms.fullScreen = 0)
int displayX, displayY, displayW, displayH, displayHz = 0;
if( !GetDisplayCoordinates( 0, displayX, displayY, displayW, displayH, displayHz ) )
{
return false;
}
// find the centered position not exceeding display bounds
const int centreX = displayX + displayW / 2;
const int centreY = displayY + displayH / 2;
const int left = centreX - w / 2;
const int right = left + w;
const int top = centreY - h / 2;
const int bottom = top + h;
x = std::max( left, displayX );
y = std::max( top, displayY );
w = std::min( right - left, displayW );
h = std::min( bottom - top, displayH );
return true;
}
bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, const char* windowTitle )
{
@ -1074,6 +1102,15 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
return false;
}
// SRS - if in windowed mode, start with centered windowed on default display, afterwards use r_windowX / r_windowY
if( parms.fullScreen == 0 )
{
if( !GetCenteredWindowDimensions( x, y, w, h ) )
{
return false;
}
}
int stylebits;
int exstyle;
@ -1136,21 +1173,17 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c
SetForegroundWindow( win32.hWnd );
SetFocus( win32.hWnd );
glConfig.isFullscreen = parms.fullScreen;
UpdateWindowSize( parms );
return true;
}
void DeviceManager::UpdateWindowSize( const glimpParms_t& params )
void DeviceManager::UpdateWindowSize( const glimpParms_t& parms )
{
windowVisible = true;
if( int( deviceParms.backBufferWidth ) != params.width ||
int( deviceParms.backBufferHeight ) != params.height ||
if( int( deviceParms.backBufferWidth ) != parms.width ||
int( deviceParms.backBufferHeight ) != parms.height ||
#if ID_MSAA
int( deviceParms.backBufferSampleCount ) != params.multiSamples ||
int( deviceParms.backBufferSampleCount ) != parms.multiSamples ||
#endif
( deviceParms.vsyncEnabled != requestedVSync && GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) )
{
@ -1158,16 +1191,18 @@ void DeviceManager::UpdateWindowSize( const glimpParms_t& params )
BackBufferResizing();
deviceParms.backBufferWidth = params.width;
deviceParms.backBufferHeight = params.height;
deviceParms.backBufferSampleCount = params.multiSamples;
deviceParms.backBufferWidth = parms.width;
deviceParms.backBufferHeight = parms.height;
deviceParms.backBufferSampleCount = parms.multiSamples;
deviceParms.vsyncEnabled = requestedVSync;
ResizeSwapChain();
BackBufferResized();
}
deviceParms.vsyncEnabled = requestedVSync;
else
{
deviceParms.vsyncEnabled = requestedVSync;
}
}
/*
@ -1375,6 +1410,28 @@ void GLimp_PreInit()
// DG: not needed on this platform, so just do nothing
}
// SRS - Function to get display frequency of monitor hosting the current window
static int GetDisplayFrequency( glimpParms_t parms )
{
HMONITOR hMonitor = MonitorFromWindow( win32.hWnd, MONITOR_DEFAULTTOPRIMARY );
MONITORINFOEX minfo;
minfo.cbSize = sizeof( minfo );
if( !GetMonitorInfo( hMonitor, &minfo ) )
{
return parms.displayHz;
}
DEVMODE devmode;
devmode.dmSize = sizeof( devmode );
if( !EnumDisplaySettings( minfo.szDevice, ENUM_CURRENT_SETTINGS, &devmode ) )
{
return parms.displayHz;
}
return devmode.dmDisplayFrequency;
}
/*
===================
GLimp_Init
@ -1455,6 +1512,7 @@ bool GLimp_Init( glimpParms_t parms )
glConfig.isStereoPixelFormat = parms.stereo;
glConfig.nativeScreenWidth = parms.width;
glConfig.nativeScreenHeight = parms.height;
glConfig.displayFrequency = GetDisplayFrequency( parms );
glConfig.multisamples = parms.multiSamples;
glConfig.pixelAspect = 1.0f; // FIXME: some monitor modes may be distorted
@ -1538,11 +1596,11 @@ bool GLimp_SetScreenParms( glimpParms_t parms )
glConfig.isFullscreen = parms.fullScreen;
glConfig.pixelAspect = 1.0f; // FIXME: some monitor modes may be distorted
glConfig.isFullscreen = parms.fullScreen;
glConfig.isStereoPixelFormat = parms.stereo;
glConfig.nativeScreenWidth = parms.width;
glConfig.nativeScreenHeight = parms.height;
deviceManager->UpdateWindowSize( parms );
glConfig.displayFrequency = GetDisplayFrequency( parms );
glConfig.multisamples = parms.multiSamples;
return true;
}

View file

@ -179,31 +179,32 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
switch( uMsg )
{
case WM_WINDOWPOSCHANGED:
// RB: FIXME this messes with with the window size in a really bad way
#if 0
if( renderSystem->IsInitialized() )//&& win32.hDC != NULL )
// SRS - Needed by ResizeImages() to resize before the start of a frame
// SRS - Aspect ratio constraints are controlled by WIN_Sizing() above
if( renderSystem->IsInitialized() && win32.hDC != NULL )
{
RECT rect;
if( ::GetClientRect( win32.hWnd, &rect ) )
{
auto originalWidth = glConfig.nativeScreenWidth;
auto originalHeight = glConfig.nativeScreenHeight;
if( rect.right > rect.left && rect.bottom > rect.top )
{
glConfig.nativeScreenWidth = rect.right - rect.left;
glConfig.nativeScreenHeight = rect.bottom - rect.top;
// save the window size in cvars if we aren't fullscreen
// SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen
int style = GetWindowLong( hWnd, GWL_STYLE );
if( ( style & WS_POPUP ) == 0 )
if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() )
{
r_windowWidth.SetInteger( glConfig.nativeScreenWidth );
r_windowHeight.SetInteger( glConfig.nativeScreenHeight );
}
// SRS - Inform ImGui that the window size has changed
ImGuiHook::NotifyDisplaySizeChanged( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
}
}
}
#endif
break;
case WM_MOVE:
{
@ -211,8 +212,9 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
RECT r;
// save the window origin in cvars if we aren't fullscreen
// SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen
int style = GetWindowLong( hWnd, GWL_STYLE );
if( ( style & WS_POPUP ) == 0 )
if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() )
{
xPos = ( short ) LOWORD( lParam ); // horizontal position
yPos = ( short ) HIWORD( lParam ); // vertical position