macOS support for OpenGL and MoltenVK, demo recording/playback improvements

This commit is contained in:
Stephen Saunders 2021-04-19 14:31:15 -04:00
parent 09c9f254c8
commit 0aae6f0902
66 changed files with 838 additions and 175 deletions

View file

@ -593,8 +593,8 @@ void G_DoLoadLevel ()
::g->joyxmove = ::g->joyymove = 0;
::g->mousex = ::g->mousey = 0;
::g->sendpause = ::g->sendsave = ::g->paused = false;
memset (::g->mousebuttons, 0, sizeof(::g->mousebuttons));
memset (::g->joybuttons, 0, sizeof(::g->joybuttons));
memset (::g->mousebuttons, 0, sizeof(::g->mousebuttons[0])*3); // SRS - mousebuttons[0] points at mousearray[1] to mousearray[3], [-1] allowed
memset (::g->joybuttons, 0, sizeof(::g->joybuttons[0])*4); // SRS - joybuttons[0] points at joyarray[1] to joyarray[4], [-1] allowed
}
//

View file

@ -820,7 +820,7 @@ int reloadlump;
// w_wad.vars end //
// z_zone.vars begin //
int sizes[NUM_ZONES+1];
memzone_t* zones[NUM_ZONES] ;
memzone_t* zones[NUM_ZONES+1] ; // SRS - Added +1 so NUM_ZONES index is not beyond end of array
int NumAlloc ;
// z_zone.vars end //
// info vars begin //

View file

@ -33,6 +33,9 @@ option(USE_VULKAN
option(SPIRV_SHADERC
"Compile SPIR-V shader byte code using shaderc instead of using Glslang directly" OFF)
option(USE_MoltenVK
"Use MoltenVK library instead of Vulkan library on macOS" OFF)
option(ONATIVE
"Optimize for the host CPU" OFF)
@ -84,7 +87,8 @@ endif()
if (FORCE_COLOR_OUTPUT)
if (CMAKE_COMPILER_IS_GNUCC)
add_compile_options(-fdiagnostics-color=always)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
# SRS - Add test for AppleClang
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
add_compile_options(-fcolor-diagnostics)
endif ()
endif ()
@ -112,7 +116,8 @@ else()
message(STATUS CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE})
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
# SRS - Add test for AppleClang
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
add_definitions(-pipe)
#add_definitions(-Wall)
add_definitions(-Werror=format-security)
@ -153,11 +158,14 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_definitions(-DUSE_EXCEPTIONS)
#endif()
add_compile_options(-Wno-pragmas -Wno-unused-variable -Wno-switch -Wno-unused-value -Winvalid-pch -Wno-multichar)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
# SRS - Change add_compile_options to add_definitions so options propagate to pre-compiled header build settings
add_definitions(-Wno-pragmas -Wno-unused-variable -Wno-switch -Wno-unused-value -Winvalid-pch -Wno-multichar)
# SRS - Add test for AppleClang
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
# add clang-specific settings for warnings (the second one make sure clang doesn't complain
# about unknown -W flags, like -Wno-unused-but-set-variable)
add_compile_options(-Wno-local-type-template-args -Wno-unknown-warning-option -Wno-inline-new-delete -Wno-switch-enum)
# SRS - Add -Wno-deprecated-register and -Wno-expansion-to-defined to list of warning settings
add_definitions(-Wno-local-type-template-args -Wno-unknown-warning-option -Wno-inline-new-delete -Wno-switch-enum -Wno-deprecated-register -Wno-expansion-to-defined)
endif()
if(NOT CMAKE_CROSSCOMPILING AND ONATIVE)
@ -168,11 +176,28 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
endif()
endif()
add_compile_options(-fno-strict-aliasing)
# SRS - Change add_compile_options to add_definitions so options propagate to pre-compiled header build settings
add_definitions(-fno-strict-aliasing)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0 -ggdb")
#set(CMAKE_C_FLAGS_DEBUGALL "${CMAKE_C_FLAGS_DEBUGALL} -g -ggdb -D_DEBUG")
#set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE} -g -ggdb -D_DEBUG -O1 -fno-omit-frame-pointer")
# SRS - Make sure OSX can find system headers and add support for minimum OSX runtime version
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# SRS - Also add -fasm-blocks otherwise Xcode complains
add_definitions(-fasm-blocks -isysroot "${CMAKE_OSX_SYSROOT}")
if("${CMAKE_OSX_DEPLOYMENT_TARGET}")
add_definitions(-mmacosx-version-min="${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
endif()
#SRS - some #ifdef _DEBUG code can cause game to crash on OSX, remove -D_DEBUG for now and fix later
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -O0")
#set(CMAKE_C_FLAGS_DEBUGALL "${CMAKE_C_FLAGS_DEBUGALL} -g -ggdb")
#set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE} -g -ggdb -O1 -fno-omit-frame-pointer")
else()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -D_DEBUG -O0")
#set(CMAKE_C_FLAGS_DEBUGALL "${CMAKE_C_FLAGS_DEBUGALL} -g -ggdb -D_DEBUG")
#set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE} -g -ggdb -D_DEBUG -O1 -fno-omit-frame-pointer")
endif()
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -ffast-math -fno-unsafe-math-optimizations -fomit-frame-pointer")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -ffast-math -fno-unsafe-math-optimizations -fomit-frame-pointer")
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -Os -ffast-math -fno-unsafe-math-optimizations -fomit-frame-pointer")
@ -333,7 +358,8 @@ if(USE_VULKAN)
if(SPIRV_SHADERC)
add_definitions(-DSPIRV_SHADERC)
if(CMAKE_CL_64)
# SRS - Add case for UNIX/OSX
if(CMAKE_CL_64 OR UNIX)
link_directories($ENV{VULKAN_SDK}/Lib)
else()
link_directories($ENV{VULKAN_SDK}/Lib32)
@ -374,7 +400,13 @@ if(USE_VULKAN)
if(NOT Vulkan_FOUND)
message(FATAL_ERROR "Could not find Vulkan library!")
else()
message(STATUS ${Vulkan_LIBRARY})
# SRS - Optionally use MoltenVK headers/library for runtime config functions on OSX
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND USE_MoltenVK)
add_definitions(-DUSE_MoltenVK)
include_directories($ENV{VULKAN_SDK}/../MoltenVK/include)
set(Vulkan_LIBRARY $ENV{VULKAN_SDK}/lib/libMoltenVK.dylib)
endif()
message(STATUS "Using Vulkan: " ${Vulkan_LIBRARY})
endif()
add_definitions(-DUSE_VULKAN)
@ -386,7 +418,12 @@ if(USE_VULKAN)
if(X11_XCB_FOUND)
add_definitions(-DHAVE_X11_XCB)
list(APPEND SUBSYSTEMS [X11])
include_directories(${X11_XCB_INCLUDE_DIRS})
# SRS - Added PKG_ preface to X11_XCB_INCLUDE_DIRS for OSX, not sure about UNIX
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
include_directories(${PKG_X11_XCB_INCLUDE_DIRS})
else()
include_directories(${X11_XCB_INCLUDE_DIRS})
endif()
endif()
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR)
elseif(WIN32)
@ -1701,9 +1738,14 @@ else()
set(Vulkan_LIBRARIES
${Vulkan_LIBRARY}
${X11_XCB_LIBRARIES}
glslang
SPIRV
)
)
# SRS - Added UNIX/OSX support for shaderc
if(SPIRV_SHADERC)
list(APPEND Vulkan_LIBRARIES shaderc_combined)
else()
list(APPEND Vulkan_LIBRARIES glslang SPIRV)
endif()
if(ENABLE_GLSLANG_BINARIES)
list(APPEND Vulkan_LIBRARIES glslang-default-resource-limits)

View file

@ -0,0 +1,5 @@
cd ..
rm -rf build
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo

View file

@ -0,0 +1,5 @@
cd ..
rm -rf build
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo

View file

@ -0,0 +1,5 @@
cd ..
rm -rf build
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DID_RETAIL" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo

View file

@ -2,4 +2,4 @@ cd ..
rm -rf build
mkdir build
cd build
cmake -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF ../neo -Wno-dev -Wexpansion-to-defined
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev

View file

@ -2,4 +2,4 @@ cd ..
rm -rf build
mkdir build
cd build
cmake -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF ../neo
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev

View file

@ -0,0 +1,5 @@
cd ..
rm -rf build
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DID_RETAIL" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev

View file

@ -0,0 +1,5 @@
cd ..
rm -rf xcode-opengl-debug
mkdir xcode-opengl-debug
cd xcode-opengl-debug
cmake -G Xcode -DCMAKE_BUILD_TYPE=Debug -DSDL2=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo

View file

@ -0,0 +1,5 @@
cd ..
rm -rf xcode-opengl-release
mkdir xcode-opengl-release
cd xcode-opengl-release
cmake -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo

View file

@ -0,0 +1,5 @@
cd ..
rm -rf xcode-vulkan-debug
mkdir xcode-vulkan-debug
cd xcode-vulkan-debug
cmake -G Xcode -DCMAKE_BUILD_TYPE=Debug -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev

View file

@ -0,0 +1,5 @@
cd ..
rm -rf xcode-vulkan-release
mkdir xcode-vulkan-release
cd xcode-vulkan-release
cmake -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DSDL2=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev

View file

@ -184,7 +184,7 @@ idMenuHandler_HUD::ShowTip
*/
void idMenuHandler_HUD::ShowTip( const char* title, const char* tip, bool autoHide )
{
autoHideTip = autoHideTip;
autoHideTip = autoHide; // SRS - Changed to assign autoHide to autoHideTip vs. assign autoHideTip to itself
tipStartTime = gameLocal.time;
hiding = false;
idMenuScreen_HUD* screen = GetHud();

View file

@ -268,7 +268,7 @@ bool idMenuWidget_ScrollBar::HandleAction( idWidgetAction& action, const idWidge
CalculatePosition( x, y );
return true;
}
case WIDGET_ACTION_EVENT_DRAG_STOP:
case ( widgetAction_t ) WIDGET_ACTION_EVENT_DRAG_STOP: // SRS - Cast actionHandler_t to widgetAction_t
{
dragging = false;
return true;

View file

@ -764,7 +764,7 @@ idVarDef::SetObject
void idVarDef::SetObject( idScriptObject* object )
{
assert( typeDef );
initialized = initialized;
initialized = initializedConstant; // SRS - Set initialized to initializedConstant vs self-assignment
assert( typeDef->Inherits( &type_object ) );
*value.objectPtrPtr = object;
}

View file

@ -75,8 +75,9 @@ public:
virtual void BufferCommandText( cmdExecution_t exec, const char* text );
virtual void ExecuteCommandBuffer();
virtual void ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, bool stripFolder, ... );
virtual void ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, int stripFolder, ... );
// SRS - Changed stripFolder type from bool to int for compatibility with va_start()
virtual void ArgCompletion_DeclName( const idCmdArgs& args, void( *callback )( const char* s ), int type );
virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs& args );
@ -796,7 +797,8 @@ void idCmdSystemLocal::ExecuteCommandBuffer()
idCmdSystemLocal::ArgCompletion_FolderExtension
============
*/
void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, bool stripFolder, ... )
void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, int stripFolder, ... )
// SRS - Changed stripFolder type from bool to int for compatibility with va_start()
{
int i;
idStr string;

View file

@ -170,7 +170,8 @@ public:
virtual void ExecuteCommandBuffer() = 0;
// Base for path/file auto-completion.
virtual void ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, bool stripFolder, ... ) = 0;
virtual void ArgCompletion_FolderExtension( const idCmdArgs& args, void( *callback )( const char* s ), const char* folder, int stripFolder, ... ) = 0;
// SRS - Changed stripFolder type from bool to int for compatibility with va_start()
// Base for decl name auto-completion.
virtual void ArgCompletion_DeclName( const idCmdArgs& args, void( *callback )( const char* s ), int type ) = 0;

View file

@ -76,7 +76,7 @@ idCVar com_forceGenericSIMD( "com_forceGenericSIMD", "0", CVAR_BOOL | CVAR_SYSTE
idCVar com_developer( "developer", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "developer mode" );
idCVar com_speeds( "com_speeds", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "show engine timings" );
// DG: support "com_showFPS 1" for fps-only view like in classic doom3 => make it CVAR_INTEGER
idCVar com_showFPS( "com_showFPS", "0", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "show frames rendered per second. 0: off 1: default bfg values, 2: only show FPS (classic view)" );
idCVar com_showFPS( "com_showFPS", "0", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_NOCHEAT, "show frames rendered per second. 0: off, 1: only show FPS (classic view), 2: default bfg values" );
// DG end
idCVar com_showMemoryUsage( "com_showMemoryUsage", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "show total and per frame memory usage" );
idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" );
@ -1338,7 +1338,8 @@ void idCommonLocal::Init( int argc, const char* const* argv, const char* cmdline
// display the legal splash screen
// No clue why we have to render this twice to show up...
RenderSplash();
//RenderSplash();
// SRS - OSX needs this for some OpenGL drivers, otherwise renders leftover image before splash
RenderSplash();
}
@ -1420,7 +1421,8 @@ void idCommonLocal::Init( int argc, const char* const* argv, const char* cmdline
AddStartupCommands();
StartMenu( true );
#ifndef ID_RETAIL
// SRS - changed ifndef to ifdef since legalMinTime should apply to retail builds, not dev builds
#ifdef ID_RETAIL
while( Sys_Milliseconds() - legalStartTime < legalMinTime )
{
RenderSplash();
@ -1792,7 +1794,8 @@ idCommonLocal::ProcessEvent
bool idCommonLocal::ProcessEvent( const sysEvent_t* event )
{
// hitting escape anywhere brings up the menu
if( game && game->IsInGame() )
// SRS - allow escape during demo playback to cancel
if( game && ( game->IsInGame() || readDemo ) )
{
if( event->evType == SE_KEY && event->evValue2 == 1 && ( event->evValue == K_ESCAPE || event->evValue == K_JOY9 ) )
{
@ -1812,8 +1815,16 @@ bool idCommonLocal::ProcessEvent( const sysEvent_t* event )
}
console->Close();
StartMenu();
// SRS - cancel demo playback and return to the main menu
if ( readDemo )
{
LeaveGame();
}
else
{
StartMenu();
}
return true;
}
else

View file

@ -55,7 +55,7 @@ static idStr FindUnusedFileName( const char* format )
return filename;
}
extern idCVar com_smp;
//extern idCVar com_smp; // SRS - No longer require non-smp mode for demos
void WriteDeclCache( idDemoFile* f, int demoCategory, int demoCode, declType_t declType )
{
@ -106,7 +106,7 @@ void idCommonLocal::StartRecordingRenderDemo( const char* demoName )
console->Close();
com_smp.SetInteger( 0 );
// com_smp.SetInteger( 0 ); // SRS - No longer require non-smp mode for demos
writeDemo = new( TAG_SYSTEM ) idDemoFile;
if( !writeDemo->OpenForWriting( demoName ) )
@ -146,7 +146,7 @@ void idCommonLocal::StopRecordingRenderDemo()
common->Printf( "stopped recording %s.\n", writeDemo->GetName() );
delete writeDemo;
writeDemo = NULL;
com_smp.SetInteger( 1 ); // motorsep 12-30-2014; turn multithreading back on
// com_smp.SetInteger( 1 ); // motorsep 12-30-2014; turn multithreading back on; SRS - No longer require non-smp mode for demos
}
/*
@ -193,7 +193,7 @@ void idCommonLocal::StopPlayingRenderDemo()
timeDemo = TD_NO;
}
com_smp.SetInteger( 1 ); // motorsep 12-30-2014; turn multithreading back on
// com_smp.SetInteger( 1 ); // motorsep 12-30-2014; turn multithreading back on; SRS - No longer require non-smp mode for demos
}
/*
@ -227,7 +227,7 @@ void idCommonLocal::StartPlayingRenderDemo( idStr demoName )
return;
}
com_smp.SetInteger( 0 );
// com_smp.SetInteger( 0 ); // SRS - No longer require non-smp mode for demos
// make sure localSound / GUI intro music shuts up
soundWorld->StopAllSounds();
@ -248,7 +248,8 @@ void idCommonLocal::StartPlayingRenderDemo( idStr demoName )
common->Printf( "couldn't open %s\n", demoName.c_str() );
delete readDemo;
readDemo = NULL;
Stop();
CreateMainMenu(); // SRS - drop back to main menu if demo playback fails
StartMenu();
return;
}
@ -258,8 +259,11 @@ void idCommonLocal::StartPlayingRenderDemo( idStr demoName )
if( opcode != DS_VERSION )
{
common->Printf( "StartPlayingRenderDemo invalid demo file\n" );
Stop();
readDemo->Close();
delete readDemo;
readDemo = NULL;
CreateMainMenu(); // SRS - drop back to main menu if demo playback fails
StartMenu();
return;
}
@ -268,22 +272,35 @@ void idCommonLocal::StartPlayingRenderDemo( idStr demoName )
if( demoVersion != RENDERDEMO_VERSION )
{
common->Printf( "StartPlayingRenderDemo got version %d, expected version %d\n", demoVersion, RENDERDEMO_VERSION );
readDemo->Close();
delete readDemo;
readDemo = NULL;
Stop();
CreateMainMenu(); // SRS - drop back to main menu if demo playback fails
StartMenu();
return;
}
numDemoFrames = 0; // SRS - Moved ahead of first call to AdvanceRenderDemo to properly handle demoshots
numShotFrames = 0; // SRS - Initialize count of demoShot frames to play before timeout to main menu
AdvanceRenderDemo( true );
renderSystem->BeginLevelLoad(); // SRS - Free static data from previous level before loading demo assets
soundSystem->BeginLevelLoad(); // SRS - Free sound media from previous level before loading demo assets
declManager->BeginLevelLoad(); // SRS - Clear declaration manager data before loading demo assets
uiManager->BeginLevelLoad(); // SRS - Clear gui manager data before loading demo assets
Game()->StartDemoPlayback( renderWorld );
AdvanceRenderDemo( true ); // SRS - Call AdvanceRenderDemo() once to load map and initial assets (like level load)
renderSystem->EndLevelLoad(); // SRS - Define static data for use by RB_StencilShadowPass if stencil shadows enabled
soundSystem->EndLevelLoad();
declManager->EndLevelLoad();
uiManager->EndLevelLoad( "" ); // SRS - FIXME: No gui assets are currently saved/reloaded in demo file, fix later?
renderWorld->GenerateAllInteractions();
const bool captureToImage = false;
UpdateScreen( captureToImage );
numDemoFrames = 1;
Game()->StartDemoPlayback( renderWorld );
renderWorld->GenerateAllInteractions();
soundSystem->SetPlayingSoundWorld( soundWorld );
timeDemoStartTime = Sys_Milliseconds();
}
@ -301,11 +318,15 @@ void idCommonLocal::TimeRenderDemo( const char* demoName, bool twice, bool quit
if( twice && readDemo )
{
while( readDemo )
timeDemo = TD_YES; // SRS - Set timeDemo to TD_YES to disable time demo playback pause when window not in focus
while( readDemo )
{
const bool captureToImage = false;
UpdateScreen( captureToImage );
AdvanceRenderDemo( true );
// const bool captureToImage = false;
// UpdateScreen( captureToImage );
BusyWait(); // SRS - Call BusyWait() vs. UpdateScreen() to avoid Pump() timeout messages in console
AdvanceRenderDemo( true );
eventLoop->RunEventLoop(); // SRS - Run event loop to allow keyboard escape to cancel first pass of the demo
}
StartPlayingRenderDemo( demo );
@ -314,6 +335,7 @@ void idCommonLocal::TimeRenderDemo( const char* demoName, bool twice, bool quit
if( !readDemo )
{
timeDemo = TD_NO; // SRS - Make sure timeDemo flag is off if readDemo is NULL
return;
}
@ -499,14 +521,15 @@ void idCommonLocal::AdvanceRenderDemo( bool singleFrameOnly )
switch( ds )
{
case DS_FINISHED:
if( numDemoFrames != 1 )
if( numDemoFrames == 1 )
{
// if the demo has a single frame (a demoShot), continuously replay
// the renderView that has already been read
Stop();
StartMenu();
}
return;
// if the demo has a single frame (a demoShot), continuously replay
// the renderView that has already been read
if ( numShotFrames++ < com_engineHz_latched*10 ) // SRS - play demoShot for min 10 sec then timeout
return;
}
LeaveGame(); // SRS - drop back to main menu after demo playback is finished
return;
case DS_RENDER:
if( renderWorld->ProcessDemoCommand( readDemo, &currentDemoRenderView, &demoTimeOffset ) )
{
@ -527,12 +550,14 @@ void idCommonLocal::AdvanceRenderDemo( bool singleFrameOnly )
}
}
// SRS - Changed macro from CONSOLE_COMMAND to CONSOLE_COMMAND_SHIP for demo-related commands - i.e. include in release builds
/*
================
Common_DemoShot_f
================
*/
CONSOLE_COMMAND( demoShot, "writes a screenshot as a demo", NULL )
CONSOLE_COMMAND_SHIP( demoShot, "writes a screenshot as a demo", NULL )
{
if( args.Argc() != 2 )
{
@ -550,7 +575,7 @@ CONSOLE_COMMAND( demoShot, "writes a screenshot as a demo", NULL )
Common_RecordDemo_f
================
*/
CONSOLE_COMMAND( recordDemo, "records a demo", NULL )
CONSOLE_COMMAND_SHIP( recordDemo, "records a demo", NULL )
{
if( args.Argc() != 2 )
{
@ -568,7 +593,7 @@ CONSOLE_COMMAND( recordDemo, "records a demo", NULL )
Common_CompressDemo_f
================
*/
CONSOLE_COMMAND( compressDemo, "compresses a demo file", idCmdSystem::ArgCompletion_DemoName )
CONSOLE_COMMAND_SHIP( compressDemo, "compresses a demo file", idCmdSystem::ArgCompletion_DemoName )
{
if( args.Argc() == 2 )
{
@ -589,7 +614,7 @@ CONSOLE_COMMAND( compressDemo, "compresses a demo file", idCmdSystem::ArgComplet
Common_StopRecordingDemo_f
================
*/
CONSOLE_COMMAND( stopRecording, "stops demo recording", NULL )
CONSOLE_COMMAND_SHIP( stopRecording, "stops demo recording", NULL )
{
commonLocal.StopRecordingRenderDemo();
}
@ -599,7 +624,7 @@ CONSOLE_COMMAND( stopRecording, "stops demo recording", NULL )
Common_PlayDemo_f
================
*/
CONSOLE_COMMAND( playDemo, "plays back a demo", idCmdSystem::ArgCompletion_DemoName )
CONSOLE_COMMAND_SHIP( playDemo, "plays back a demo", idCmdSystem::ArgCompletion_DemoName )
{
if( args.Argc() >= 2 )
{
@ -612,7 +637,7 @@ CONSOLE_COMMAND( playDemo, "plays back a demo", idCmdSystem::ArgCompletion_DemoN
Common_TimeDemo_f
================
*/
CONSOLE_COMMAND( timeDemo, "times a demo", idCmdSystem::ArgCompletion_DemoName )
CONSOLE_COMMAND_SHIP( timeDemo, "times a demo", idCmdSystem::ArgCompletion_DemoName )
{
if( args.Argc() >= 2 )
{
@ -625,9 +650,9 @@ CONSOLE_COMMAND( timeDemo, "times a demo", idCmdSystem::ArgCompletion_DemoName )
Common_TimeDemoQuit_f
================
*/
CONSOLE_COMMAND( timeDemoQuit, "times a demo and quits", idCmdSystem::ArgCompletion_DemoName )
CONSOLE_COMMAND_SHIP( timeDemoQuit, "times a demo and quits", idCmdSystem::ArgCompletion_DemoName )
{
commonLocal.TimeRenderDemo( va( "demos/%s", args.Argv( 1 ) ), true );
commonLocal.TimeRenderDemo( va( "demos/%s", args.Argv( 1 ) ), ( args.Argc() > 2 ), true ); // SRS - fixed missing "twice" argument
}
/*
@ -635,7 +660,7 @@ CONSOLE_COMMAND( timeDemoQuit, "times a demo and quits", idCmdSystem::ArgComplet
Common_AVIDemo_f
================
*/
CONSOLE_COMMAND( aviDemo, "writes AVIs for a demo", idCmdSystem::ArgCompletion_DemoName )
CONSOLE_COMMAND_SHIP( aviDemo, "writes AVIs for a demo", idCmdSystem::ArgCompletion_DemoName )
{
commonLocal.AVIRenderDemo( va( "demos/%s", args.Argv( 1 ) ) );
}
@ -645,7 +670,7 @@ CONSOLE_COMMAND( aviDemo, "writes AVIs for a demo", idCmdSystem::ArgCompletion_D
Common_AVIGame_f
================
*/
CONSOLE_COMMAND( aviGame, "writes AVIs for the current game", NULL )
CONSOLE_COMMAND_SHIP( aviGame, "writes AVIs for the current game", NULL )
{
commonLocal.AVIGame( args.Argv( 1 ) );
}

View file

@ -547,6 +547,7 @@ private:
timeDemo_t timeDemo;
int timeDemoStartTime;
int numDemoFrames; // for timeDemo and demoShot
int numShotFrames; // SRS - for demoShot playback timeout
int demoTimeOffset;
renderView_t currentDemoRenderView;

View file

@ -195,7 +195,7 @@ gameReturn_t idGameThread::RunGameAndDraw( int numGameFrames_, idUserCmdMgr& use
// start the thread going
// foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example)
if( com_smp.GetBool() == false || com_editors != 0 )
if( com_smp.GetInteger() <= 0 || com_editors != 0 )
{
// run it in the main thread so PIX profiling catches everything
Run();
@ -347,7 +347,8 @@ void idCommonLocal::Draw()
}
else if( readDemo )
{
AdvanceRenderDemo( true );
// SRS - Advance demo inside Frame() instead of Draw() to support smp mode playback
// AdvanceRenderDemo( true );
renderWorld->RenderScene( &currentDemoRenderView );
renderSystem->DrawDemoPics();
}
@ -563,7 +564,8 @@ void idCommonLocal::Frame()
// RB end, DG end
{
// RB: don't release the mouse when opening a PDA or menu
if( console->Active() || ImGuiTools::ReleaseMouseForTools() )
// SRS - don't release when console open in a game (otherwise may be out of frame on return) but always release at main menu
if( ( console->Active() && !game ) || !mapSpawned || ImGuiTools::ReleaseMouseForTools() )
{
Sys_GrabMouseCursor( false );
}
@ -679,7 +681,8 @@ void idCommonLocal::Frame()
// don't run any frames when paused
// jpcy: the game is paused when playing a demo, but playDemo should wait like the game does
if( pauseGame && !( readDemo && !timeDemo ) )
// SRS - don't wait if window not in focus and playDemo itself paused
if( pauseGame && ( !( readDemo && !timeDemo ) || session->IsSystemUIShowing() || com_pause.GetInteger() ) )
{
gameFrame++;
gameTimeResidual = 0;
@ -766,6 +769,11 @@ void idCommonLocal::Frame()
ExecuteMapChange();
mapSpawnData.savegameFile = NULL;
mapSpawnData.persistentPlayerInfo.Clear();
// SRS - If in Doom 3 mode (com_smp = -1) on map change, must obey fence before returning to avoid command buffer sync issues
if( com_smp.GetInteger() < 0 )
{
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend );
}
return;
}
else if( session->GetState() != idSession::INGAME && mapSpawned )
@ -788,7 +796,19 @@ void idCommonLocal::Frame()
// send frame and mouse events to active guis
GuiFrameEvents();
// SRS - Advance demos inside Frame() vs. Draw() to support smp mode playback
// SRS - Pause playDemo (but not timeDemo) when window not in focus
if ( readDemo && ( !( session->IsSystemUIShowing() || com_pause.GetInteger() ) || timeDemo ) )
{
AdvanceRenderDemo( true );
if( !readDemo )
{
// SRS - Important to return after demo playback is finished to avoid command buffer sync issues
return;
}
}
//--------------------------------------------
// Prepare usercmds and kick off the game processing
// in a background thread
@ -839,7 +859,8 @@ void idCommonLocal::Frame()
// RB begin
#if defined(USE_DOOMCLASSIC)
// If we're in Doom or Doom 2, run tics and upload the new texture.
if( ( GetCurrentGame() == DOOM_CLASSIC || GetCurrentGame() == DOOM2_CLASSIC ) && !( Dialog().IsDialogPausing() || session->IsSystemUIShowing() ) )
// SRS - Add check for com_pause cvar to make sure window is in focus - if not classic game should be paused (FIXME: but classic music still plays in background)
if( ( GetCurrentGame() == DOOM_CLASSIC || GetCurrentGame() == DOOM2_CLASSIC ) && !( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || com_pause.GetInteger() ) )
{
RunDoomClassicFrame();
}
@ -850,12 +871,7 @@ void idCommonLocal::Frame()
gameReturn_t ret = gameThread.RunGameAndDraw( numGameFrames, userCmdMgr, IsClient(), gameFrame - numGameFrames );
// foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example)
if( com_smp.GetInteger() < 0 )
{
// RB: this is the same as Doom 3 renderSystem->EndFrame()
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend );
}
else if( com_smp.GetInteger() == 0 || com_editors != 0 )
if( com_smp.GetInteger() == 0 || com_editors != 0 )
{
// in non-smp mode, run the commands we just generated, instead of
// frame-delayed ones from a background thread
@ -875,6 +891,13 @@ void idCommonLocal::Frame()
}
frameTiming.finishRenderTime = Sys_Microseconds();
// SRS - If in Doom 3 mode (com_smp = -1), must sync after RenderCommandBuffers() otherwise get artifacts due to improper command buffer swap timing
if( com_smp.GetInteger() < 0 )
{
// RB: this is the same as Doom 3 renderSystem->EndFrame()
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend );
}
// make sure the game / draw thread has completed
// This may block if the game is taking longer than the render back end
gameThread.WaitForThread();
@ -888,7 +911,8 @@ void idCommonLocal::Frame()
SendSnapshots();
// Render the sound system using the latest commands from the game thread
if( pauseGame )
// SRS - Enable sound during normal playDemo playback but not during timeDemo
if( pauseGame && !( readDemo && !timeDemo ) )
{
soundWorld->Pause();
soundSystem->SetPlayingSoundWorld( menuSoundWorld );
@ -898,6 +922,10 @@ void idCommonLocal::Frame()
soundWorld->UnPause();
soundSystem->SetPlayingSoundWorld( soundWorld );
}
// SRS - Play silence when dialog waiting or window not in focus
if ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || com_pause.GetInteger() )
soundSystem->SetPlayingSoundWorld( NULL );
soundSystem->Render();
// process the game return for map changes, etc

View file

@ -72,7 +72,8 @@ ID_INLINE void* operator new( size_t s )
return Mem_Alloc( s, TAG_NEW );
}
ID_INLINE void operator delete( void* p )
// SRS - Added noexcept to silence build-time warning
ID_INLINE void operator delete( void* p ) noexcept
{
Mem_Free( p );
}
@ -81,7 +82,8 @@ ID_INLINE void* operator new[]( size_t s )
return Mem_Alloc( s, TAG_NEW );
}
ID_INLINE void operator delete[]( void* p )
// SRS - Added noexcept to silence build-time warning
ID_INLINE void operator delete[]( void* p ) noexcept
{
Mem_Free( p );
}
@ -352,7 +354,7 @@ ID_INLINE _type_* idBlockAlloc<_type_, _blockSize_, memTag>::Alloc()
_type_ * t = ( _type_* ) element->buffer;
if( clearAllocs )
{
memset( t, 0, sizeof( _type_ ) );
memset( (void*)t, 0, sizeof( _type_ ) ); // SRS - Added (void*) cast to silence build-time warning
}
new( t ) _type_;
return t;

View file

@ -197,6 +197,8 @@ void idLib::FatalError( const char* fmt, ... )
va_end( argptr );
common->FatalError( "%s", text );
exit(EXIT_FAILURE); // SRS - Added exit to silence build warning since FatalError has attribute noreturn
}
/*
@ -214,6 +216,8 @@ void idLib::Error( const char* fmt, ... )
va_end( argptr );
common->Error( "%s", text );
exit(EXIT_FAILURE); // SRS - Added exit to silence build warning since Error has attribute noreturn
}
/*

View file

@ -150,8 +150,9 @@ Note: The data is merely moved around the list, so any pointers to data within t
template< class type, int size >
ID_INLINE void idStaticList<type, size>::Sort( const idSort<type>& sort )
{
if( list == NULL )
{
/* if( list == NULL ) */
if( Num() <= 0 ) // SRS - Instead of checking this->list for NULL, check this->Num() for empty list
{
return;
}
sort.Sort( Ptr(), Num() );

View file

@ -181,14 +181,20 @@ ID_INLINE void idStrPool::FreeString( const idPoolStr* poolStr )
* we're shutting down (at this point) just get rid of the following assertion:
* assert( poolStr->numUsers >= 1 );
*/
if( poolStr->numUsers < 1 )
{
return;
}
//if( poolStr->numUsers < 1 ) // SRS - This test does not work if idStrPool is empty and poolStr->numUsers is undefined
//{
// return;
//}
// DG end
if( pool.Num() <= 0 ) // SRS - Instead, check for empty idStrPool and return to prevent segfaulting on shutdown
{
return;
}
assert( poolStr->pool == this );
assert( poolStr->numUsers >= 1 ); // SRS - Reestablish assertion
poolStr->numUsers--;
if( poolStr->numUsers <= 0 )
{

View file

@ -93,7 +93,9 @@ public:
}
cpuid_t cpuid;
virtual ~idSIMDProcessor() {} // SRS - Added virtual destructor
virtual const char* VPCALL GetName() const = 0;
virtual void VPCALL MinMax( float& min, float& max, const float* src, const int count ) = 0;

View file

@ -87,7 +87,12 @@ const int MAX_EXPRESSION_REGISTERS = 4096;
// everything that is needed by the backend needs
// to be double buffered to allow it to run in
// parallel on a dual cpu machine
const uint32 NUM_FRAME_DATA = 2;
#if defined(__APPLE__) && defined(USE_VULKAN)
// SRS - macOS MoltenVK/Metal needs triple buffering for full screen to work properly
const uint32 NUM_FRAME_DATA = 3;
#else
const uint32 NUM_FRAME_DATA = 2;
#endif
#if defined(USE_VULKAN)
#include "../renderer/Vulkan/qvk.h"

View file

@ -165,8 +165,11 @@ ID_INLINE void WriteIndexPair( triIndex_t* dest, const triIndex_t a, const triIn
#else
#ifdef _MSVC
#define NODEFAULT default: __assume( 0 )
#else // not _MSVC
#elif defined(__GNUC__)
// TODO: is that __assume an important optimization? if so, is there a gcc equivalent?
// SRS - The gcc equivalent is __builtin_unreachable()
#define NODEFAULT default: __builtin_unreachable()
#else // not _MSVC and not __GNUC__
#define NODEFAULT
#endif
#endif

View file

@ -8,7 +8,10 @@
/* #define const */
#define CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
// SRS - don't redefine HAVE_STDLIB_H if already defined
#ifndef HAVE_STDLIB_H
#define HAVE_STDLIB_H
#endif
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */

View file

@ -369,8 +369,8 @@ jpeg_has_multiple_scans( j_decompress_ptr cinfo ) {
GLOBAL boolean
jpeg_finish_decompress( j_decompress_ptr cinfo ) {
if ( ( ( cinfo->global_state == DSTATE_SCANNING ) ||
( cinfo->global_state == DSTATE_RAW_OK ) && !cinfo->buffered_image ) ) {
if ( ( cinfo->global_state == DSTATE_SCANNING ) ||
( ( cinfo->global_state == DSTATE_RAW_OK ) && !cinfo->buffered_image ) ) { // SRS - Relocated parentheses to surround && expression
/* Terminate final pass of non-buffered mode */
if ( cinfo->output_scanline < cinfo->output_height ) {
ERREXIT( cinfo, JERR_TOO_LITTLE_DATA );

View file

@ -381,11 +381,12 @@ static const int extend_test[16] = /* entry n is 2**(n-1) */
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
{ 0, ( ( -1 ) << 1 ) + 1, ( ( -1 ) << 2 ) + 1, ( ( -1 ) << 3 ) + 1, ( ( -1 ) << 4 ) + 1,
( ( -1 ) << 5 ) + 1, ( ( -1 ) << 6 ) + 1, ( ( -1 ) << 7 ) + 1, ( ( -1 ) << 8 ) + 1,
( ( -1 ) << 9 ) + 1, ( ( -1 ) << 10 ) + 1, ( ( -1 ) << 11 ) + 1, ( ( -1 ) << 12 ) + 1,
( ( -1 ) << 13 ) + 1, ( ( -1 ) << 14 ) + 1, ( ( -1 ) << 15 ) + 1 };
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ // SRS - Cast to unsigned int
{ 0, static_cast<int>(( (unsigned int)( -1 ) << 1 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 2 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 3 ) + 1),
static_cast<int>(( (unsigned int)( -1 ) << 4 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 5 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 6 ) + 1),
static_cast<int>(( (unsigned int)( -1 ) << 7 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 8 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 9 ) + 1),
static_cast<int>(( (unsigned int)( -1 ) << 10 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 11 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 12 ) + 1),
static_cast<int>(( (unsigned int)( -1 ) << 13 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 14 ) + 1), static_cast<int>(( (unsigned int)( -1 ) << 15 ) + 1) };
#endif /* AVOID_TABLES */

View file

@ -33,6 +33,8 @@
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
# include <io.h>
#elif defined(__GNUC__)
# include <unistd.h> // SRS - For explicit declaration of lseek, read, write, close
#endif
#ifdef NO_DEFLATE /* for compatibility with old definition */

View file

@ -1488,7 +1488,7 @@ z_streamp strm;
{
struct inflate_state FAR *state;
if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
if (strm == Z_NULL || strm->state == Z_NULL) return (unsigned long)(-1L) << 16; // SRS - Cast to unsigned long
state = (struct inflate_state FAR *)strm->state;
return ((long)(state->back) << 16) +
(state->mode == COPY ? state->length :

View file

@ -896,16 +896,64 @@ bool idBinaryImage::LoadFromGeneratedFile( idFile* bFile, ID_TIME_T sourceTimeSt
// sizes are still retained, so the stored data size may be larger than
// just the multiplication of dimensions
assert( img.dataSize >= img.width * img.height * BitsForFormat( ( textureFormat_t )fileData.format ) / 8 );
img.Alloc( img.dataSize );
#if defined(__APPLE__) && defined(USE_VULKAN)
int imgfile_dataSize = img.dataSize;
// SRS - Allocate 2x memory to prepare for in-place conversion from FMT_RGB565 to FMT_RGBA8
if( ( textureFormat_t )fileData.format == FMT_RGB565 )
{
img.Alloc( img.dataSize * 2 );
}
else
{
img.Alloc( img.dataSize );
}
if( img.data == NULL )
{
return false;
}
if( bFile->Read( img.data, img.dataSize ) <= 0 )
// SRS - Read image data using actual on-disk data size
if( bFile->Read( img.data, imgfile_dataSize ) <= 0 )
{
return false;
}
// SRS - Convert FMT_RGB565 16-bits to FMT_RGBA8 32-bits in place using pre-allocated space
if( ( textureFormat_t )fileData.format == FMT_RGB565 )
{
//SRS - Make sure we have an integer number of RGBA8 storage slots
assert( img.dataSize % 4 == 0 );
for( int pixelIndex = img.dataSize/2 - 2; pixelIndex >= 0; pixelIndex -= 2 )
{
#if 1
// SRS - Option 1: Scale and shift algorithm
uint16 pixelValue_rgb565 = img.data[pixelIndex + 0] << 8 | img.data[pixelIndex + 1];
img.data[pixelIndex*2 + 0] = ( ( ( pixelValue_rgb565 ) >> 11 ) * 527 + 23 ) >> 6;
img.data[pixelIndex*2 + 1] = ( ( ( pixelValue_rgb565 & 0x07E0 ) >> 5 ) * 259 + 33 ) >> 6;
img.data[pixelIndex*2 + 2] = ( ( ( pixelValue_rgb565 & 0x001F ) ) * 527 + 23 ) >> 6;
#else
// SRS - Option 2: Shift and combine algorithm - is this faster?
uint8 pixelValue_rgb565_hi = img.data[pixelIndex + 0];
uint8 pixelValue_rgb565_lo = img.data[pixelIndex + 1];
img.data[pixelIndex*2 + 0] = ( pixelValue_rgb565_hi & 0xF8 ) | ( pixelValue_rgb565_hi >> 5 );
img.data[pixelIndex*2 + 1] = ( pixelValue_rgb565_hi << 5 ) | ( ( pixelValue_rgb565_lo & 0xE0 ) >> 3 ) | ( ( pixelValue_rgb565_hi & 0x07 ) >> 1 );
img.data[pixelIndex*2 + 2] = ( pixelValue_rgb565_lo << 3 ) | ( ( pixelValue_rgb565_lo & 0x1F ) >> 2 );
#endif
img.data[pixelIndex*2 + 3] = 0xFF;
}
}
#else
img.Alloc( img.dataSize );
if( img.data == NULL )
{
return false;
}
if( bFile->Read( img.data, img.dataSize ) <= 0 )
{
return false;
}
#endif
}
return true;

View file

@ -455,6 +455,9 @@ private:
#if defined( USE_VULKAN )
void CreateSampler();
// SRS - added method to set image layout
void SetImageLayout( VkImage image, VkImageSubresourceRange subresourceRange, VkImageLayout oldImageLayout, VkImageLayout newImageLayout );
// SRS End
bool bIsSwapChainImage;
VkFormat internalFormat;

View file

@ -399,7 +399,12 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
if( ( fileSystem->InProductionMode() && binaryFileTime != FILE_NOT_FOUND_TIMESTAMP ) || ( ( binaryFileTime != FILE_NOT_FOUND_TIMESTAMP )
&& ( header.colorFormat == opts.colorFormat )
#if defined(__APPLE__) && defined(USE_VULKAN)
// SRS - Handle case when image read is cached and RGB565 format conversion is already done
&& ( header.format == opts.format || ( header.format == FMT_RGB565 && opts.format == FMT_RGBA8 ) )
#else
&& ( header.format == opts.format )
#endif
&& ( header.textureType == opts.textureType )
) )
{
@ -407,7 +412,17 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
opts.height = header.height;
opts.numLevels = header.numLevels;
opts.colorFormat = ( textureColor_t )header.colorFormat;
opts.format = ( textureFormat_t )header.format;
#if defined(__APPLE__) && defined(USE_VULKAN)
// SRS - Set in-memory format to FMT_RGBA8 for converted FMT_RGB565 image
if( header.format == FMT_RGB565 )
{
opts.format = FMT_RGBA8;
}
else
#endif
{
opts.format = ( textureFormat_t )header.format;
}
opts.textureType = ( textureType_t )header.textureType;
if( cvarSystem->GetCVarBool( "fs_buildresources" ) )
{
@ -791,6 +806,28 @@ void idImage::GenerateImage( const byte* pic, int width, int height, textureFilt
if( pic == NULL || opts.textureType == TT_2D_MULTISAMPLE )
{
AllocImage();
#if defined(USE_VULKAN)
// SRS - update layout of Ambient Occlusion image otherwise get Vulkan validation layer errors with SSAO enabled
if( imgName == "_ao0" || imgName == "_ao1" )
{
VkImageSubresourceRange subresourceRange;
if( internalFormat == VK_FORMAT_D32_SFLOAT_S8_UINT || opts.format == FMT_DEPTH )
{
subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
}
else
{
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = opts.numLevels;
subresourceRange.baseArrayLayer = 0;
subresourceRange.layerCount = 1;
SetImageLayout( image, subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, layout );
}
#endif
}
else
{

View file

@ -551,13 +551,13 @@ void idImage::SetTexParameters()
}
// RB: disabled use of unreliable extension that can make the game look worse
/*
// SRS - Try with feature turned back on using r_lodBias CVAR vs. hardcoded value
if( glConfig.textureLODBiasAvailable && ( usage != TD_FONT ) )
{
// use a blurring LOD bias in combination with high anisotropy to fix our aliasing grate textures...
glTexParameterf( target, GL_TEXTURE_LOD_BIAS_EXT, 0.5 ); //r_lodBias.GetFloat() );
glTexParameterf( target, GL_TEXTURE_LOD_BIAS_EXT, /*0.5*/ r_lodBias.GetFloat() );
}
*/
// RB end
// set the wrap/clamp modes

View file

@ -31,6 +31,19 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
// SRS - Include SDL headers to enable vsync changes without restart for UNIX-like OSs
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
// SRS - Don't seem to need these #undefs (at least on macOS), are they needed for Linux, etc?
// DG: SDL.h somehow needs the following functions, so #undef those silly
// "don't use" #defines from Str.h
//#undef strncmp
//#undef strcasecmp
//#undef vsnprintf
// DG end
#include <SDL.h>
#endif
// SRS end
#include "../RenderCommon.h"
#include "../RenderBackend.h"
#include "../../framework/Common_local.h"
@ -339,10 +352,13 @@ static void R_CheckPortableExtensions()
// GL_ARB_occlusion_query
glConfig.occlusionQueryAvailable = GLEW_ARB_occlusion_query != 0;
// GL_ARB_timer_query using the DSA interface
//glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
#if defined(__APPLE__)
// SRS - DSA not available in Apple OpenGL 4.1, but enable for OSX anyways since elapsed time query will be used to get timing info instead
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
#else
// GL_ARB_timer_query using the DSA interface
glConfig.timerQueryAvailable = ( GLEW_ARB_direct_state_access != 0 && GLEW_ARB_timer_query != 0 );
#endif
// GREMEDY_string_marker
glConfig.gremedyStringMarkerAvailable = GLEW_GREMEDY_string_marker != 0;
@ -1534,6 +1550,23 @@ void idRenderBackend::CheckCVars()
}
}
// SRS - Enable SDL-driven vync changes without restart for UNIX-like OSs
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
extern idCVar r_swapInterval;
if( r_swapInterval.IsModified() )
{
r_swapInterval.ClearModified();
#if SDL_VERSION_ATLEAST(2, 0, 0)
if( SDL_GL_SetSwapInterval( r_swapInterval.GetInteger() ) < 0 )
common->Warning( "Vsync changes not supported without restart" );
#else
if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval.GetInteger() ) < 0 )
common->Warning( "Vsync changes not supported without restart" );
#endif
}
#endif
// SRS end
if( r_antiAliasing.IsModified() )
{
switch( r_antiAliasing.GetInteger() )

View file

@ -785,7 +785,7 @@ void idRenderBackend::DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs )
if( r_showTris.GetInteger() == 3 )
{
GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_TWOSIDED );
GL_State( (glStateBits & ~( GLS_CULL_MASK )) | GLS_CULL_TWOSIDED ); // SRS - Added parens to silence build warnings
}
GL_Color( color );
@ -794,7 +794,7 @@ void idRenderBackend::DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs )
if( r_showTris.GetInteger() == 3 )
{
GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_FRONTSIDED );
GL_State( (glStateBits & ~( GLS_CULL_MASK )) | GLS_CULL_FRONTSIDED ); // SRS - Added parens to silence build warnings
}
}

View file

@ -128,8 +128,14 @@ void idRenderProgManager::LoadShader( shader_t& shader )
default:
{
outFileGLSL.Format( "renderprogs/glsl-4_50/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
outFileUniforms.Format( "renderprogs/glsl-4_50/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
//SRS - OSX supports only up to GLSL 4.1
#if defined(__APPLE__)
outFileGLSL.Format( "renderprogs/glsl-4_10/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
outFileUniforms.Format( "renderprogs/glsl-4_10/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
#else
outFileGLSL.Format( "renderprogs/glsl-4_50/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
outFileUniforms.Format( "renderprogs/glsl-4_50/%s%s", shader.name.c_str(), shader.nameOutSuffix.c_str() );
#endif
}
}

View file

@ -2050,7 +2050,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
case SL_SPECULAR:
{
// ignore stage that fails the condition
if( !surfaceRegs[ surfaceStage->conditionRegister ] )
if( !surfaceRegs[ surfaceStage->conditionRegister ] || vLight->lightDef->parms.noSpecular ) // SRS - From RB forums
{
break;
}

View file

@ -113,7 +113,8 @@ void RB_SetVertexColorParms( stageVertexColor_t svc );
#if defined( USE_VULKAN )
#if defined(__linux__)
//SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
#include <SDL.h>
#include <SDL_vulkan.h>
#endif
@ -133,7 +134,8 @@ struct gpuInfo_t
struct vulkanContext_t
{
// Eric: If on linux, use this to pass SDL_Window pointer to the SDL_Vulkan_* methods not in sdl_vkimp.cpp file.
#if defined(__linux__)
// SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
SDL_Window* sdlWindow = nullptr;
#endif
uint64 frameCounter;

View file

@ -978,6 +978,9 @@ extern idCVar r_windowHeight;
extern idCVar r_debugContext; // enable various levels of context debug
extern idCVar r_glDriver; // "opengl32", etc
// SRS - Added cvar to control workarounds for AMD OSX driver bugs when shadow mapping enabled
extern idCVar r_skipAMDWorkarounds; // skip work arounds for AMD driver bugs
// SRS end
extern idCVar r_skipIntelWorkarounds; // skip work arounds for Intel driver bugs
extern idCVar r_vidMode; // video mode number
extern idCVar r_displayRefresh; // optional display refresh rate option for vid mode
@ -1241,7 +1244,8 @@ struct glimpParms_t
};
// Eric: If on Linux using Vulkan use the sdl_vkimp.cpp methods
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
#include <vector>
#define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))

View file

@ -617,17 +617,31 @@ void idRenderLog::OpenMainBlock( renderLogMainBlock_t block )
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 0 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, queryPool, queryIndex );
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
#elif defined(__APPLE__)
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( glConfig.timerQueryAvailable && ( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() ) )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] == 0 )
{
glGenQueries( 1, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
glBeginQuery( GL_TIME_ELAPSED_EXT, glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
#else
if( glConfig.timerQueryAvailable )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ block * 2 ] == 0 )
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 ] == 0 )
{
glCreateQueries( GL_TIMESTAMP, 2, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ block * 2 ] );
glCreateQueries( GL_TIMESTAMP, 2, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 ] );
}
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ block * 2 + 0 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ block * 2 + 0 ]++;
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 0 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 0 ]++;
}
#endif
}
@ -651,7 +665,17 @@ void idRenderLog::CloseMainBlock()
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, queryIndex );
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
#elif defined(__APPLE__)
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( glConfig.timerQueryAvailable && ( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() ) )
{
glEndQuery( GL_TIME_ELAPSED_EXT );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
}
#else
if( glConfig.timerQueryAvailable )

View file

@ -771,7 +771,12 @@ struct typeConversion_t
const char* vertexInsert =
{
// SRS - OSX OpenGL only supports up to GLSL 4.1, but current RenderProgs shaders seem to work as-is on OSX OpenGL drivers
#if defined(__APPLE__) && !defined(USE_VULKAN)
"#version 410\n"
#else
"#version 450\n"
#endif
"#pragma shader_stage( vertex )\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
//"#define PC\n"
@ -786,7 +791,12 @@ const char* vertexInsert =
const char* fragmentInsert =
{
"#version 450\n"
// SRS - OSX OpenGL only supports up to GLSL 4.1, but current RenderProgs shaders seem to work as-is on OSX OpenGL drivers
#if defined(__APPLE__) && !defined(USE_VULKAN)
"#version 410\n"
#else
"#version 450\n"
#endif
"#pragma shader_stage( fragment )\n"
"#extension GL_ARB_separate_shader_objects : enable\n"
//"#define PC\n"
@ -1502,7 +1512,7 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, rp
idStr filenameHint = "// filename " + idStr( name ) + "\n";
// RB: changed to allow multiple versions of GLSL
if( ( stage == SHADER_STAGE_VERTEX ) )
if( stage == SHADER_STAGE_VERTEX ) // SRS - Remove extra parens
{
switch( glConfig.driverType )
{
@ -1551,7 +1561,7 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, rp
if( vkGLSL )
{
out += "\n";
if( ( stage == SHADER_STAGE_VERTEX ) )
if( stage == SHADER_STAGE_VERTEX ) // SRS - Remove extra parens
{
out += "layout( binding = 0 ) uniform UBOV {\n";
}

View file

@ -130,7 +130,8 @@ void idRenderSystemLocal::RenderCommandBuffers( const emptyCommand_t* const cmdH
// draw 2D graphics
if( !r_skipBackEnd.GetBool() )
{
#if !defined(USE_VULKAN)
// SRS - For OSX skip total rendering time query due to missing GL_TIMESTAMP support in Apple OpenGL 4.1, will calculate it inside SwapCommandBuffers_FinishRendering instead
#if !defined(USE_VULKAN) && !defined(__APPLE__)
if( glConfig.timerQueryAvailable )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ MRB_GPU_TIME ] == 0 )
@ -741,6 +742,16 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering(
backend.pc.gpuPostProcessingMicroSec = ( gpuEndNanoseconds - gpuStartNanoseconds ) / 1000;
}
// SRS - For OSX OpenGL calculate total rendering time vs direct measurement due to missing GL_TIMESTAMP support in Apple OpenGL 4.1
#if defined(__APPLE__)
backend.pc.gpuMicroSec = backend.pc.gpuDepthMicroSec + backend.pc.gpuScreenSpaceAmbientOcclusionMicroSec + backend.pc.gpuAmbientPassMicroSec + backend.pc.gpuInteractionsMicroSec + backend.pc.gpuShaderPassMicroSec + backend.pc.gpuPostProcessingMicroSec + commonLocal.GetRendererIdleMicroseconds();
if( gpuMicroSec != NULL )
{
*gpuMicroSec = backend.pc.gpuMicroSec;
}
#endif
for( int i = 0; i < MRB_TOTAL_QUERIES; i++ )
{

View file

@ -56,7 +56,15 @@ glconfig_t glConfig;
idCVar r_requestStereoPixelFormat( "r_requestStereoPixelFormat", "1", CVAR_RENDERER, "Ask for a stereo GL pixel format on startup" );
idCVar r_debugContext( "r_debugContext", "0", CVAR_RENDERER, "Enable various levels of context debug." );
idCVar r_glDriver( "r_glDriver", "", CVAR_RENDERER, "\"opengl32\", etc." );
// SRS - Added workaround for AMD OSX driver bugs caused by GL_EXT_timer_query when shadow mapping enabled; Intel bugs not present on OSX
#if defined(__APPLE__)
idCVar r_skipIntelWorkarounds( "r_skipIntelWorkarounds", "1", CVAR_RENDERER | CVAR_BOOL, "skip workarounds for Intel driver bugs" );
idCVar r_skipAMDWorkarounds( "r_skipAMDWorkarounds", "0", CVAR_RENDERER | CVAR_BOOL, "skip workarounds for AMD driver bugs" );
#else
idCVar r_skipIntelWorkarounds( "r_skipIntelWorkarounds", "0", CVAR_RENDERER | CVAR_BOOL, "skip workarounds for Intel driver bugs" );
idCVar r_skipAMDWorkarounds( "r_skipAMDWorkarounds", "1", CVAR_RENDERER | CVAR_BOOL, "skip workarounds for AMD driver bugs" );
#endif
// SRS end
// RB: disabled 16x MSAA
idCVar r_antiAliasing( "r_antiAliasing", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, " 0 = None\n 1 = SMAA 1x\n 2 = MSAA 2x\n 3 = MSAA 4x\n 4 = MSAA 8x\n", 0, ANTI_ALIASING_MSAA_8X );
// RB end
@ -90,7 +98,8 @@ idCVar r_useSRGB( "r_useSRGB", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE,
idCVar r_maxAnisotropicFiltering( "r_maxAnisotropicFiltering", "8", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "limit aniso filtering" );
idCVar r_useTrilinearFiltering( "r_useTrilinearFiltering", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "Extra quality filtering" );
// RB: not used anymore
idCVar r_lodBias( "r_lodBias", "0.5", CVAR_RENDERER | CVAR_ARCHIVE, "UNUSED: image lod bias" );
// SRS - Reenabled LODBIAS
idCVar r_lodBias( "r_lodBias", "0.5", CVAR_RENDERER | CVAR_ARCHIVE, /*"UNUSED: */"image lod bias" );
// RB end
idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" );
@ -428,7 +437,8 @@ void R_SetNewMode( const bool fullInit )
if( fullInit )
{
// create the context as well as setting up the window
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
if( VKimp_Init( parms ) )
#else
if( GLimp_Init( parms ) )
@ -445,7 +455,8 @@ void R_SetNewMode( const bool fullInit )
else
{
// just rebuild the window
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
if( VKimp_SetScreenParms( parms ) )
#else
if( GLimp_SetScreenParms( parms ) )
@ -1399,7 +1410,8 @@ void R_SetColorMappings()
int inf = idMath::Ftoi( 0xffff * pow( j / 255.0f, invg ) + 0.5f );
tr.gammaTable[i] = idMath::ClampInt( 0, 0xFFFF, inf );
}
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
VKimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable );
#else
GLimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable );
@ -2105,6 +2117,9 @@ void idRenderSystemLocal::Shutdown()
R_ShutdownFrameData();
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();
// free the vertex cache, which should have nothing allocated now
vertexCache.Shutdown();

View file

@ -156,6 +156,11 @@ void idVertexCache::Shutdown()
frameData[i].indexBuffer.FreeBufferObject();
frameData[i].jointBuffer.FreeBufferObject();
}
// SRS - free static buffers to avoid Vulkan validation layer errors on shutdown
staticData.vertexBuffer.FreeBufferObject();
staticData.indexBuffer.FreeBufferObject();
staticData.jointBuffer.FreeBufferObject();
}
/*

View file

@ -167,7 +167,8 @@ idVulkanBlock::Init
*/
bool idVulkanBlock::Init()
{
if( memoryTypeIndex == UINT64_MAX )
//SRS - Changed UINT64_MAX to UINT32_MAX for type consistency, otherwise test is always false
if( memoryTypeIndex == UINT32_MAX )
{
return false;
}
@ -495,8 +496,9 @@ void idVulkanBlock::Print()
idLib::Printf( "Type Index: %u\n", memoryTypeIndex );
idLib::Printf( "Usage: %s\n", memoryUsageStrings[ usage ] );
idLib::Printf( "Count: %d\n", count );
idLib::Printf( "Size: %lu\n", size );
idLib::Printf( "Allocated: %lu\n", allocated );
//SRS - Changed %lu to %llu
idLib::Printf( "Size: %llu\n", size );
idLib::Printf( "Allocated: %llu\n", allocated );
idLib::Printf( "Next Block: %u\n", nextBlockId );
idLib::Printf( "------------------------\n" );
@ -505,8 +507,9 @@ void idVulkanBlock::Print()
idLib::Printf( "{\n" );
idLib::Printf( "\tId: %u\n", current->id );
idLib::Printf( "\tSize: %lu\n", current->size );
idLib::Printf( "\tOffset: %lu\n", current->offset );
//SRS - Changed %lu to %llu
idLib::Printf( "\tSize: %llu\n", current->size );
idLib::Printf( "\tOffset: %llu\n", current->offset );
idLib::Printf( "\tType: %s\n", allocationTypeStrings[ current->type ] );
idLib::Printf( "}\n" );
@ -679,7 +682,8 @@ void idVulkanAllocator::Print()
{
idLib::Printf( "Device Local MB: %d\n", int( deviceLocalMemoryBytes / 1024 * 1024 ) );
idLib::Printf( "Host Visible MB: %d\n", int( hostVisibleMemoryBytes / 1024 * 1024 ) );
idLib::Printf( "Buffer Granularity: %lu\n", bufferImageGranularity );
//SRS - Changed %lu to %llu
idLib::Printf( "Buffer Granularity: %llu\n", bufferImageGranularity );
idLib::Printf( "\n" );
for( int i = 0; i < VK_MAX_MEMORY_TYPES; ++i )
@ -702,7 +706,8 @@ CONSOLE_COMMAND( Vulkan_PrintHeapInfo, "Print out the heap information for this
for( uint32 i = 0; i < props.memoryHeapCount; ++i )
{
VkMemoryHeap heap = props.memoryHeaps[ i ];
idLib::Printf( "id=%d, size=%lu, flags=", i, heap.size );
//SRS - Changed %lu to %llu
idLib::Printf( "id=%d, size=%llu, flags=", i, heap.size );
if( heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT )
{
idLib::Printf( "DEVICE_LOCAL" );

View file

@ -105,8 +105,14 @@ bool idVertexBuffer::AllocBufferObject( const void* data, int allocSize, bufferU
}
else if( usage == BU_DYNAMIC )
{
// SRS - needed to ensure host coherency for MoltenVK on OSX < 10.15.6, otherwise black screen
#if defined(__APPLE__)
vmaReq.usage = VMA_MEMORY_USAGE_UNKNOWN;
vmaReq.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
#else
vmaReq.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
vmaReq.flags = VMA_MEMORY_REQUIREMENT_PERSISTENT_MAP_BIT;
#endif
vmaReq.flags = VMA_MEMORY_REQUIREMENT_PERSISTENT_MAP_BIT;
}
ID_VK_CHECK( vmaCreateBuffer( vmaAllocator, &bufferCreateInfo, &vmaReq, &apiObject, &vmaAllocation, &allocation ) );
@ -357,7 +363,13 @@ bool idIndexBuffer::AllocBufferObject( const void* data, int allocSize, bufferUs
}
else if( usage == BU_DYNAMIC )
{
vmaReq.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
// SRS - needed to ensure host coherency for MoltenVK on OSX < 10.15.6, otherwise black screen
#if defined(__APPLE__)
vmaReq.usage = VMA_MEMORY_USAGE_UNKNOWN;
vmaReq.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
#else
vmaReq.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
#endif
vmaReq.flags = VMA_MEMORY_REQUIREMENT_PERSISTENT_MAP_BIT;
}
@ -610,8 +622,14 @@ bool idUniformBuffer::AllocBufferObject( const void* data, int allocSize, buffer
}
else if( usage == BU_DYNAMIC )
{
vmaReq.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
vmaReq.flags = VMA_MEMORY_REQUIREMENT_PERSISTENT_MAP_BIT;
// SRS - needed to ensure host coherency for MoltenVK on OSX < 10.15.6, otherwise black screen
#if defined(__APPLE__)
vmaReq.usage = VMA_MEMORY_USAGE_UNKNOWN;
vmaReq.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
#else
vmaReq.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
#endif
vmaReq.flags = VMA_MEMORY_REQUIREMENT_PERSISTENT_MAP_BIT;
}
ID_VK_CHECK( vmaCreateBuffer( vmaAllocator, &bufferCreateInfo, &vmaReq, &apiObject, &vmaAllocation, &allocation ) );
@ -803,4 +821,4 @@ void idUniformBuffer::ClearWithoutFreeing()
#else
allocation.deviceMemory = VK_NULL_HANDLE;
#endif
}
}

View file

@ -657,13 +657,18 @@ void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int
{
assert( x >= 0 && y >= 0 && mipLevel >= 0 && width >= 0 && height >= 0 && mipLevel < opts.numLevels );
// SRS - Calculate buffer size without changing original width and height dimensions for compressed images
int bufferW = width;
int bufferH = height;
if( IsCompressed() )
{
width = ( width + 3 ) & ~3;
height = ( height + 3 ) & ~3;
bufferW = ( width + 3 ) & ~3;
bufferH = ( height + 3 ) & ~3;
}
int size = width * height * BitsForFormat( opts.format ) / 8;
int size = bufferW * bufferH * BitsForFormat( opts.format ) / 8;
// SRS end
VkBuffer buffer;
VkCommandBuffer commandBuffer;
@ -722,7 +727,7 @@ void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int
VkBufferImageCopy imgCopy = {};
imgCopy.bufferOffset = offset;
imgCopy.bufferRowLength = pixelPitch;
imgCopy.bufferImageHeight = height;
imgCopy.bufferImageHeight = bufferH; // SRS - Use buffer height vs. image height to avoid vulkan errors for compressed images
imgCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imgCopy.imageSubresource.layerCount = 1;
imgCopy.imageSubresource.mipLevel = mipLevel;
@ -730,7 +735,7 @@ void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int
imgCopy.imageOffset.x = x;
imgCopy.imageOffset.y = y;
imgCopy.imageOffset.z = 0;
imgCopy.imageExtent.width = width;
imgCopy.imageExtent.width = width; // SRS - Always use original width and height dimensions, even when image is compressed
imgCopy.imageExtent.height = height;
imgCopy.imageExtent.depth = 1;
@ -760,4 +765,128 @@ void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int
vkCmdPipelineBarrier( commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, NULL, 0, NULL, 1, &barrier );
layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
}
// SRS - added method to set image layout
/*
====================
idImage::SetImageLayout
====================
*/
void idImage::SetImageLayout( VkImage image, VkImageSubresourceRange subresourceRange, VkImageLayout oldImageLayout, VkImageLayout newImageLayout )
{
VkBuffer buffer;
VkCommandBuffer commandBuffer;
int size = 0;
int offset = 0;
byte* data = stagingManager.Stage( size, 16, commandBuffer, buffer, offset );
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
barrier.subresourceRange = subresourceRange;
barrier.oldLayout = oldImageLayout;
barrier.newLayout = newImageLayout;
// Source layouts (old)
// Source access mask controls actions that have to be finished on the old layout before it will be transitioned to the new layout
switch ( oldImageLayout )
{
case VK_IMAGE_LAYOUT_UNDEFINED:
// Image layout is undefined (or does not matter)
// Only valid as initial layout
// No flags required, listed only for completeness
barrier.srcAccessMask = 0;
break;
case VK_IMAGE_LAYOUT_PREINITIALIZED:
// Image is preinitialized
// Only valid as initial layout for linear images, preserves memory contents
// Make sure host writes have been finished
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
// Image is a color attachment
// Make sure any writes to the color buffer have been finished
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
// Image is a depth/stencil attachment
// Make sure any writes to the depth/stencil buffer have been finished
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
// Image is a transfer source
// Make sure any reads from the image have been finished
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
// Image is a transfer destination
// Make sure any writes to the image have been finished
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
// Image is read by a shader
// Make sure any shader reads from the image have been finished
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
// Other source layouts aren't handled (yet)
break;
}
// Target layouts (new)
// Destination access mask controls the dependency for the new image layout
switch ( newImageLayout )
{
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
// Image will be used as a transfer destination
// Make sure any writes to the image have been finished
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
// Image will be used as a transfer source
// Make sure any reads from the image have been finished
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
// Image will be used as a color attachment
// Make sure any writes to the color buffer have been finished
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
// Image layout will be used as a depth/stencil attachment
// Make sure any writes to depth/stencil buffer have been finished
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
// Image will be read in a shader (sampler, input attachment)
// Make sure any writes to the image have been finished
if ( barrier.srcAccessMask == 0 )
{
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
}
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
break;
default:
// Other destination layouts aren't handled (yet)
break;
}
vkCmdPipelineBarrier( commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, NULL, 0, NULL, 1, &barrier );
}
// SRS End

View file

@ -74,6 +74,16 @@ static const char* g_instanceExtensions[ g_numInstanceExtensions ] =
};
#endif
// SRS - needed for MoltenVK portability implementation on OSX
#if defined(__APPLE__)
// required for VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME visibility (as of SDK 1.2.170.0)
#include <vulkan/vulkan_beta.h>
#if defined(USE_MoltenVK)
// optionally needed for runtime access to fullImageViewSwizzle (instead of env var MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE = 1)
#include <MoltenVK/vk_mvk_moltenvk.h>
#endif
#endif
static const int g_numDebugInstanceExtensions = 1;
static const char* g_debugInstanceExtensions[ g_numDebugInstanceExtensions ] =
{
@ -83,7 +93,12 @@ static const char* g_debugInstanceExtensions[ g_numDebugInstanceExtensions ] =
static const int g_numValidationLayers = 1;
static const char* g_validationLayers[ g_numValidationLayers ] =
{
// SRS - use MoltenVK validation layer on macOS when using libMoltenVK in place of libvulkan
#if defined(__APPLE__) && defined(USE_MoltenVK)
"MoltenVK"
#else
"VK_LAYER_KHRONOS_validation"
#endif
};
#define ID_VK_ERROR_STRING( x ) case static_cast< int >( x ): return #x
@ -288,7 +303,8 @@ static void CreateVulkanInstance()
ValidateValidationLayers();
}
#if defined(__linux__)
// SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
auto extensions = get_required_extensions( sdlInstanceExtensions, enableLayers );
createInfo.enabledExtensionCount = static_cast<uint32_t>( extensions.size() );
createInfo.ppEnabledExtensionNames = extensions.data();
@ -442,7 +458,8 @@ static void CreateSurface()
ID_VK_CHECK( vkCreateWaylandSurfaceKHR( info.inst, &createInfo, NULL, &info.surface ) );
#else
#if defined(__linux__)
// SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
if( !SDL_Vulkan_CreateSurface( vkcontext.sdlWindow, vkcontext.instance, &vkcontext.surface ) )
{
idLib::FatalError( "Error while creating Vulkan surface: %s", SDL_GetError() );
@ -506,6 +523,15 @@ static void PopulateDeviceExtensions( const idList< VkExtensionProperties >& ext
{
//idLib::Printf( "Checking Vulkan device extension [%s]\n", extensionProps[ i ].extensionName );
// SRS - needed for MoltenVK portability implementation on OSX
#if defined(__APPLE__)
if( idStr::Icmp( extensionProps[ i ].extensionName, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME ) == 0 )
{
extensions.AddUnique( VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME );
continue;
}
#endif
if( idStr::Icmp( extensionProps[ i ].extensionName, VK_EXT_DEBUG_MARKER_EXTENSION_NAME ) == 0 && enableLayers )
{
extensions.AddUnique( VK_EXT_DEBUG_MARKER_EXTENSION_NAME );
@ -711,6 +737,17 @@ static void CreateLogicalDeviceAndQueues()
devqInfo.Append( qinfo );
}
// SRS - needed for MoltenVK portability implementation on OSX
#if defined(__APPLE__)
VkPhysicalDeviceFeatures2 deviceFeatures2 = {};
VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures = {};
deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
deviceFeatures2.pNext = &portabilityFeatures;
portabilityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR;
vkGetPhysicalDeviceFeatures2( vkcontext.physicalDevice, &deviceFeatures2 );
#else
VkPhysicalDeviceFeatures deviceFeatures = {};
deviceFeatures.textureCompressionBC = VK_TRUE;
deviceFeatures.imageCubeArray = VK_TRUE;
@ -719,12 +756,18 @@ static void CreateLogicalDeviceAndQueues()
deviceFeatures.depthBounds = vkcontext.physicalDeviceFeatures.depthBounds;
deviceFeatures.fillModeNonSolid = VK_TRUE;
deviceFeatures.samplerAnisotropy = vkcontext.physicalDeviceFeatures.samplerAnisotropy; // RB
#endif
VkDeviceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
// SRS - needed for MoltenVK portability implementation on OSX
#if defined(__APPLE__)
info.pNext = &deviceFeatures2;
#else
info.pEnabledFeatures = &deviceFeatures;
#endif
info.queueCreateInfoCount = devqInfo.Num();
info.pQueueCreateInfos = devqInfo.Ptr();
info.pEnabledFeatures = &deviceFeatures;
info.enabledExtensionCount = vkcontext.deviceExtensions.Num();
info.ppEnabledExtensionNames = vkcontext.deviceExtensions.Ptr();
@ -843,7 +886,8 @@ static VkExtent2D ChooseSurfaceExtent( VkSurfaceCapabilitiesKHR& caps )
int width = glConfig.nativeScreenWidth;
int height = glConfig.nativeScreenHeight;
#if defined(__linux__)
// SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
SDL_Vulkan_GetDrawableSize( vkcontext.sdlWindow, &width, &height );
width = idMath::ClampInt( caps.minImageExtent.width, caps.maxImageExtent.width, width );
@ -1110,6 +1154,14 @@ static void CreateRenderTargets()
{
vkcontext.sampleCount = VK_SAMPLE_COUNT_2_BIT;
}
#if defined(__APPLE__)
// SRS - Disable MSAA for OSX since shaderStorageImageMultisample is disabled on MoltenVK for now
if( samples >= 2 )
{
vkcontext.sampleCount = VK_SAMPLE_COUNT_1_BIT;
}
#endif
// Select Depth Format
{
@ -1127,7 +1179,8 @@ static void CreateRenderTargets()
depthOptions.format = FMT_DEPTH;
// Eric: See if this fixes resizing
#if defined(__linux__)
// SRS - Add OSX case
#if defined(__linux__) || defined(__APPLE__)
gpuInfo_t& gpu = *vkcontext.gpu;
VkExtent2D extent = ChooseSurfaceExtent( gpu.surfaceCaps );
@ -1247,7 +1300,8 @@ static void CreateRenderPass()
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
// RB
//depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
// SRS - reenable, otherwise get Vulkan validation layer warnings
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@ -1453,7 +1507,8 @@ void idRenderBackend::Init()
// DG: make sure SDL has setup video so getting supported modes in R_SetNewMode() works
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
VKimp_PreInit();
#else
GLimp_PreInit();
@ -1474,6 +1529,16 @@ void idRenderBackend::Init()
idLib::Printf( "Creating Vulkan Instance...\n" );
CreateVulkanInstance();
// SRS - On macOS optionally set fullImageViewSwizzle to TRUE (instead of env var MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE = 1)
#if defined(__APPLE__) && defined(USE_MoltenVK)
MVKConfiguration pConfig;
size_t pConfigSize = sizeof( pConfig );
vkGetMoltenVKConfigurationMVK( vkcontext.instance, &pConfig, &pConfigSize );
pConfig.fullImageViewSwizzle = VK_TRUE;
vkSetMoltenVKConfigurationMVK( vkcontext.instance, &pConfig, &pConfigSize );
#endif
// create the windowing interface
//#ifdef _WIN32
CreateSurface();
@ -1638,7 +1703,8 @@ void idRenderBackend::Shutdown()
ClearContext();
// destroy main window
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
VKimp_Shutdown();
#else
GLimp_Shutdown();

View file

@ -146,7 +146,9 @@ idVulkanStagingManager::Shutdown
*/
void idVulkanStagingManager::Shutdown()
{
vkUnmapMemory( vkcontext.device, memory );
// SRS - use vkFreeMemory (with implicit unmap) vs. vkUnmapMemory to avoid validation layer errors on shutdown
//vkUnmapMemory( vkcontext.device, memory );
vkFreeMemory( vkcontext.device, memory, NULL );
memory = VK_NULL_HANDLE;
mappedData = NULL;
@ -160,6 +162,10 @@ void idVulkanStagingManager::Shutdown()
maxBufferSize = 0;
currentBuffer = 0;
// SRS - destroy command pool to avoid validation layer errors on shutdown
vkDestroyCommandPool( vkcontext.device, commandPool, NULL );
commandPool = VK_NULL_HANDLE;
}
/*

View file

@ -768,7 +768,27 @@ remove them if not needed.
#include <mutex> // for std::mutex
#include <string.h>
#if !defined(_WIN32)
//SRS - Modified from vkQuake2, to compile with C++11 on OSX versions with no aligned_alloc
#if defined(__APPLE__)
#if !defined(MAC_OS_X_VERSION_10_16) && defined(__cplusplus) && __cplusplus < 201703L
// For C++14, usr/include/malloc/_malloc.h declares aligned_alloc() only with
// the MacOSX11.0 SDK in Xcode 12 (which is what adds MAC_OS_X_VERSION_10_16).
// For C++17 aligned_alloc is available with the 10.15 SDK already.
void* aligned_alloc( size_t alignment, size_t size )
{
// alignment must be >= sizeof(void*)
if(alignment < sizeof(void*))
{
alignment = sizeof(void*);
}
void *pointer;
if(posix_memalign(&pointer, alignment, size) == 0)
return pointer;
return NULL;
}
#endif
#elif !defined(_WIN32)
#include <malloc.h> // for aligned_alloc()
#endif
@ -3468,7 +3488,8 @@ void VmaBlock::PrintDetailedMap( class VmaStringBuilder& sb ) const
sb.Add( ",\n\t\t\t\"FreeBytes\": " );
sb.AddNumber( m_SumFreeSize );
sb.Add( ",\n\t\t\t\"Suballocations\": " );
sb.AddNumber( m_Suballocations.size() );
//SRS - cast to uint32_t to avoid type ambiguity
sb.AddNumber( ( uint32_t )m_Suballocations.size() );
sb.Add( ",\n\t\t\t\"FreeSuballocations\": " );
sb.AddNumber( m_FreeCount );
sb.Add( ",\n\t\t\t\"SuballocationList\": [" );
@ -4933,7 +4954,8 @@ void VmaAllocator_T::PrintDetailedMap( VmaStringBuilder& sb )
sb.Add( ",\n\"OwnAllocations\": {\n\t\"Type " );
ownAllocationsStarted = true;
}
sb.AddNumber( memTypeIndex );
//SRS - cast to uint32_t to avoid type ambiguity, memTypeIndex is an unsigned int
sb.AddNumber( ( uint32_t )memTypeIndex );
if( blockVectorType == VMA_BLOCK_VECTOR_TYPE_MAPPED )
{
sb.Add( " Mapped" );
@ -4984,7 +5006,8 @@ void VmaAllocator_T::PrintDetailedMap( VmaStringBuilder& sb )
sb.Add( ",\n\"Allocations\": {\n\t\"Type " );
allocationsStarted = true;
}
sb.AddNumber( memTypeIndex );
//SRS - cast to uint32_t to avoid type ambiguity, memTypeIndex is an unsigned int
sb.AddNumber( ( uint32_t )memTypeIndex );
if( blockVectorType == VMA_BLOCK_VECTOR_TYPE_MAPPED )
{
sb.Add( " Mapped" );

View file

@ -39,7 +39,7 @@ int maskForNumBits[33] = { NBM( 0x00 ), NBM( 0x01 ), NBM( 0x02 ), NBM( 0x03 ),
NBM( 0x1C ), NBM( 0x1D ), NBM( 0x1E ), NBM( 0x1F ), -1
};
#define NBS( x ) (int32)( (-1) << ( x - 1 ) )
#define NBS( x ) (int32)( (unsigned long)(-1L) << ( x - 1 ) ) // SRS - Cast to unsigned long
int signForNumBits[33] = { NBS( 0x01 ), NBS( 0x01 ), NBS( 0x02 ), NBS( 0x03 ),
NBS( 0x04 ), NBS( 0x05 ), NBS( 0x06 ), NBS( 0x07 ),
NBS( 0x08 ), NBS( 0x09 ), NBS( 0x0A ), NBS( 0x0B ),

View file

@ -396,8 +396,8 @@ void Sys_ReLaunch()
// DG end
}
// OS X doesn't have clock_gettime()
int clock_gettime( clk_id_t clock, struct timespec* tp )
// OS X 10.11 or earlier doesn't have native clock_gettime()
int clock_gettime( /*clk_id_t*/ clockid_t clock, struct timespec* tp ) // SRS - use APPLE clockid_t
{
switch( clock )
{

View file

@ -410,6 +410,7 @@ Sys_DefaultBasePath
Get the default base path
- binary image path
- MacOS app bundle resources directory path // SRS - Added MacOS app bundle resources path
- current directory
- hardcoded
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
@ -434,6 +435,20 @@ const char* Sys_DefaultBasePath()
{
common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
}
#if defined(__APPLE__) // SRS - - Added check for MacOS app bundle resources path
basepath += "/../Resources";
testbase = basepath;
testbase += "/";
testbase += BASE_GAMEDIR;
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
{
return basepath.c_str();
}
else
{
common->Printf( "no '%s' directory in MacOS app bundle resources path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
}
#endif
}
if( basepath != Posix_Cwd() )
{

View file

@ -68,8 +68,10 @@ char* Posix_ConsoleInput();
double MeasureClockTicks();
#ifdef __APPLE__
enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW };
int clock_gettime( clk_id_t clock, struct timespec* tp );
#if !defined(CLOCK_REALTIME) // SRS - define clockid_t enum for OSX 10.11 and earlier
enum /*clk_id_t*/ clockid_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW };
#endif
int clock_gettime( /*clk_id_t*/ clockid_t clock, struct timespec* tp ); // SRS - use APPLE clockid_t
#endif
// Eric: Not used on Linux since using SDL2

View file

@ -852,7 +852,8 @@ void Sys_GrabMouseCursor( bool grabIt )
{
flags = GRAB_SETSTATE;
}
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
VKimp_GrabInput( flags );
#else
GLimp_GrabInput( flags );

View file

@ -35,7 +35,8 @@ const int GRAB_REENABLE = ( 1 << 1 );
const int GRAB_HIDECURSOR = ( 1 << 2 );
const int GRAB_SETSTATE = ( 1 << 3 );
#if defined(__linux__) && defined(USE_VULKAN)
// SRS - Add OSX case
#if ( defined(__linux__) || defined(__APPLE__) ) && defined(USE_VULKAN)
void VKimp_GrabInput( int flags );
#else
void GLimp_GrabInput( int flags );

View file

@ -41,6 +41,10 @@ If you have questions concerning this license or the applicable additional terms
#include <SDL.h>
#include <SDL_vulkan.h>
#include <vulkan/vulkan.h>
// SRS - optinally needed for VK_MVK_MOLTENVK_EXTENSION_NAME visibility
#if defined(__APPLE__) && defined(USE_MoltenVK)
#include <MoltenVK/vk_mvk_moltenvk.h>
#endif
#include <vector>
#include "renderer/RenderCommon.h"
@ -90,6 +94,14 @@ std::vector<const char*> get_required_extensions( const std::vector<const char*>
}
}
// SRS - needed for MoltenVK portability implementation and optionally for MoltenVK configuration on OSX
#if defined(__APPLE__)
sdlInstanceExtensions.push_back( VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME );
#if defined(USE_MoltenVK)
sdlInstanceExtensions.push_back( VK_MVK_MOLTENVK_EXTENSION_NAME );
#endif
#endif
if( enableValidationLayers )
{
sdlInstanceExtensions.push_back( "VK_EXT_debug_report" );
@ -305,11 +317,11 @@ bool VKimp_Init( glimpParms_t parms )
common->Printf( "No usable VK mode found: %s", SDL_GetError() );
return false;
}
/* SRS - This must be leftover code from OpenGL, disable it
#ifdef __APPLE__
glewExperimental = GL_TRUE;
#endif
*/
// DG: disable cursor, we have two cursors in menu (because mouse isn't grabbed in menu)
SDL_ShowCursor( SDL_DISABLE );
// DG end

View file

@ -947,6 +947,8 @@ idSessionCallbacks
class idSessionCallbacks
{
public:
virtual ~idSessionCallbacks() {} // SRS - Added virtual destructor
virtual idLobby& GetPartyLobby() = 0;
virtual idLobby& GetGameLobby() = 0;
virtual idLobby& GetActingGameStateLobby() = 0;

View file

@ -236,6 +236,8 @@ public:
idLobbyBackend() : type( TYPE_INVALID ), isLocal( false ), isHost( false ) {}
idLobbyBackend( lobbyBackendType_t lobbyType ) : type( lobbyType ), isLocal( false ), isHost( false ) {}
virtual ~idLobbyBackend() {} // SRS - Added virtual destructor
virtual void StartHosting( const idMatchParameters& p, float skillLevel, lobbyBackendType_t type ) = 0;
virtual void StartFinding( const idMatchParameters& p, int numPartyUsers, float skillLevel ) = 0;
virtual void JoinFromConnectInfo( const lobbyConnectInfo_t& connectInfo ) = 0;

View file

@ -272,6 +272,7 @@ idSaveLoadParms::~idSaveLoadParms
*/
idSaveLoadParms::~idSaveLoadParms()
{
/* SRS - Don't need to repeat this code here, since auto-deletes are already handled by idSaveGameManager::FinishProcessor
for( int i = 0; i < files.Num(); ++i )
{
if( files[i]->type & SAVEGAMEFILE_AUTO_DELETE )
@ -279,6 +280,7 @@ idSaveLoadParms::~idSaveLoadParms()
delete files[i];
}
}
*/
}
/*

View file

@ -39,7 +39,9 @@ class idVoiceChatMgr
{
public:
idVoiceChatMgr() : activeLobbyType( -1 ), activeGroupIndex( 0 ), sendFrame( 0 ), disableVoiceReasons( 0 ), sendGlobal( false ) {}
virtual ~idVoiceChatMgr() {} // SRS - Added virtual destructor
virtual void Init( void* pXAudio2 );
virtual void Shutdown();