Skip to content
Open
19 changes: 11 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,8 @@ macro(AddApplicationInternal Target Executable)
add_dependencies(${Target} runtime_deps)
endif()

set_property(TARGET ${Target} APPEND PROPERTY COMPILE_OPTIONS ${A_Flags})
set_property(TARGET ${Target} APPEND PROPERTY COMPILE_OPTIONS ${A_CompileFlags})
set_property(TARGET ${Target} APPEND PROPERTY LINK_OPTIONS ${A_LinkFlags})
set_property(TARGET ${Target} APPEND PROPERTY INCLUDE_DIRECTORIES ${ENGINE_DIR} ${MOUNT_DIR} ${LIB_DIR})
set_property(TARGET ${Target} APPEND PROPERTY COMPILE_DEFINITIONS ${A_Definitions})
set_target_properties(${Target} PROPERTIES OUTPUT_NAME "${Executable}" PREFIX "" FOLDER "engine")
Expand All @@ -846,13 +847,14 @@ endmacro()

function(AddApplication)
set(oneValueArgs Target ExecutableName)
set(multiValueArgs ApplicationMain Definitions Flags CompileFeatures Files Libs Tests)
set(multiValueArgs ApplicationMain Definitions CompileFlags LinkFlags Files Libs Tests)
cmake_parse_arguments(A "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

# Reuse object files between the real application and the test one
add_library(${A_Target}-objects OBJECT EXCLUDE_FROM_ALL ${A_Files} ${PCH_FILE})
target_link_libraries(${A_Target}-objects engine-lib ${A_Libs} ${LIBS_BASE} ${CPP23SupportLibrary})
set_property(TARGET ${A_Target}-objects APPEND PROPERTY COMPILE_OPTIONS ${A_Flags})
set_property(TARGET ${A_Target}-objects APPEND PROPERTY COMPILE_OPTIONS ${A_CompileFlags})
set_property(TARGET ${A_Target}-objects APPEND PROPERTY LINK_OPTIONS ${A_LinkFlags})
set_property(TARGET ${A_Target}-objects APPEND PROPERTY INCLUDE_DIRECTORIES ${ENGINE_DIR} ${MOUNT_DIR} ${LIB_DIR})
set_property(TARGET ${A_Target}-objects APPEND PROPERTY COMPILE_DEFINITIONS ${A_Definitions})

Expand Down Expand Up @@ -893,8 +895,8 @@ if (NOT NACL)
ExecutableName dummyapp
Definitions USELESS_DEFINITION_TO_AVOID_PCH_ISSUE
ApplicationMain ${ENGINE_DIR}/null/NullApplication.cpp
Flags ${WARNINGS}
Files ${COMMON_DIR}/Util.h # must be nonempty
CompileFlags ${WARNINGS}
Files ${DUMMYAPPLIST}
Tests ${ENGINETESTLIST}
)
endif()
Expand All @@ -920,7 +922,8 @@ if (BUILD_CLIENT)
ExecutableName ${CLIENT_EXECUTABLE_NAME}
ApplicationMain ${ENGINE_DIR}/client/ClientApplication.cpp
Definitions ${Definitions}
Flags ${WARNINGS}
CompileFlags ${WARNINGS};${OPENMP_FLAG}
LinkFlags ${OPENMP_FLAG}
Files ${WIN_RC} ${BUILDINFOLIST} ${QCOMMONLIST} ${SERVERLIST} ${CLIENTBASELIST} ${CLIENTLIST}
Libs ${LIBS_CLIENT} ${LIBS_CLIENTBASE} ${LIBS_ENGINE}
Tests ${CLIENTTESTLIST}
Expand All @@ -938,7 +941,7 @@ if (BUILD_SERVER)
ExecutableName daemonded
ApplicationMain ${ENGINE_DIR}/server/ServerApplication.cpp
Definitions BUILD_ENGINE BUILD_SERVER
Flags ${WARNINGS}
CompileFlags ${WARNINGS}
Files ${WIN_RC} ${BUILDINFOLIST} ${QCOMMONLIST} ${SERVERLIST} ${DEDSERVERLIST}
Libs ${LIBS_ENGINE}
Tests ${ENGINETESTLIST}
Expand All @@ -951,7 +954,7 @@ if (BUILD_TTY_CLIENT)
ExecutableName daemon-tty
ApplicationMain ${ENGINE_DIR}/client/ClientApplication.cpp
Definitions BUILD_ENGINE BUILD_TTY_CLIENT
Flags ${WARNINGS}
CompileFlags ${WARNINGS}
Files ${WIN_RC} ${BUILDINFOLIST} ${QCOMMONLIST} ${SERVERLIST} ${CLIENTBASELIST} ${TTYCLIENTLIST}
Libs ${LIBS_CLIENTBASE} ${LIBS_ENGINE}
Tests ${ENGINETESTLIST}
Expand Down
24 changes: 24 additions & 0 deletions cmake/DaemonFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ if (USE_FLOAT_EXCEPTIONS)
add_definitions(-DDAEMON_USE_FLOAT_EXCEPTIONS)
endif()

if (NOT NACL AND BUILD_CLIENT)
option(USE_OPENMP "Use OpenMP to parallelize some tasks" OFF)
endif()

if (MSVC)
set_c_cxx_flag("/MP")

Expand All @@ -267,6 +271,16 @@ if (MSVC)
set_cxx_flag("/std:c++23preview")
endif()

if (NOT NACL AND BUILD_CLIENT AND USE_OPENMP)
check_CXX_compiler_flag("/openmp" FLAG_OPENMP)

if (FLAG_OPENMP)
set(OPENMP_FLAG "/openmp")
else()
message(WARNING "Missing OpenMP")
endif()
endif()

if (USE_FAST_MATH)
set_c_cxx_flag("/fp:fast")
else()
Expand Down Expand Up @@ -362,6 +376,16 @@ else()
endif()
endif()

if (NOT NACL AND BUILD_CLIENT AND USE_OPENMP)
check_CXX_compiler_flag("-fopenmp" FLAG_FOPENMP)

if (FLAG_FOPENMP)
set(OPENMP_FLAG "-fopenmp")
else()
message(WARNING "Missing OpenMP")
endif()
endif()

if (NACL AND USE_NACL_SAIGO AND SAIGO_ARCH STREQUAL "arm")
# Saigo produces broken arm builds when optimizing them.
# See: https://github.com/Unvanquished/Unvanquished/issues/3297
Expand Down
13 changes: 13 additions & 0 deletions src.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ set(ENGINELIST
${ENGINE_DIR}/RefAPI.h
)

set(OMPLIST
${ENGINE_DIR}/framework/OmpSystem.cpp
${ENGINE_DIR}/framework/OmpSystem.h
)

if (WIN32)
set(ENGINELIST ${ENGINELIST}
${ENGINE_DIR}/sys/con_passive.cpp
Expand Down Expand Up @@ -271,6 +276,7 @@ set(CLIENTBASELIST
)

set(CLIENTLIST
${OMPLIST}
${ENGINE_DIR}/audio/ALObjects.cpp
${ENGINE_DIR}/audio/ALObjects.h
${ENGINE_DIR}/audio/Audio.cpp
Expand Down Expand Up @@ -304,16 +310,23 @@ set(CLIENTTESTLIST ${ENGINETESTLIST}
)

set(TTYCLIENTLIST
${OMPLIST}
${ENGINE_DIR}/null/NullAudio.cpp
${ENGINE_DIR}/null/NullKeyboard.cpp
${ENGINE_DIR}/null/null_input.cpp
${ENGINE_DIR}/null/null_renderer.cpp
)

set(DEDSERVERLIST
${OMPLIST}
${ENGINE_DIR}/null/NullKeyboard.cpp
${ENGINE_DIR}/null/null_client.cpp
${ENGINE_DIR}/null/null_input.cpp
)

set(DUMMYAPPLIST
${OMPLIST}
${COMMON_DIR}/Util.h
)

set(WIN_RC ${ENGINE_DIR}/sys/windows-resource/icon.rc)
104 changes: 104 additions & 0 deletions src/engine/framework/OmpSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
===========================================================================
Daemon BSD Source Code
Copyright (c) 2025, Daemon Developers
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Daemon developers nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===========================================================================
*/

#include <algorithm>

#include "CvarSystem.h"
#include "OmpSystem.h"

#if defined(_OPENMP)
#include "omp.h"
#endif

#if defined(_OPENMP)
static Cvar::Range<Cvar::Cvar<int>> common_ompThreads(
"common.ompThreads", "OpenMP threads", Cvar::NONE, 0, 0, 32 );
#endif

namespace Omp {
#if defined(_OPENMP)
static int ompMaxThreads = 1;
#endif

static int ompThreads = 1;

static void ReadMaxThreads()
{
#if defined(_OPENMP)
ompMaxThreads = omp_get_max_threads();
#endif
}

void EnlistThreads()
{
#if defined(_OPENMP)
omp_set_num_threads( ompThreads );
#endif
}

void SetupThreads()
{
#if defined(_OPENMP)
if ( common_ompThreads.Get() )
{
ompThreads = common_ompThreads.Get();
return;
}

if ( ompMaxThreads <= 4 )
{
ompThreads = ompMaxThreads;
return;
}

if ( ompMaxThreads <= 16 )
{
ompThreads = ompMaxThreads - ( ompMaxThreads / 4 );
return;
}

ompThreads = 16;
#endif

EnlistThreads();
}

void Init()
{
ReadMaxThreads();
SetupThreads();
EnlistThreads();
}

int GetThreads()
{
return ompThreads;
}
}
41 changes: 41 additions & 0 deletions src/engine/framework/OmpSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
===========================================================================
Daemon BSD Source Code
Copyright (c) 2025, Daemon Developers
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Daemon developers nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===========================================================================
*/

#ifndef COMMON_OMP_SYSTEM_H_
#define COMMON_OMP_SYSTEM_H_

namespace Omp {
void EnlistThreads();
void SetupThreads();
void Init();
int GetThreads();
};

#endif // COMMON_OMP_SYSTEM_H_
3 changes: 3 additions & 0 deletions src/engine/framework/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ConsoleHistory.h"
#include "CommandSystem.h"
#include "LogSystem.h"
#include "OmpSystem.h"
#include "System.h"
#include "CrashDump.h"
#include "CvarSystem.h"
Expand Down Expand Up @@ -829,6 +830,8 @@ static void SetCvarsWithInitFlag(cmdlineArgs_t& cmdlineArgs)
// Initialize the engine
static void Init(int argc, char** argv)
{
Omp::Init();

cmdlineArgs_t cmdlineArgs;

#ifdef _WIN32
Expand Down
3 changes: 3 additions & 0 deletions src/engine/qcommon/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Maryland 20850 USA.
#include "framework/CommandSystem.h"
#include "framework/CvarSystem.h"
#include "framework/LogSystem.h"
#include "framework/OmpSystem.h"
#include "framework/System.h"
#include "sys/sys_events.h"
#include <common/FileSystem.h>
Expand Down Expand Up @@ -783,6 +784,8 @@ static Cvar::Cvar<bool> showTraceStats("common.showTraceStats", "are physics tra

void Com_Frame()
{
Omp::SetupThreads();

int msec, minMsec;
static int lastTime = 0;
//int key;
Expand Down
3 changes: 3 additions & 0 deletions src/engine/renderer/tr_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// tr_backend.c

#include "framework/OmpSystem.h"
#include "tr_local.h"
#include "gl_shader.h"
#include "Material.h"
Expand Down Expand Up @@ -3829,6 +3830,8 @@ RB_RenderThread
*/
void RB_RenderThread()
{
Omp::EnlistThreads();

const void *data;

// wait for either a rendering command or a quit command
Expand Down
16 changes: 16 additions & 0 deletions src/engine/renderer/tr_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_init.c -- functions that are not called every frame
#include "tr_local.h"
#include "framework/CvarSystem.h"
#include "framework/OmpSystem.h"
#include "DetectGLVendors.h"
#include "Material.h"
#include "GeometryCache.h"
Expand Down Expand Up @@ -1057,6 +1058,21 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
Log::Notice("Using dual processor acceleration." );
}

#if defined(_OPENMP)
int ompThreads = Omp::GetThreads();

if ( ompThreads == 1 )
{
Log::Notice("%sNot using OpenMP parallelism: only one thread.", Color::ToString( Color::Red ) );
}
else
{
Log::Notice("%sUsing OpenMP parallelism with %d threads.", Color::ToString( Color::Green ), ompThreads );
}
#else
Log::Notice("%sNot using OpenMP parallelism: unavailable.", Color::ToString( Color::Red ) );
#endif

if ( r_finish->integer )
{
Log::Notice("Forcing glFinish." );
Expand Down
Loading
Loading