Integrating latest from github/staging

Integrating up through commit 5e1bdae
This commit is contained in:
alexpete
2021-03-26 14:31:50 -07:00
parent 9c54341af8
commit 36c4e827bd
764 changed files with 11453 additions and 20251 deletions
@@ -1080,7 +1080,7 @@ void C3DEngine::WorldStreamUpdate()
if (GetCVars()->e_StreamSaveStartupResultsIntoXML)
{
const char* testResultsFile = "@cache@/TestResults/Streaming_Level_Start_Throughput.xml";
const char* testResultsFile = "@usercache@/TestResults/Streaming_Level_Start_Throughput.xml";
AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb");
if (resultsFile != AZ::IO::InvalidHandle)
+1 -1
View File
@@ -952,7 +952,7 @@ void C3DEngine::ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOu
if (GetCVars()->e_SQTestCount == 0)
{
const char* testResultsFile = "@cache@/TestResults/Streaming_Latency_Test.xml";
const char* testResultsFile = "@usercache@/TestResults/Streaming_Latency_Test.xml";
AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb");
if (resultsFile != AZ::IO::InvalidHandle)
+2 -12
View File
@@ -461,7 +461,7 @@ void C3DEngine::UnloadLevel()
m_ptexIconLowMemoryUsage = nullptr;
m_ptexIconHighMemoryUsage = nullptr;
m_ptexIconEditorConnectedToConsole = nullptr;
if (m_pOpticsManager && !gEnv->IsEditor())
{
m_pOpticsManager->Reset();
@@ -656,7 +656,7 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
// set default render parameters.
// for some reason this is not done later???
m_pSkyLightManager->UpdateRenderParams();
}
}
// Load LevelData.xml File.
XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
@@ -687,17 +687,7 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
// preload level cgfs
if (GetCVars()->e_StatObjPreload && !gEnv->IsEditor())
{
if (GetCVars()->e_StatObjPreload == 2)
{
GetSystem()->OutputLoadingTimeStats();
}
m_pObjManager->PreloadLevelObjects();
if (GetCVars()->e_StatObjPreload == 2)
{
GetSystem()->OutputLoadingTimeStats();
}
}
std::vector<struct IStatObj*>* pStatObjTable = NULL;
+2 -1
View File
@@ -317,7 +317,8 @@ int CLightEntity::UpdateGSMLightSourceDynamicShadowFrustum(int nDynamicLodCount,
if (bDoGSM)
{
Vec3 vSunDir = Get3DEngine()->GetSunDir().GetNormalized(); // todo: remove GetNormalized() once GetSunDir() returns the normalized value
//Vec3 vSunDir = Get3DEngine()->GetSunDir().GetNormalized(); // todo: remove GetNormalized() once GetSunDir() returns the normalized value
Vec3 vSunDir = Vec3(1.0f, 0.0f, 0.0f);
Vec3 vCameraDirWithoutDepth = vCameraDir - vCameraDir.Dot(vSunDir) * vSunDir;
Vec3 vFocusPos = passInfo.GetCamera().GetPosition() + vCameraDirWithoutDepth * fGSMBoxSize;
+1 -14
View File
@@ -117,10 +117,6 @@ CMatInfo::CMatInfo()
ZeroStruct(m_streamZoneInfo);
#ifdef TRACE_MATERIAL_LEAKS
m_sLoadingCallstack = GetSystem()->GetLoadingProfilerCallstack();
#endif
// Used to know when a .dccmtl file has been changed,
// requiring the source material to be updated
m_dccMaterialHash = 0;
@@ -341,7 +337,7 @@ ISurfaceType* CMatInfo::GetSurfaceType()
//////////////////////////////////////////////////////////////////////////
void CMatInfo::SetSubMtlCount(int numSubMtl)
{
AUTO_LOCK(GetSubMaterialResizeLock());
AUTO_LOCK(GetSubMaterialResizeLock());
if (numSubMtl > 0)
{
m_Flags |= MTL_FLAG_MULTI_SUBMTL;
@@ -1112,15 +1108,6 @@ void CMatInfo::SetTexelDensityDebug([[maybe_unused]] int mode)
#endif
}
const char* CMatInfo::GetLoadingCallstack()
{
#ifdef TRACE_MATERIAL_LEAKS
return m_sLoadingCallstack.c_str();
#else
return "";
#endif
}
void CMatInfo::PrecacheMaterial(const float _fEntDistance, IRenderMesh* pRenderMesh, bool bFullUpdate, bool bDrawNear)
{
// FUNCTION_PROFILER_3DENGINE;
+1 -14
View File
@@ -18,7 +18,6 @@
#include <IMaterial.h>
#if !defined(CONSOLE)
# define TRACE_MATERIAL_LEAKS
# define SUPPORT_MATERIAL_EDITING
#endif
@@ -203,7 +202,7 @@ public:
bool SetGetMaterialParamFloat(const char* sParamName, float& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
bool SetGetMaterialParamVec3(const char* sParamName, Vec3& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
bool SetGetMaterialParamVec4(const char* sParamName, Vec4& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
void SetDirty(bool dirty = true) override;
bool IsDirty() const override;
@@ -264,11 +263,6 @@ public:
bool IsForwardRenderingRequired();
bool IsNearestCubemapRequired();
//////////////////////////////////////////////////////////////////////////
// Debug routines
//////////////////////////////////////////////////////////////////////////
virtual const char* GetLoadingCallstack(); // trace leaking materials by callstack
void DisableTextureStreaming() override;
virtual void RequestTexturesLoading(const float fMipFactor);
@@ -286,13 +280,6 @@ public:
void SetDccMaterialHash(uint32 hash) override { m_dccMaterialHash = hash; }
virtual CryCriticalSection& GetSubMaterialResizeLock();
public:
//////////////////////////////////////////////////////////////////////////
// for debug purposes
//////////////////////////////////////////////////////////////////////////
#ifdef TRACE_MATERIAL_LEAKS
string m_sLoadingCallstack;
#endif
private:
friend class CMatMan;
+1 -9
View File
@@ -16,7 +16,6 @@
#pragma once
#if !defined(CONSOLE)
# define TRACE_CGF_LEAKS
# define SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS
#endif
@@ -337,13 +336,6 @@ public:
std::vector<uint16> m_chunkBoneIds;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// for debug purposes
//////////////////////////////////////////////////////////////////////////
#ifdef TRACE_CGF_LEAKS
string m_sLoadingCallstack;
#endif
private:
//////////////////////////////////////////////////////////////////////////
// Sub objects.
@@ -419,7 +411,7 @@ public:
virtual unsigned int GetBreakableByGame() { return m_bBreakableByGame; };
//Note: This function checks both the children and root data
//It should really be 'has any deformable objects'
//It should really be 'has any deformable objects'
//Should eventually be refactored as part of an eventual statobj refactor.
virtual bool IsDeformable() override;
@@ -56,10 +56,6 @@ CStatObj::CStatObj()
m_fLodDistance = 0.0f;
Init();
#ifdef TRACE_CGF_LEAKS
m_sLoadingCallstack = GetSystem()->GetLoadingProfilerCallstack();
#endif
}
//////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -1064,7 +1064,7 @@ namespace Audio
///////////////////////////////////////////////////////////////////////////////////////////
// Interface methods
virtual bool Initialize(const SSystemInitParams* initParams) = 0;
virtual bool Initialize() = 0;
virtual void Release() = 0;
};
+1 -6
View File
@@ -392,7 +392,7 @@ struct IMaterial
virtual void SetDirty(bool dirty = true) = 0;
virtual bool IsDirty() const = 0;
//! Returns true if the material is the parent of a group of materials
//! Returns true if the material is the parent of a group of materials
virtual bool IsMaterialGroup() const = 0;
//! Returns true if the material is a single material belongs to a material group
@@ -411,11 +411,6 @@ struct IMaterial
// - 2, fast sketch mode.
virtual void SetSketchMode(int mode) = 0;
//////////////////////////////////////////////////////////////////////////
// Debug routines
//////////////////////////////////////////////////////////////////////////
virtual const char* GetLoadingCallstack() = 0; // trace leaking materials by callstack
// Sets FT_DONT_STREAM flag for all textures used by the material
// If a stream is already in process, this will stop the stream and flush the device texture
virtual void DisableTextureStreaming() = 0;
+7 -189
View File
@@ -119,8 +119,6 @@ namespace AZ
class IResourceCompilerHelper;
class CBootProfilerRecord;
namespace Serialization {
struct IArchiveHost;
}
@@ -629,15 +627,7 @@ struct SSystemInitParams
void* hWnd; //
void* hWndForInputSystem; // the HWND for the input devices, distinct from the hWnd, which the rendering system overrides anyways
char remoteIP[256];
int remotePort;
bool remoteFileIO;
bool remoteResourceCompiler;
bool connectToRemote;
bool waitForConnection; // if true, wait for the remote connection to be established before proceeding to system init.
char assetsPlatform[64]; // what flavor of assets to load. Corresponds to those in rc.ini and asset processor ini
char gameFolderName[256]; // just the name. Not the full path.
char branchToken[12]; // information written by the assetprocessor which help determine whether the game/editor are running from the same branch or not
ILog* pLog; // You can specify your own ILog to be used by System.
ILogCallback* pLogCallback; // You can specify your own ILogCallback to be added on log creation (used by Editor).
@@ -648,45 +638,6 @@ struct SSystemInitParams
IOutputPrintSink* pPrintSync; // Print Sync which can be used to catch all output from engine
char szSystemCmdLine[2048]; // Command line.
// set some paths before you create the system.
// rootPath - (REQUIRED) folder containing root. Must contain system.cfg or bootstrap.cfg basically.
// the remainder are optional and if specified should contain prefixes that can be prepended to any file to get to that location:
// READ ONLY!
char rootPath[256];
char rootPathCache[256];
// assetsPath - (REQUIRED) - where you assets live. The engine config parser will default this to @root@/gamename
// READ ONLY!
char assetsPath[256];
char assetsPathCache[256];
// userPath - (OPTIONAL) User path contains a folder for preferences persistent storage. May be persisted to the cloud (by things like IOS)
// If not specified, this is assumed @root@/User/
// WRITABLE
char userPath[256];
// cachePath - (OPTIONAL) a temporary store that can be erased at any time and does not need to be persisted
// on the cloud or anything like that. if not specified, this will be @user@/Cache
// WRITABLE
char cachePath[256];
// logPath - (OPTIONAL) a log path folder.
// If not specified, it will be @cache@/Logs
// WRITABLE
char logPath[256];
// the game should never use these values instead, the game should be using crypak or fileio with aliases:
// @root@ To get to the folder where system.cfg lives
// @assets@ to get to the folder containing game assets (textures and such) - by default, this is @root@/Gamename/
// @devroot@ to get to source files that are checked into source control (PC EDITOR ONLY!)
// @engroot@ to get to path to the engine root folder
// @user@ to access user store
// @cache@ to access temporary cache
// @log@ to access log file and other forensic storage
char szBinariesDir[256];
bool bEditor; // When running in Editor mode.
bool bPreview; // When running in Preview mode (Minimal initialization).
bool bTestMode; // When running in Automated testing mode.
@@ -730,26 +681,7 @@ struct SSystemInitParams
hWnd = NULL;
hWndForInputSystem = NULL;
memset(rootPath, 0, sizeof(rootPath));
memset(rootPathCache, 0, sizeof(rootPathCache));
memset(userPath, 0, sizeof(userPath));
memset(assetsPath, 0, sizeof(assetsPath));
memset(assetsPathCache, 0, sizeof(assetsPathCache));
memset(cachePath, 0, sizeof(cachePath));
memset(logPath, 0, sizeof(logPath));
memset(gameFolderName, 0, sizeof(gameFolderName));
memset(branchToken, 0, sizeof(branchToken));
memset(remoteIP, 0, sizeof(remoteIP));
azstrcpy(remoteIP, sizeof(remoteIP), "127.0.0.1");
memset(assetsPlatform, 0, sizeof(assetsPlatform));
azstrcpy(assetsPlatform, sizeof(assetsPlatform), "pc");
remotePort = 45643;
remoteFileIO = false;
remoteResourceCompiler = false;
connectToRemote = false;
waitForConnection = false;
pLog = NULL;
pLogCallback = NULL;
@@ -762,7 +694,6 @@ struct SSystemInitParams
pValidator = NULL;
pPrintSync = NULL;
memset(szSystemCmdLine, 0, sizeof(szSystemCmdLine));
memset(szBinariesDir, 0, sizeof(szBinariesDir));
bEditor = false;
bPreview = false;
@@ -798,17 +729,6 @@ struct SSystemInitParams
pSharedEnvironment = nullptr;
}
bool UseAssetCache() const
{
#if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_MAC) || defined(AZ_PLATFORM_LINUX)
char checkPath[AZ_MAX_PATH_LEN] = { 0 };
azsnprintf(checkPath, AZ_MAX_PATH_LEN, "%s/engine.json", rootPathCache);
return AZ::IO::SystemFile::Exists(checkPath);
#else
return false;
#endif // defined(AZ_PLATFORM_WINDOWS) || AZ_TRAIT_OS_PLATFORM_APPLE
}
};
// Notes:
@@ -1228,11 +1148,6 @@ struct ISystem
// Gets number of CPUs
virtual int GetLogicalCPUCount() = 0;
//! Get the 'kind' of assets you need to load - this describes the flavor of assets you are going to load
//! based on the platform you're on - so for example, android on ES3 will be 'es3' but android on opengl might load PC assets or others...
//! This is defined in bootstrap.cfg and is read-only during runtime.
virtual const char* GetAssetsPlatform() const = 0;
// Summary:
// Return the rendering driver name. GL or Metal
virtual const char* GetRenderingDriverName() const = 0;
@@ -1406,43 +1321,6 @@ struct ISystem
// True if system running in Test mode.
virtual bool IsTestMode() const = 0;
//////////////////////////////////////////////////////////////////////////
// Loading time/memory profiling
//////////////////////////////////////////////////////////////////////////
// Summary:
// Starts function loading stats profiling.
virtual struct SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName) = 0;
// Summary:
// Ends function loading stats profiling.
virtual void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler) = 0;
// Summary:
// Starts function profiling with bootprofiler (session must be started).
virtual CBootProfilerRecord* StartBootSectionProfiler(const char* name, const char* args) = 0;
// Summary:
// Ends function profiling with bootprofiler.
virtual void StopBootSectionProfiler(CBootProfilerRecord* record) = 0;
// Summary:
// Starts frame session
virtual void StartBootProfilerSessionFrames(const char* pName) = 0;
// Summary:
// Stops frame session
virtual void StopBootProfilerSessionFrames() = 0;
// Summary:
// Prints loading stats into log.
virtual void OutputLoadingTimeStats() = 0;
// Summary:
// Starts function loading stats profiling.
virtual const char* GetLoadingProfilerCallstack() = 0;
//////////////////////////////////////////////////////////////////////////
// File version.
//////////////////////////////////////////////////////////////////////////
@@ -1581,10 +1459,10 @@ struct ISystem
//////////////////////////////////////////////////////////////////////////
// Summary:
// Enable/Disable drawing the console
// Enable/Disable drawing the console
virtual void SetConsoleDrawEnabled(bool enabled) = 0;
// Enable/Disable drawing the UI
// Enable/Disable drawing the UI
virtual void SetUIDrawEnabled(bool enabled) = 0;
// Summary:
@@ -1772,79 +1650,19 @@ struct DiskOperationInfo
#endif
#if defined(ENABLE_LOADING_PROFILER)
struct CLoadingTimeProfiler
{
CLoadingTimeProfiler(ISystem* pSystem, const char* szFuncName)
: m_pSystem(pSystem)
{
m_pSystem = pSystem;
m_pTimeContainer = m_pSystem->StartLoadingSectionProfiling(this, szFuncName);
}
~CLoadingTimeProfiler()
{
m_pSystem->EndLoadingSectionProfiling(this);
}
struct SLoadingTimeContainer* m_pTimeContainer;
double m_fConstructorTime;
double m_fConstructorMemUsage;
DiskOperationInfo m_constructorInfo;
ISystem* m_pSystem;
};
class CSYSBootProfileBlock
{
ISystem* m_pSystem;
CBootProfilerRecord* m_pRecord;
public:
CSYSBootProfileBlock(ISystem* pSystem, const char* name, const char* args = NULL)
: m_pSystem(pSystem)
{
if (m_pSystem)
{
m_pRecord = m_pSystem->StartBootSectionProfiler(name, args);
}
}
~CSYSBootProfileBlock()
{
if (m_pSystem)
{
m_pSystem->StopBootSectionProfiler(m_pRecord);
}
}
};
#ifdef AZ_PROFILE_TELEMETRY
#if defined(ENABLE_LOADING_PROFILER) && AZ_PROFILE_TELEMETRY
#define LOADING_TIME_PROFILE_SECTION AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore)
#define LOADING_TIME_PROFILE_SECTION_ARGS(...) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, __VA_ARGS__)
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName) AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, sectionName)
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, sectionName, args)
#else
#define LOADING_TIME_PROFILE_SECTION CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv && gEnv->pSystem ? gEnv->pSystem : nullptr, __FUNCTION__);
#define LOADING_TIME_PROFILE_SECTION_ARGS(args) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, __FUNCTION__, args);
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, sectionName);
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, sectionName, args);
#endif // AZ_PROFILE_TELEMETRY
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, ...) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, sectionName, __VA_ARGS__)
#else
#define LOADING_TIME_PROFILE_SECTION
#define LOADING_TIME_PROFILE_SECTION_ARGS(args)
#define LOADING_TIME_PROFILE_SECTION_ARGS(...)
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName)
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args)
#define LOADING_TIME_PROFILE_SESSION_SECTION(sessionName)
#define LOADING_TIME_PROFILE_SESSION_START(sessionName)
#define LOADING_TIME_PROFILE_SESSION_STOP(sessionName)
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, ...)
#endif
@@ -1865,7 +1683,7 @@ extern SC_API SSystemGlobalEnvironment* gEnv;
inline ISystem* GetISystem()
{
// Some unit tests temporarily install and then uninstall ISystem* mocks.
// It is generally okay for runtime and tool systems which call this function to cache the returned pointer,
// It is generally okay for runtime and tool systems which call this function to cache the returned pointer,
// because their lifetime is usually shorter than the lifetime of the ISystem* implementation.
// It is NOT safe for this function to cache it as a static itself, though, as the static it would cache
// it inside may outlive the the actual instance implementing ISystem* when unit tests are torn down and then restarted.
+7 -8
View File
@@ -15,10 +15,12 @@
#include <AzCore/base.h>
#include <AzCore/IO/SystemFile.h> // for max path len
#include <ISystem.h>
#include <AzCore/std/string/string.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <ISystem.h>
namespace MaterialUtils
{
//! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes
@@ -75,14 +77,11 @@ namespace MaterialUtils
static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 };
if (!removals[removalSize - 1])
{
if ((gEnv) && (gEnv->pConsole))
auto projectName = AZ::Utils::GetProjectName();
if (!projectName.empty())
{
ICVar* pGameNameCVar = gEnv->pConsole->GetCVar("sys_game_folder");
if (pGameNameCVar)
{
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, pGameNameCVar->GetString());
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
}
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str());
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
}
if (cachedGameName[0] == 0)
@@ -55,8 +55,6 @@ public:
int());
MOCK_METHOD0(GetLogicalCPUCount,
int());
MOCK_CONST_METHOD0(GetAssetsPlatform,
const char*());
MOCK_CONST_METHOD0(GetRenderingDriverName,
const char*());
MOCK_METHOD1(DumpMemoryUsageStatistics,
@@ -206,22 +204,6 @@ public:
bool());
MOCK_METHOD3(SetFrameProfiler,
void(bool on, bool display, char* prefix));
MOCK_METHOD2(StartLoadingSectionProfiling,
struct SLoadingTimeContainer*(CLoadingTimeProfiler * pProfiler, const char* szFuncName));
MOCK_METHOD1(EndLoadingSectionProfiling,
void(CLoadingTimeProfiler * pProfiler));
MOCK_METHOD2(StartBootSectionProfiler,
CBootProfilerRecord * (const char* name, const char* args));
MOCK_METHOD1(StopBootSectionProfiler,
void(CBootProfilerRecord * record));
MOCK_METHOD1(StartBootProfilerSessionFrames,
void(const char* pName));
MOCK_METHOD0(StopBootProfilerSessionFrames,
void());
MOCK_METHOD0(OutputLoadingTimeStats,
void());
MOCK_METHOD0(GetLoadingProfilerCallstack,
const char*());
MOCK_METHOD0(GetFileVersion,
const SFileVersion&());
MOCK_METHOD0(GetProductVersion,
@@ -1,160 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include "ISystem.h"
#include <AzCore/base.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/Platform/PlatformDefaults.h>
// any of the following tags can be present in the bootstrap.cfg
// you can also prefix it with a platform.
// so for example, you can specify remote_ip alone to specify it for all platforms
// or you could specify android_remote_ip to change it for android only.
// the instructions are executed in the order that they appear, so you can set the default
// by using the non-platform-specific version, and then later on in the file you
// can override specific platforms.
#define CONFIG_KEY_FOR_REMOTEIP "remote_ip"
#define CONFIG_KEY_FOR_REMOTEPORT "remote_port"
#define CONFIG_KEY_FOR_GAMEFOLDER "sys_game_folder"
#define CONFIG_KEY_FOR_REMOTEFILEIO "remote_filesystem"
#define CONFIG_KEY_FOR_CONNECTTOREMOTE "connect_to_remote"
#define CONFIG_KEY_WAIT_FOR_CONNECT "wait_for_connect"
#define DEFAULT_GAMEDLL "EmptyTemplate"
#define DEFAULT_GAMEFOLDER "EmptyTemplate"
#define DEFAULT_REMOTEIP "127.0.0.1"
#define DEFAULT_REMOTEPORT 45643
#define CONFIG_KEY_FOR_ASSETS "assets"
#define CONFIG_KEY_FOR_BRANCHTOKEN "assetProcessor_branch_token"
//////////////////////////////////////////////////////////////////////////
class CEngineConfig
{
public:
string m_gameFolder; // folder only ("MyGame")
string m_assetPlatform; // what platform folder assets are from if more than one is available or using VFS ("pc" / "es3")
bool m_connectToRemote;
bool m_remoteFileIO;
bool m_waitForConnect;
string m_remoteIP;
int m_remotePort;
string m_rootFolder; // The engine root folder
string m_branchToken;
CEngineConfig([[maybe_unused]] const char** sourcePaths = nullptr, [[maybe_unused]] size_t numSearchPaths = 0, [[maybe_unused]] size_t numLevelsUp = 3)
: m_gameFolder(DEFAULT_GAMEFOLDER)
, m_connectToRemote(false)
, m_remoteFileIO(false)
, m_remotePort(DEFAULT_REMOTEPORT)
, m_waitForConnect(false)
, m_remoteIP(DEFAULT_REMOTEIP)
{
m_assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
AZ::SettingsRegistryInterface::FixedValueString gameFolder;
auto gameFolderKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/%s",
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, CONFIG_KEY_FOR_GAMEFOLDER);
if (settingsRegistry->Get(gameFolder, gameFolderKey))
{
m_gameFolder.assign(gameFolder.c_str(), gameFolder.size());
}
AZ::SettingsRegistryInterface::FixedValueString engineRoot;
if (settingsRegistry->Get(engineRoot, AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
{
m_rootFolder.assign(engineRoot.c_str(), engineRoot.size());
}
}
OnLoadSettings();
}
void CopyToStartupParams(SSystemInitParams& startupParams) const
{
startupParams.remoteFileIO = m_remoteFileIO;
startupParams.remotePort = m_remotePort;
startupParams.connectToRemote = m_connectToRemote;
startupParams.waitForConnection = m_waitForConnect;
azstrncpy(startupParams.remoteIP, sizeof(startupParams.remoteIP), m_remoteIP.c_str(), m_remoteIP.length() + 1); // +1 for the null terminator
azstrncpy(startupParams.assetsPlatform, sizeof(startupParams.assetsPlatform), m_assetPlatform.c_str(), m_assetPlatform.length() + 1); // +1 for the null terminator
azstrncpy(startupParams.rootPath, sizeof(startupParams.rootPath), m_rootFolder.c_str(), m_rootFolder.length() + 1); // +1 for the null terminator
azstrncpy(startupParams.gameFolderName, sizeof(startupParams.gameFolderName), m_gameFolder.c_str(), m_gameFolder.length() + 1); // +1 for the null terminator
azstrncpy(startupParams.branchToken, sizeof(startupParams.branchToken), m_branchToken.c_str(), m_branchToken.length() + 1); // +1 for the null terminator
// compute assets path based on game folder name
string gameFolderLower(m_gameFolder);
gameFolderLower.MakeLower();
azsnprintf(startupParams.assetsPath, sizeof(startupParams.assetsPath), "%s/%s", startupParams.rootPath, gameFolderLower.c_str());
// compute where the cache should be located
azsnprintf(startupParams.rootPathCache, sizeof(startupParams.rootPathCache), "%s/Cache/%s/%s", m_rootFolder.c_str(), m_gameFolder.c_str(), m_assetPlatform.c_str());
azsnprintf(startupParams.assetsPathCache, sizeof(startupParams.assetsPathCache), "%s/%s", startupParams.rootPathCache, gameFolderLower.c_str());
}
protected:
void OnLoadSettings()
{
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry == nullptr)
{
AZ_Warning("ParseEngineConfig", false, "Attempting to load configuration data while SettingsRegistry does not exist");
return;
}
AZ::SettingsRegistryInterface::FixedValueString settingsKeyPrefix = AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey;
AZ::SettingsRegistryInterface::FixedValueString settingsValueString;
AZ::s64 settingsValueInt{};
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEFILEIO))
{
m_remoteFileIO = settingsValueInt != 0;
}
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_WAIT_FOR_CONNECT))
{
m_waitForConnect = settingsValueInt != 0;
}
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_CONNECTTOREMOTE))
{
m_connectToRemote = settingsValueInt != 0;
}
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEPORT))
{
m_remotePort = aznumeric_cast<AZ::u16>(settingsValueInt);
}
if (settingsValueString = {};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueString, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEIP))
{
m_remoteIP.assign(settingsValueString.c_str(), settingsValueString.size());
}
if (settingsValueString = {};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueString, settingsKeyPrefix, CONFIG_KEY_FOR_ASSETS))
{
m_assetPlatform.assign(settingsValueString.c_str(), settingsValueString.size());
}
if (settingsValueString = {};
settingsRegistry->Get(settingsValueString, settingsKeyPrefix + "/" + CONFIG_KEY_FOR_BRANCHTOKEN))
{
m_branchToken.assign(settingsValueString.c_str(), settingsValueString.size());
}
}
};
+1 -1
View File
@@ -293,7 +293,7 @@ typedef uint32 vtx_idx;
#if defined(ENABLE_PROFILING_CODE)
# define USE_DISK_PROFILER
//# define ENABLE_LOADING_PROFILER // Not guaranteed to have enough slots for all the threads in the system
# define ENABLE_LOADING_PROFILER // requires AZ_PROFILE_TELEMETRY to also be defined
#endif
#if defined(SOFTCODE_ENABLED)
@@ -110,7 +110,6 @@ set(FILES
AzDXGIFormat.h
SFunctor.h
FunctorBaseFunction.h
ParseEngineConfig.h
CustomMemoryHeap.h
FunctorBaseMember.h
stridedptr.h
-630
View File
@@ -1,630 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#if defined(ENABLE_LOADING_PROFILER)
#include "BootProfiler.h"
#include "ThreadInfo.h"
#include <stack>
#include <AzFramework/IO/FileOperations.h>
namespace
{
StaticInstance<CBootProfiler, AZStd::no_destruct<CBootProfiler>> gProfilerInstance;
enum
{
eMAX_THREADS_TO_PROFILE = 128,
eNUM_RECORDS_PER_POOL = 2048, // so, eNUM_RECORDS_PER_POOL * sizeof(CBootProfilerRecord) == mem consumed by pool item
// sizeof(CProfileBlockTimes)==152,
// poolmem = 304Kb for 1 pool per thread
};
}
int CBootProfiler::CV_sys_bp_frames = 0;
float CBootProfiler::CV_sys_bp_time_threshold = 0;
class CProfileBlockTimes
{
protected:
LARGE_INTEGER m_startTimeStamp;
LARGE_INTEGER m_stopTimeStamp;
LARGE_INTEGER m_freq;
CProfileBlockTimes()
{
memset(&m_startTimeStamp, 0, sizeof(m_startTimeStamp));
memset(&m_stopTimeStamp, 0, sizeof(m_stopTimeStamp));
memset(&m_freq, 0, sizeof(m_freq));
}
};
class CBootProfilerRecord
{
public:
const char* m_label;
LARGE_INTEGER m_startTimeStamp;
LARGE_INTEGER m_stopTimeStamp;
LARGE_INTEGER m_freq;
CBootProfilerRecord* m_pParent;
typedef AZStd::vector<CBootProfilerRecord*> ChildVector;
ChildVector m_Childs;
CryFixedStringT<256> m_args;
ILINE CBootProfilerRecord(const char* label, LARGE_INTEGER timestamp, LARGE_INTEGER freq, const char* args)
: m_label(label)
, m_startTimeStamp(timestamp)
, m_freq(freq)
, m_pParent(NULL)
{
memset(&m_stopTimeStamp, 0, sizeof(m_stopTimeStamp));
if (args)
{
m_args = args;
}
}
ILINE ~CBootProfilerRecord()
{
// childs are allocated via pool as well, the destructors of each child
// is called explicitly, for the purpose of freeing memory occupied by
// m_Child vector. Otherwise there will be a memory leak.
ChildVector::iterator it = m_Childs.begin();
while (it != m_Childs.end())
{
(*it)->~CBootProfilerRecord();
++it;
}
}
void Print(AZ::IO::HandleType fileHandle, char* buf, size_t buf_size, size_t depth, LARGE_INTEGER stopTime, const char* threadName, const float timeThreshold)
{
if (m_stopTimeStamp.QuadPart == 0)
{
m_stopTimeStamp = stopTime;
}
const float time = (float)(m_stopTimeStamp.QuadPart - m_startTimeStamp.QuadPart) * 1000.f / (float)m_freq.QuadPart;
if (timeThreshold > 0.0f && time < timeThreshold)
{
return;
}
string tabs; //tabs(depth++, '\t')
tabs.insert(0, depth++, '\t');
{
string label = m_label;
label.replace("&", "&amp;");
label.replace("<", "&lt;");
label.replace(">", "&gt;");
label.replace("\"", "&quot;");
label.replace("'", "&apos;");
if (m_args.size() > 0)
{
m_args.replace("&", "&amp;");
m_args.replace("<", "&lt;");
m_args.replace(">", "&gt;");
m_args.replace("\"", "&quot;");
m_args.replace("'", "&apos;");
m_args.replace("%", "&#37;");
}
sprintf_s(buf, buf_size, "%s<block name=\"%s\" totalTimeMS=\"%f\" startTime=\"%" PRIu64 "\" stopTime=\"%" PRIu64 "\" args=\"%s\"> \n",
tabs.c_str(), label.c_str(), time, m_startTimeStamp.QuadPart, m_stopTimeStamp.QuadPart, m_args.c_str());
AZ::IO::Print(fileHandle, buf);
}
const size_t childsSize = m_Childs.size();
for (size_t i = 0; i < childsSize; ++i)
{
CBootProfilerRecord* record = m_Childs[i];
assert(record);
record->Print(fileHandle, buf, buf_size, depth, stopTime, threadName, timeThreshold);
}
sprintf_s(buf, buf_size, "%s</block>\n", tabs.c_str());
AZ::IO::Print(fileHandle, buf);
}
};
//////////////////////////////////////////////////////////////////////////
class CProfileInfo
{
friend class CBootProfilerSession;
private:
CBootProfilerRecord* m_pRoot;
CBootProfilerRecord* m_pCurrent;
public:
CProfileInfo()
: m_pRoot(NULL)
, m_pCurrent(NULL) {}
};
class CBootProfilerThreadsInterface
{
protected:
CBootProfilerThreadsInterface()
{
memset(m_threadInfo, 0, sizeof(m_threadInfo));
m_threadCounter = 0;
}
unsigned int GetThreadIndexByID(unsigned int threadID);
const char* GetThreadNameByIndex(unsigned int threadIndex);
int m_threadCounter;
private:
unsigned int m_threadInfo[eMAX_THREADS_TO_PROFILE]; //threadIDs
};
//////////////////////////////////////////////////////////////////////////
ILINE unsigned int CBootProfilerThreadsInterface::GetThreadIndexByID(unsigned int threadID)
{
for (int i = 0; i < eMAX_THREADS_TO_PROFILE; ++i)
{
if (m_threadInfo[i] == 0)
{
break;
}
if (m_threadInfo[i] == threadID)
{
return i;
}
}
unsigned int counter = CryInterlockedIncrement(&m_threadCounter) - 1; //count to index
m_threadInfo[counter] = threadID;
return counter;
}
ILINE const char* CBootProfilerThreadsInterface::GetThreadNameByIndex(unsigned int threadIndex)
{
assert(threadIndex < m_threadCounter);
const char* threadName = CryThreadGetName(m_threadInfo[threadIndex]);
return threadName;
}
class CRecordPool
{
public:
CRecordPool()
: m_baseAddr(NULL)
, m_allocCounter(0)
, m_next(NULL)
{
m_baseAddr = (CBootProfilerRecord*)CryModuleMemalign(eNUM_RECORDS_PER_POOL * sizeof(CBootProfilerRecord), 16);
}
~CRecordPool()
{
CryModuleMemalignFree(m_baseAddr);
delete m_next;
}
ILINE CBootProfilerRecord* allocateRecord()
{
if (m_allocCounter < eNUM_RECORDS_PER_POOL)
{
CBootProfilerRecord* newRecord = m_baseAddr + m_allocCounter;
++m_allocCounter;
return newRecord;
}
else
{
return NULL;
}
}
ILINE void setNextPool(CRecordPool* pool) { m_next = pool; }
private:
CBootProfilerRecord* m_baseAddr;
uint32 m_allocCounter;
CRecordPool* m_next;
};
class CBootProfilerSession
: public CBootProfilerThreadsInterface
, protected CProfileBlockTimes
{
public:
CBootProfilerSession();
~CBootProfilerSession();
void Start();
void Stop();
CBootProfilerRecord* StartBlock(const char* name, const char* args);
void StopBlock(CBootProfilerRecord* record);
void CollectResults(const char* filename, const float timeThreshold);
private:
string m_name;
CProfileInfo m_threadsProfileInfo[eMAX_THREADS_TO_PROFILE];
CRecordPool* m_threadsRecordsPool[eMAX_THREADS_TO_PROFILE]; //head
CRecordPool* m_threadsCurrentPools[eMAX_THREADS_TO_PROFILE]; //current
};
//////////////////////////////////////////////////////////////////////////
CBootProfilerSession::CBootProfilerSession()
{
memset(m_threadsProfileInfo, 0, sizeof(m_threadsProfileInfo));
memset(m_threadsRecordsPool, 0, sizeof(m_threadsRecordsPool));
memset(m_threadsCurrentPools, 0, sizeof(m_threadsCurrentPools));
}
CBootProfilerSession::~CBootProfilerSession()
{
for (unsigned int i = 0; i < m_threadCounter; ++i)
{
CProfileInfo& profile = m_threadsProfileInfo[i];
// Since m_pRoot is allocated using memory pool (line 296),
// its destructor is called explicitly to free the memory of
// m_Childs and each of its child.
if (profile.m_pRoot)
{
profile.m_pRoot->~CBootProfilerRecord();
}
delete m_threadsRecordsPool[i];
}
}
void CBootProfilerSession::Start()
{
LARGE_INTEGER time, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&time);
m_startTimeStamp = time;
m_freq = freq;
}
void CBootProfilerSession::Stop()
{
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
m_stopTimeStamp = time;
}
CBootProfilerRecord* CBootProfilerSession::StartBlock(const char* name, const char* args)
{
const unsigned int curThread = CryGetCurrentThreadId();
const unsigned int threadIndex = GetThreadIndexByID(curThread);
assert(threadIndex < eMAX_THREADS_TO_PROFILE);
CProfileInfo& profile = m_threadsProfileInfo[threadIndex];
CRecordPool* pool = m_threadsCurrentPools[threadIndex];
if (!profile.m_pRoot)
{
if (!pool)
{
pool = new CRecordPool;
m_threadsRecordsPool[threadIndex] = pool;
m_threadsCurrentPools[threadIndex] = pool;
}
CBootProfilerRecord* rec = pool->allocateRecord();
profile.m_pRoot = profile.m_pCurrent = new(rec)CBootProfilerRecord("root", m_startTimeStamp, m_freq, args);
}
assert(pool);
LARGE_INTEGER time, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&time);
CBootProfilerRecord* pParent = profile.m_pCurrent;
assert(pParent);
assert(profile.m_pRoot);
CBootProfilerRecord* rec = pool->allocateRecord();
if (!rec)
{
//pool is full, create a new one
pool = new CRecordPool;
m_threadsCurrentPools[threadIndex]->setNextPool(pool);
m_threadsCurrentPools[threadIndex] = pool;
rec = pool->allocateRecord();
}
profile.m_pCurrent = new(rec)CBootProfilerRecord(name, time, freq, args);
profile.m_pCurrent->m_pParent = pParent;
pParent->m_Childs.push_back(profile.m_pCurrent);
return profile.m_pCurrent;
}
void CBootProfilerSession::StopBlock(CBootProfilerRecord* record)
{
if (record)
{
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
record->m_stopTimeStamp = time;
unsigned int curThread = CryGetCurrentThreadId();
unsigned int threadIndex = GetThreadIndexByID(curThread);
assert(threadIndex < eMAX_THREADS_TO_PROFILE);
CProfileInfo& profile = m_threadsProfileInfo[threadIndex];
profile.m_pCurrent = record->m_pParent;
}
}
void CBootProfilerSession::CollectResults(const char* filename, const float timeThreshold)
{
if (!gEnv || !gEnv->pCryPak)
{
AZ_Warning("BootProfiler", false, "CryPak not set - skipping CollectResults");
return;
}
static const char* szTestResults = "@cache@\\TestResults";
string filePath = string(szTestResults) + "\\" + "bp_" + filename + ".xml";
char path[AZ::IO::IArchive::MaxPath] = "";
gEnv->pCryPak->AdjustFileName(filePath.c_str(), path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
gEnv->pCryPak->MakeDir(szTestResults);
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
gEnv->pFileIO->Open(path, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, fileHandle);
if (fileHandle == AZ::IO::InvalidHandle)
{
return;
}
char buf[512];
const unsigned int buf_size = sizeof(buf);
sprintf_s(buf, buf_size, "<root>\n");
AZ::IO::Print(fileHandle, buf);
const size_t numThreads = m_threadCounter;
for (size_t i = 0; i < numThreads; ++i)
{
CBootProfilerRecord* pRoot = m_threadsProfileInfo[i].m_pRoot;
if (pRoot)
{
pRoot->m_stopTimeStamp = m_stopTimeStamp;
const char* threadName = GetThreadNameByIndex(i);
if (!threadName)
{
threadName = "UNKNOWN";
}
const float time = (float)(pRoot->m_stopTimeStamp.QuadPart - pRoot->m_startTimeStamp.QuadPart) * 1000.f / (float)pRoot->m_freq.QuadPart;
sprintf_s(buf, buf_size, "\t<thread name=\"%s\" totalTimeMS=\"%f\" startTime=\"%" PRIu64 "\" stopTime=\"%" PRIu64 "\" > \n", threadName, time,
pRoot->m_startTimeStamp.QuadPart, pRoot->m_stopTimeStamp.QuadPart);
AZ::IO::Print(fileHandle, buf);
for (size_t recordIdx = 0; recordIdx < pRoot->m_Childs.size(); ++recordIdx)
{
CBootProfilerRecord* record = pRoot->m_Childs[recordIdx];
assert(record);
record->Print(fileHandle, buf, buf_size, 2, m_stopTimeStamp, threadName, timeThreshold);
}
sprintf_s(buf, buf_size, "\t</thread>\n");
AZ::IO::Print(fileHandle, buf);
}
}
sprintf_s(buf, buf_size, "</root>\n");
AZ::IO::Print(fileHandle, buf);
gEnv->pFileIO->Close(fileHandle);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CBootProfiler& CBootProfiler::GetInstance()
{
return gProfilerInstance;
}
CBootProfiler::CBootProfiler()
: m_pCurrentSession(NULL)
, m_pFrameRecord(NULL)
, m_levelLoadAdditionalFrames(0)
{
}
CBootProfiler::~CBootProfiler()
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
for (TSessionMap::iterator it = m_sessions.begin(); it != m_sessions.end(); ++it)
{
CBootProfilerSession* session = it->second;
delete session;
}
}
// start session
void CBootProfiler::StartSession(const char* sessionName)
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
TSessionMap::const_iterator it = m_sessions.find(sessionName);
if (it == m_sessions.end())
{
m_pCurrentSession = new CBootProfilerSession();
m_sessions[sessionName] = m_pCurrentSession;
m_pCurrentSession->Start();
}
}
// stop session
void CBootProfiler::StopSession(const char* sessionName)
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
if (m_pCurrentSession)
{
TSessionMap::iterator it = m_sessions.find(sessionName);
if (it != m_sessions.end())
{
if (m_pCurrentSession == it->second)
{
CBootProfilerSession* session = m_pCurrentSession;
m_pCurrentSession = NULL;
session->Stop();
session->CollectResults(sessionName, CV_sys_bp_time_threshold);
delete session;
}
m_sessions.erase(it);
}
}
}
CBootProfilerRecord* CBootProfiler::StartBlock(const char* name, const char* args)
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
if (m_pCurrentSession)
{
return m_pCurrentSession->StartBlock(name, args);
}
return NULL;
}
void CBootProfiler::StopBlock(CBootProfilerRecord* record)
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
if (m_pCurrentSession)
{
m_pCurrentSession->StopBlock(record);
}
}
void CBootProfiler::StartFrame(const char* name)
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
if (CV_sys_bp_frames)
{
StartSession("frames");
m_pFrameRecord = StartBlock(name, NULL);
}
}
void CBootProfiler::StopFrame()
{
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
if (m_pCurrentSession && CV_sys_bp_frames)
{
StopBlock(m_pFrameRecord);
m_pFrameRecord = NULL;
--CV_sys_bp_frames;
if (0 == CV_sys_bp_frames)
{
StopSession("frames");
}
}
if (m_pCurrentSession && m_levelLoadAdditionalFrames)
{
--m_levelLoadAdditionalFrames;
if (0 == m_levelLoadAdditionalFrames)
{
StopSession("level");
}
}
}
void CBootProfiler::Init(ISystem* pSystem)
{
//REGISTER_CVAR(sys_BootProfiler, 1, VF_DEV_ONLY,
// "Collect and output session statistics into TestResults/bp_(session_name).xml \n"
// "0 = Disabled\n"
// "1 = Enabled\n");
pSystem->GetISystemEventDispatcher()->RegisterListener(this);
StartSession("boot");
}
void CBootProfiler::RegisterCVars()
{
REGISTER_CVAR2("sys_bp_frames", &CV_sys_bp_frames, 0, VF_DEV_ONLY, "Starts frame profiling for specified number of frames using BootProfiler");
REGISTER_CVAR2("sys_bp_time_threshold", &CV_sys_bp_time_threshold, 0.1f, VF_DEV_ONLY, "If greater than 0 don't write blocks that took less time (default 0.1 ms)");
}
void CBootProfiler::OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
{
switch (event)
{
case ESYSTEM_EVENT_GAME_POST_INIT_DONE:
{
StopSession("boot");
break;
}
case ESYSTEM_EVENT_GAME_MODE_SWITCH_START:
{
break;
}
case ESYSTEM_EVENT_GAME_MODE_SWITCH_END:
{
break;
}
case ESYSTEM_EVENT_LEVEL_LOAD_START:
{
break;
}
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
{
StartSession("level");
break;
}
case ESYSTEM_EVENT_LEVEL_LOAD_END:
{
StopSession("level");
break;
}
case ESYSTEM_EVENT_LEVEL_PRECACHE_END:
{
//level loading can be stopped here, or m_levelLoadAdditionalFrames can be used to prolong dump for this amount of frames
//StopSession("level");
m_levelLoadAdditionalFrames = 20;
break;
}
}
}
void CBootProfiler::SetFrameCount(int frameCount)
{
CV_sys_bp_frames = frameCount;
}
#endif
-67
View File
@@ -1,67 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_BOOTPROFILER_H
#define CRYINCLUDE_CRYSYSTEM_BOOTPROFILER_H
#pragma once
#if defined(ENABLE_LOADING_PROFILER)
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/parallel/mutex.h>
class CBootProfilerRecord;
class CBootProfilerSession;
class CBootProfiler
: public ISystemEventListener
{
friend class CBootProfileBLock;
public:
CBootProfiler();
~CBootProfiler();
static CBootProfiler& GetInstance();
void Init(ISystem* pSystem);
void RegisterCVars();
void StartSession(const char* sessionName);
void StopSession(const char* sessionName);
CBootProfilerRecord* StartBlock(const char* name, const char* args);
void StopBlock(CBootProfilerRecord* record);
void StartFrame(const char* name);
void StopFrame();
protected:
// === ISystemEventListener
virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam);
void SetFrameCount(int frameCount);
private:
CBootProfilerSession* m_pCurrentSession;
typedef AZStd::unordered_map<AZStd::string, CBootProfilerSession*> TSessionMap;
TSessionMap m_sessions;
static int CV_sys_bp_frames;
static float CV_sys_bp_time_threshold;
CBootProfilerRecord* m_pFrameRecord;
AZStd::recursive_mutex m_recordMutex;
int m_levelLoadAdditionalFrames;
};
#endif
#endif // CRYINCLUDE_CRYSYSTEM_BOOTPROFILER_H
+1 -12
View File
@@ -277,17 +277,6 @@ int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode);
WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr);
if (CSystem* pSystem = (CSystem*)GetSystem())
{
if (const char* pLoadingProfilerCallstack = pSystem->GetLoadingProfilerCallstack())
{
if (pLoadingProfilerCallstack[0])
{
WriteLineToLog("<CrySystem> LoadingProfilerCallstack: %s", pLoadingProfilerCallstack);
}
}
}
{
IMemoryManager::SProcessMemInfo memInfo;
if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo))
@@ -593,7 +582,7 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
for (unsigned int i2 = 0; i2 < numFrames; ++i2)
{
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
}
}
}
+7 -11
View File
@@ -20,8 +20,8 @@
#include "System.h"
#include <AzFramework/IO/FileOperations.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
//#if !defined(LINUX)
#include <ISystem.h>
@@ -186,21 +186,17 @@ AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
}
}
if (gEnv->pConsole)
{
if (ICVar* pCVarGameDir = gEnv->pConsole->GetCVar("sys_game_folder"))
{
sprintf(s, "GameDir: %s\n", pCVarGameDir->GetString());
azstrcat(str, length, s);
}
}
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
azstrcat(str, length, "ProjectDir: ");
azstrcat(str, length, projectPath.c_str());
azstrcat(str, length, "\n");
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME
GetModuleFileNameA(NULL, s, sizeof(s));
// Log EXE filename only if possible (not full EXE path which could contain sensitive info)
AZStd::string exeName;
if (AzFramework::StringFunc::Path::GetFullFileName(s, exeName))
if (AZ::StringFunc::Path::GetFullFileName(s, exeName))
{
azstrcat(str, length, "Executable: ");
azstrcat(str, length, exeName.c_str());
@@ -1,647 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#if defined(ENABLE_LOADING_PROFILER)
#include "System.h"
#include "LoadingProfiler.h"
#define LOADING_TIME_CONTAINER_MAX_TEXT_SIZE 1024
#define MAX_LOADING_TIME_PROFILER_STACK_DEPTH 16
//#define SAVE_SAVELEVELSTATS_IN_ROOT
struct SLoadingTimeContainer
: public _i_reference_target_t
{
SLoadingTimeContainer() {}
SLoadingTimeContainer(SLoadingTimeContainer* pParent, const char* pPureFuncName, const int nRootIndex)
{
m_dSelfMemUsage = m_dTotalMemUsage = m_dSelfTime = m_dTotalTime = 0;
m_nCounter = 1;
m_pFuncName = pPureFuncName;
m_pParent = pParent;
m_nRootIndex = nRootIndex;
}
static int Cmp_SLoadingTimeContainer_Time(const void* v1, const void* v2)
{
SLoadingTimeContainer* pChunk1 = (SLoadingTimeContainer*)v1;
SLoadingTimeContainer* pChunk2 = (SLoadingTimeContainer*)v2;
if (pChunk1->m_dSelfTime > pChunk2->m_dSelfTime)
{
return -1;
}
else if (pChunk1->m_dSelfTime < pChunk2->m_dSelfTime)
{
return 1;
}
return 0;
}
static int Cmp_SLoadingTimeContainer_MemUsage(const void* v1, const void* v2)
{
SLoadingTimeContainer* pChunk1 = (SLoadingTimeContainer*)v1;
SLoadingTimeContainer* pChunk2 = (SLoadingTimeContainer*)v2;
if (pChunk1->m_dSelfMemUsage > pChunk2->m_dSelfMemUsage)
{
return -1;
}
else if (pChunk1->m_dSelfMemUsage < pChunk2->m_dSelfMemUsage)
{
return 1;
}
return 0;
}
static double GetUsedMemory(ISystem* pSysytem)
{
static IMemoryManager::SProcessMemInfo processMemInfo;
pSysytem->GetIMemoryManager()->GetProcessMemInfo(processMemInfo);
return double(processMemInfo.PagefileUsage) / double(1024 * 1024);
}
void Clear()
{
for (size_t i = 0, end = m_pChilds.size(); i < end; ++i)
{
delete m_pChilds[i];
}
}
~SLoadingTimeContainer()
{
Clear();
}
double m_dSelfTime, m_dTotalTime;
double m_dSelfMemUsage, m_dTotalMemUsage;
uint32 m_nCounter;
const char* m_pFuncName;
SLoadingTimeContainer* m_pParent;
int m_nRootIndex;
std::vector<SLoadingTimeContainer*> m_pChilds;
DiskOperationInfo m_selfInfo;
DiskOperationInfo m_totalInfo;
bool m_bUsed;
};
bool operator== (const SLoadingTimeContainer& a, const SLoadingTimeContainer& b)
{
return b.m_pFuncName == a.m_pFuncName;
}
bool operator== (const SLoadingTimeContainer& a, const char* b)
{
return b == a.m_pFuncName;
}
SLoadingTimeContainer* CLoadingProfilerSystem::m_pCurrentLoadingTimeContainer = 0;
SLoadingTimeContainer* CLoadingProfilerSystem::m_pRoot[2] = {0, 0};
int CLoadingProfilerSystem::m_iActiveRoot = 0;
ICVar* CLoadingProfilerSystem::m_pEnableProfile = 0;
int CLoadingProfilerSystem::nLoadingProfileMode = 1;
int CLoadingProfilerSystem::nLoadingProfilerNotTrackedAllocations = -1;
CryCriticalSection CLoadingProfilerSystem::csLock;
//////////////////////////////////////////////////////////////////////////
void CLoadingProfilerSystem::OutputLoadingTimeStats(ILog* pLog, int nMode)
{
nLoadingProfileMode = nMode;
PodArray<SLoadingTimeContainer> arrNoStack;
CreateNoStackList(arrNoStack);
if (nLoadingProfileMode > 0)
{ // loading mem stats per func
pLog->Log("------ Level loading memory allocations (MB) by function ------------");
pLog->Log(" ||Self | Total | Calls | Function (%d MB lost)||", nLoadingProfilerNotTrackedAllocations);
pLog->Log("---------------------------------------------------------------------");
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_MemUsage);
for (int i = 0; i < arrNoStack.Count(); i++)
{
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
pLog->Log("|%6.1f | %6.1f | %6d | %s|",
pTimeContainer->m_dSelfMemUsage, pTimeContainer->m_dTotalMemUsage, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
}
pLog->Log("---------------------------------------------------------------------");
}
if (nLoadingProfileMode > 0)
{ // loading time stats per func
pLog->Log("----------- Level loading time (sec) by function --------------------");
pLog->Log(" ||Self | Total | Calls | Function||");
pLog->Log("---------------------------------------------------------------------");
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
for (int i = 0; i < arrNoStack.Count(); i++)
{
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
pLog->Log("|%6.1f | %6.1f | %6d | %s|",
pTimeContainer->m_dSelfTime, pTimeContainer->m_dTotalTime, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
}
if (nLoadingProfileMode == 1)
{
pLog->Log("----- ( Use sys_ProfileLevelLoading 2 for more detailed stats ) -----");
}
else
{
pLog->Log("---------------------------------------------------------------------");
}
}
if (nLoadingProfileMode > 0)
{ // file info
pLog->Log("----------------------------- Level file information by function --------------------------------");
pLog->Log("|| Self | Total |Bandwith| Calls | Function||");
pLog->Log("|| Seeks |FileOpen|FileRead| Seeks |FileOpen|FileRead| Kb/s | | ||");
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
for (int i = 0; i < arrNoStack.Count(); i++)
{
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
double bandwidth = pTimeContainer->m_dSelfTime > 0 ? (pTimeContainer->m_selfInfo.m_dOperationSize / pTimeContainer->m_dSelfTime / 1024.0) : 0.;
pLog->Log("|%6d | %6d | %6d |%6d | %6d | %6d | %6.1f | %6d | %s|",
pTimeContainer->m_selfInfo.m_nSeeksCount, pTimeContainer->m_selfInfo.m_nFileOpenCount, pTimeContainer->m_selfInfo.m_nFileReadCount,
pTimeContainer->m_totalInfo.m_nSeeksCount, pTimeContainer->m_totalInfo.m_nFileOpenCount, pTimeContainer->m_totalInfo.m_nFileReadCount,
bandwidth, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
}
if (nLoadingProfileMode == 1)
{
pLog->Log("----- ( Use sys_ProfileLevelLoading 2 for more detailed stats ) -----");
}
else
{
pLog->Log("---------------------------------------------------------------------");
}
}
}
struct CSystemEventListner_LoadingProfiler
: public ISystemEventListener
{
private:
CLoadingTimeProfiler* m_pPrecacheProfiler;
ESystemEvent lastEvent;
public:
CSystemEventListner_LoadingProfiler()
: m_pPrecacheProfiler(NULL) {}
virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
{
switch (event)
{
case ESYSTEM_EVENT_GAME_MODE_SWITCH_START:
{
CLoadingProfilerSystem::Clean();
if (m_pPrecacheProfiler == NULL)
{
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "ModeSwitch");
}
break;
}
case ESYSTEM_EVENT_GAME_MODE_SWITCH_END:
{
SAFE_DELETE(m_pPrecacheProfiler);
CLoadingProfilerSystem::SaveTimeContainersToFile(gEnv->bMultiplayer == true ? "mode_switch_mp.lmbrlp" : "mode_switch_sp.lmbrlp", 0.0, true);
}
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
{
CLoadingProfilerSystem::Clean();
if (m_pPrecacheProfiler == NULL)
{
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "LevelLoading");
}
break;
}
case ESYSTEM_EVENT_LEVEL_LOAD_END:
{
delete m_pPrecacheProfiler;
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "Precache");
break;
}
case ESYSTEM_EVENT_LEVEL_PRECACHE_END:
{
if (lastEvent == ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME)
{
SAFE_DELETE(m_pPrecacheProfiler);
string levelName = "no_level";
ICVar* sv_map = gEnv->pConsole->GetCVar("sv_map");
if (sv_map)
{
levelName = sv_map->GetString();
}
string levelNameFullProfile = levelName + "_LP.lmbrlp";
string levelNameThreshold = levelName + "_LP_OneSec.lmbrlp";
CLoadingProfilerSystem::SaveTimeContainersToFile(levelNameFullProfile.c_str(), 0.0, false);
CLoadingProfilerSystem::SaveTimeContainersToFile(levelNameThreshold.c_str(), 1.0, true);
}
break;
}
case ESYSTEM_EVENT_LEVEL_POST_UNLOAD:
{
// Ensure that the precache profiler is dead
SAFE_DELETE(m_pPrecacheProfiler);
break;
}
}
if (event != ESYSTEM_EVENT_RANDOM_SEED)
{
lastEvent = event;
}
}
};
static CSystemEventListner_LoadingProfiler g_system_event_listener_loadingProfiler;
void CLoadingProfilerSystem::Init()
{
gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_loadingProfiler);
}
//////////////////////////////////////////////////////////////////////////
void CLoadingProfilerSystem::ShutDown()
{
if (gEnv && gEnv->pSystem && gEnv->pSystem->GetISystemEventDispatcher())
{
gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(&g_system_event_listener_loadingProfiler);
}
}
//////////////////////////////////////////////////////////////////////////
SLoadingTimeContainer* CLoadingProfilerSystem::StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName)
{
if (!nLoadingProfileMode || !gEnv->pConsole)
{
return NULL;
}
DWORD threadID = GetCurrentThreadId();
static DWORD dwMainThreadId = GetCurrentThreadId();
if (threadID != dwMainThreadId)
{
return NULL;
}
if (!m_pEnableProfile)
{
if (gEnv->pConsole)
{
m_pEnableProfile = gEnv->pConsole->GetCVar("sys_ProfileLevelLoading");
if (!m_pEnableProfile)
{
return 0;
}
}
else
{
return 0;
}
}
if (m_pEnableProfile->GetIVal() <= 0)
{
return 0;
}
//if (m_pCurrentLoadingTimeContainer == m_pRoot && strstr(szFuncName,"Open"))
//{
// pProfiler->m_constructorInfo.m_nFileOpenCount +=1;
//}
CryAutoCriticalSection lock(csLock);
if (true /*pProfiler && pProfiler->m_pSystem*/)
{
ITimer* pTimer = pProfiler->m_pSystem->GetITimer();
pProfiler->m_fConstructorTime = pTimer->GetAsyncTime().GetSeconds();
pProfiler->m_fConstructorMemUsage = SLoadingTimeContainer::GetUsedMemory(pProfiler->m_pSystem);
DiskOperationInfo info;
pProfiler->m_constructorInfo = info;
if (nLoadingProfilerNotTrackedAllocations < 0)
{
nLoadingProfilerNotTrackedAllocations = (int)pProfiler->m_fConstructorMemUsage;
}
}
SLoadingTimeContainer* pParent = m_pCurrentLoadingTimeContainer;
if (!pParent)
{
pParent = m_pCurrentLoadingTimeContainer = m_pRoot[m_iActiveRoot] = new SLoadingTimeContainer(0, "Root", m_iActiveRoot);
}
for (size_t i = 0, end = m_pCurrentLoadingTimeContainer->m_pChilds.size(); i < end; ++i)
{
if (m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_pFuncName == szFuncName)
{
assert(m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_pParent == m_pCurrentLoadingTimeContainer);
assert(!m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_bUsed);
m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_bUsed = true;
m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_nCounter++;
m_pCurrentLoadingTimeContainer = m_pCurrentLoadingTimeContainer->m_pChilds[i];
return m_pCurrentLoadingTimeContainer;
}
}
m_pCurrentLoadingTimeContainer = new SLoadingTimeContainer(pParent, szFuncName, pParent->m_nRootIndex);
m_pCurrentLoadingTimeContainer->m_bUsed = true;
{
// Need to iterate from the end than
pParent->m_pChilds.push_back(m_pCurrentLoadingTimeContainer);
}
return m_pCurrentLoadingTimeContainer;
}
void CLoadingProfilerSystem::EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler)
{
if (!nLoadingProfileMode)
{
return;
}
static DWORD dwMainThreadId = GetCurrentThreadId();
if (GetCurrentThreadId() != dwMainThreadId)
{
return;
}
if (!pProfiler->m_pTimeContainer)
{
return;
}
CryAutoCriticalSection lock(csLock);
if (true /*pProfiler && pProfiler->m_pSystem*/)
{
ITimer* pTimer = pProfiler->m_pSystem->GetITimer();
double fSelfTime = pTimer->GetAsyncTime().GetSeconds() - pProfiler->m_fConstructorTime;
double fMemUsage = SLoadingTimeContainer::GetUsedMemory(pProfiler->m_pSystem);
double fSelfMemUsage = fMemUsage - pProfiler->m_fConstructorMemUsage;
if (fSelfTime < 0.0)
{
assert(0);
}
pProfiler->m_pTimeContainer->m_dSelfTime += fSelfTime;
pProfiler->m_pTimeContainer->m_dTotalTime += fSelfTime;
pProfiler->m_pTimeContainer->m_dSelfMemUsage += fSelfMemUsage;
pProfiler->m_pTimeContainer->m_dTotalMemUsage += fSelfMemUsage;
DiskOperationInfo info;
info -= pProfiler->m_constructorInfo;
pProfiler->m_pTimeContainer->m_totalInfo += info;
pProfiler->m_pTimeContainer->m_selfInfo += info;
pProfiler->m_pTimeContainer->m_bUsed = false;
SLoadingTimeContainer* pParent = pProfiler->m_pTimeContainer->m_pParent;
pParent->m_selfInfo -= info;
pParent->m_dSelfTime -= fSelfTime;
pParent->m_dSelfMemUsage -= fSelfMemUsage;
if (pProfiler->m_pTimeContainer->m_pParent && pProfiler->m_pTimeContainer->m_pParent->m_nRootIndex == m_iActiveRoot)
{
m_pCurrentLoadingTimeContainer = pProfiler->m_pTimeContainer->m_pParent;
}
}
}
const char* CLoadingProfilerSystem::GetLoadingProfilerCallstack()
{
CryAutoCriticalSection lock(csLock);
static char szStack[1024];
szStack[0] = 0;
SLoadingTimeContainer* pC = m_pCurrentLoadingTimeContainer;
PodArray<SLoadingTimeContainer*> arrItems;
while (pC)
{
arrItems.Add(pC);
pC = pC->m_pParent;
}
for (int i = arrItems.Count() - 1; i >= 0; i--)
{
cry_strcat(szStack, " > ");
cry_strcat(szStack, arrItems[i]->m_pFuncName);
}
return &szStack[0];
}
void CLoadingProfilerSystem::FillProfilersList(AZStd::vector<SLoadingProfilerInfo>& profilers)
{
UpdateSelfStatistics(m_pRoot[m_iActiveRoot]);
PodArray<SLoadingTimeContainer> arrNoStack;
CreateNoStackList(arrNoStack);
//qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
uint32 count = arrNoStack.Size();
profilers.resize(count);
for (uint32 i = 0; i < count; ++i)
{
profilers[i].name = arrNoStack[i].m_pFuncName;
profilers[i].selfTime = arrNoStack[i].m_dSelfTime;
profilers[i].callsTotal = arrNoStack[i].m_nCounter;
profilers[i].totalTime = arrNoStack[i].m_dTotalTime;
profilers[i].memorySize = arrNoStack[i].m_dTotalMemUsage;
profilers[i].selfInfo = arrNoStack[i].m_selfInfo;
profilers[i].totalInfo = arrNoStack[i].m_totalInfo;
}
}
void CLoadingProfilerSystem::AddTimeContainerFunction(PodArray<SLoadingTimeContainer>& arrNoStack, SLoadingTimeContainer* node)
{
if (!node)
{
return;
}
SLoadingTimeContainer* it = std::find(arrNoStack.begin(), arrNoStack.end(), node->m_pFuncName);
if (it == arrNoStack.end())
{
arrNoStack.push_back(*node);
}
else
{
it->m_dSelfMemUsage += node->m_dSelfMemUsage;
it->m_dSelfTime += node->m_dSelfTime;
it->m_dTotalMemUsage += node->m_dTotalMemUsage;
it->m_dTotalTime += node->m_dTotalTime;
it->m_nCounter += node->m_nCounter;
it->m_selfInfo += node->m_selfInfo;
it->m_totalInfo += node->m_totalInfo;
}
for (size_t i = 0, end = node->m_pChilds.size(); i < end; ++i)
{
AddTimeContainerFunction(arrNoStack, node->m_pChilds[i]);
}
}
void CLoadingProfilerSystem::CreateNoStackList(PodArray<SLoadingTimeContainer>& arrNoStack)
{
AddTimeContainerFunction(arrNoStack, m_pRoot[m_iActiveRoot]);
}
#define g_szTestResults "@cache@\\TestResults"
void CLoadingProfilerSystem::SaveTimeContainersToFile(const char* name, double fMinTotalTime, bool bClean)
{
if (m_pRoot[m_iActiveRoot])
{
const char* levelName = name;
//Ignore any folders in the input name
const char* folder = strrchr(name, '/');
if (folder != NULL)
{
levelName = folder + 1;
}
char path[AZ::IO::IArchive::MaxPath];
path[sizeof(path) - 1] = 0;
gEnv->pCryPak->AdjustFileName(string(string(g_szTestResults) + "\\" + levelName).c_str(), path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
gEnv->pCryPak->MakeDir(g_szTestResults);
AZ::IO::HandleType handle = AZ::IO::InvalidHandle;
AZ::IO::Result f = AZ::IO::FileIOBase::GetInstance()->Open(path,AZ::IO::OpenMode::ModeWrite, handle);
if (handle != AZ::IO::InvalidHandle)
{
UpdateSelfStatistics(m_pRoot[m_iActiveRoot]);
WriteTimeContainerToFile(m_pRoot[m_iActiveRoot], handle, 0, fMinTotalTime);
AZ::IO::FileIOBase::GetInstance()->Close(handle);
}
if (bClean)
{
Clean();
}
}
}
void CLoadingProfilerSystem::WriteTimeContainerToFile(SLoadingTimeContainer* p, AZ::IO::HandleType &handle, unsigned int depth, double fMinTotalTime)
{
if (p == NULL)
{
return;
}
if (p->m_dTotalTime < fMinTotalTime)
{
return;
}
CryFixedStringT<MAX_LOADING_TIME_PROFILER_STACK_DEPTH> sDepth;
for (unsigned int i = 0; i < depth; i++)
{
sDepth += "\t";
}
CryFixedStringT<128> str(p->m_pFuncName);
str.replace(':', '_');
char data[4096];
AZ::u64 bytesWritten;
azsnprintf(data, sizeof(data), "%s<%s selfTime='%f' selfMemory='%f' totalTime='%f' totalMemory='%f' count='%i' totalSeeks='%i' totalReads='%i' totalOpens='%i' totalDiskSize='%f' selfSeeks='%i' selfReads='%i' selfOpens='%i' selfDiskSize='%f'>\n",
sDepth.c_str(), str.c_str(), p->m_dSelfTime, p->m_dSelfMemUsage, p->m_dTotalTime, p->m_dTotalMemUsage, p->m_nCounter,
p->m_totalInfo.m_nSeeksCount, p->m_totalInfo.m_nFileReadCount, p->m_totalInfo.m_nFileOpenCount, p->m_totalInfo.m_dOperationSize,
p->m_selfInfo.m_nSeeksCount, p->m_selfInfo.m_nFileReadCount, p->m_selfInfo.m_nFileOpenCount, p->m_selfInfo.m_dOperationSize);
AZ::IO::FileIOBase::GetInstance()->Write(handle, data, strlen(data), &bytesWritten);
for (size_t i = 0, end = p->m_pChilds.size(); i < end; ++i)
{
WriteTimeContainerToFile(p->m_pChilds[i], handle, depth + 1, fMinTotalTime);
}
azsnprintf(data, sizeof(data), "%s</%s>\n", sDepth.c_str(), str.c_str());
AZ::IO::FileIOBase::GetInstance()->Write(handle, data, strlen(data), &bytesWritten);
}
void CLoadingProfilerSystem::UpdateSelfStatistics(SLoadingTimeContainer* p)
{
if (p == NULL)
{
return;
}
p->m_dSelfMemUsage = 0;
p->m_dSelfTime = 0;
p->m_nCounter = 1;
p->m_selfInfo.m_dOperationSize = 0;
p->m_selfInfo.m_nFileOpenCount = 0;
p->m_selfInfo.m_nFileReadCount = 0;
p->m_selfInfo.m_nSeeksCount = 0;
for (size_t i = 0, end = p->m_pChilds.size(); i < end; ++i)
{
p->m_dTotalMemUsage += p->m_pChilds[i]->m_dTotalMemUsage;
p->m_dTotalTime += p->m_pChilds[i]->m_dTotalTime;
p->m_totalInfo += p->m_pChilds[i]->m_totalInfo;
}
}
void CLoadingProfilerSystem::Clean()
{
m_iActiveRoot = (m_iActiveRoot + 1) % 2;
if (m_pRoot[m_iActiveRoot])
{
delete m_pRoot[m_iActiveRoot];
}
m_pCurrentLoadingTimeContainer = m_pRoot[m_iActiveRoot] = 0;
}
#endif
@@ -1,69 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_LOADINGPROFILER_H
#define CRYINCLUDE_CRYSYSTEM_LOADINGPROFILER_H
#pragma once
#if defined(ENABLE_LOADING_PROFILER)
struct SLoadingTimeContainer;
struct SLoadingProfilerInfo
{
string name;
double selfTime;
double totalTime;
uint32 callsTotal;
double memorySize;
DiskOperationInfo selfInfo;
DiskOperationInfo totalInfo;
};
class CLoadingProfilerSystem
{
public:
static void Init();
static void ShutDown();
static void CreateNoStackList(PodArray<SLoadingTimeContainer>&);
static void OutputLoadingTimeStats(ILog* pLog, int nMode);
static SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName);
static void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler);
static const char* GetLoadingProfilerCallstack();
static void FillProfilersList(AZStd::vector<SLoadingProfilerInfo>& profilers);
static void FlushTimeContainers();
static void SaveTimeContainersToFile(const char*, double fMinTotalTime, bool bClean);
static void WriteTimeContainerToFile(SLoadingTimeContainer* p, AZ::IO::HandleType &handle, unsigned int depth, double fMinTotalTime);
static void UpdateSelfStatistics(SLoadingTimeContainer* p);
static void Clean();
protected:
static void AddTimeContainerFunction(PodArray<SLoadingTimeContainer>&, SLoadingTimeContainer*);
protected:
static int nLoadingProfileMode;
static int nLoadingProfilerNotTrackedAllocations;
static CryCriticalSection csLock;
static int m_iMaxArraySize;
static SLoadingTimeContainer* m_pCurrentLoadingTimeContainer;
static SLoadingTimeContainer* m_pRoot[2];
static int m_iActiveRoot;
static ICVar* m_pEnableProfile;
};
#endif
#endif // CRYINCLUDE_CRYSYSTEM_LOADINGPROFILER_H
@@ -16,6 +16,7 @@
#include <ISystem.h>
#include <AzCore/Socket/AzSocket.h>
#include <AzCore/Utils/Utils.h>
#undef LockDebug
//#define LockDebug(str1,str2) {string strMessage;strMessage.Format(str1,str2);if (m_clients.size()) OutputDebugString(strMessage.c_str());}
@@ -46,16 +47,13 @@ public:
const char* path = nullptr; // Don't call GetGameFolder here, it returns a full absolute path and we just really want the game name
if (ICVar* pVar = gEnv->pConsole->GetCVar("sys_game_folder"))
{
path = pVar->GetString();
}
if (!path)
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
if (projectPath.empty())
{
return;
}
pNotificationNetwork->Send("SystemInfo", path, ::strlen(path) + 1);
pNotificationNetwork->Send("SystemInfo", projectPath.c_str(), projectPath.size());
}
} g_queryNotification;
@@ -1243,7 +1243,7 @@ namespace
{
char path[AZ::IO::IArchive::MaxPath];
path[sizeof(path) - 1] = 0;
gEnv->pCryPak->AdjustFileName("@cache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
gEnv->pCryPak->AdjustFileName("@usercache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
sFileName = path;
}
AZ::IO::HandleType fileHandle = fxopen(sFileName, (bFirstTime) ? "wt" : "at");
+12 -28
View File
@@ -157,7 +157,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include "ServerThrottle.h"
#include "ILocalMemoryUsage.h"
#include "ResourceManager.h"
#include "LoadingProfiler.h"
#include "HMDBus.h"
#include "OverloadSceneManager/OverloadSceneManager.h"
#include <IThreadManager.h>
@@ -168,7 +167,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include "IZStdDecompressor.h"
#include "zlib.h"
#include "RemoteConsole/RemoteConsole.h"
#include "BootProfiler.h"
#include <PNoise3.h>
#include <StringUtils.h>
@@ -320,10 +318,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_bIsAsserting = false;
m_pSystemEventDispatcher = new CSystemEventDispatcher(); // Must be first.
#if defined(ENABLE_LOADING_PROFILER)
CBootProfiler::GetInstance().Init(this);
#endif
if (m_pSystemEventDispatcher)
{
m_pSystemEventDispatcher->RegisterListener(this);
@@ -422,7 +416,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
// m_sys_filecache = NULL;
m_gpu_particle_physics = NULL;
m_pCpu = NULL;
m_sys_game_folder = NULL;
m_bInitializedSuccessfully = false;
m_bShaderCacheGenMode = false;
@@ -634,10 +627,6 @@ void CSystem::ShutDown()
EBUS_EVENT(CrySystemEventBus, OnCrySystemShutdown, *this);
}
#if defined(ENABLE_LOADING_PROFILER)
CLoadingProfilerSystem::ShutDown();
#endif
if (m_pUserCallback)
{
m_pUserCallback->OnShutdown();
@@ -657,7 +646,7 @@ void CSystem::ShutDown()
SAFE_DELETE(m_pTextModeConsole);
KillPhysicsThread();
if (m_sys_firstlaunch)
{
m_sys_firstlaunch->Set("0");
@@ -828,7 +817,7 @@ void CSystem::ShutDown()
void CSystem::Quit()
{
CryLogAlways("CSystem::Quit invoked from thread %" PRI_THREADID " (main is %" PRI_THREADID ")", GetCurrentThreadId(), gEnv->mMainThreadId);
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop);
// If this was set from anywhere but the main thread, bail and let the main thread handle shutdown
@@ -857,13 +846,13 @@ void CSystem::Quit()
/*
* TODO: This call to _exit, _Exit, TerminateProcess etc. needs to
* eventually be removed. This causes an extremely early exit before we
* actually perform cleanup. When this gets called most managers are
* eventually be removed. This causes an extremely early exit before we
* actually perform cleanup. When this gets called most managers are
* simply never deleted and we leave it to the OS to clean up our mess
* which is just really bad practice. However there are LOTS of issues
* with shutdown at the moment. Removing this will simply cause
* a crash when either the Editor or Launcher initiate shutdown. Both
* applications crash differently too. Bugs will be logged about those
* with shutdown at the moment. Removing this will simply cause
* a crash when either the Editor or Launcher initiate shutdown. Both
* applications crash differently too. Bugs will be logged about those
* issues.
*/
#if defined(AZ_RESTRICTED_PLATFORM)
@@ -1117,7 +1106,7 @@ void CSystem::CreatePhysicsThread()
#include AZ_RESTRICTED_FILE(System_cpp)
#endif
{
{
m_PhysThread = new CPhysicsThreadTask;
GetIThreadTaskManager()->RegisterTask(m_PhysThread, threadParams);
}
@@ -1412,7 +1401,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
ti.xscale = ti.yscale = 1.2f;
const int viewportHeight = GetViewCamera().GetViewSurfaceZ();
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_8
#include AZ_RESTRICTED_FILE(System_cpp)
@@ -1428,7 +1417,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
switch (stat.GetType())
{
case AZ::IO::Statistic::Type::FloatingPoint:
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
AZStd::string::format("%s/%s: %.3f", stat.GetOwner().data(), stat.GetName().data(), stat.GetFloatValue()).c_str());
break;
case AZ::IO::Statistic::Type::Integer:
@@ -2744,10 +2733,10 @@ bool CSystem::HandleMessage([[maybe_unused]] HWND hWnd, UINT uMsg, WPARAM wParam
{
// System event translation
case WM_CLOSE:
/*
/*
Trigger CSystem to call Quit() the next time
it calls Update(). HandleMessages can get messages
pumped to it from SyncMainWithRender which would
pumped to it from SyncMainWithRender which would
be called recurively by Quit(). Doing so would
cause the render thread to deadlock and the main
thread to spin in SRenderThread::WaitFlushFinishedCond.
@@ -2897,11 +2886,6 @@ std::shared_ptr<AZ::IO::FileIOBase> CSystem::CreateLocalFileIO()
return std::make_shared<AZ::IO::LocalFileIO>();
}
const char* CSystem::GetAssetsPlatform() const
{
return m_assetPlatform.c_str();
}
IViewSystem* CSystem::GetIViewSystem()
{
return m_pViewSystem;
+3 -33
View File
@@ -45,7 +45,6 @@ struct IConsoleCmdArgs;
class CServerThrottle;
struct ICryFactoryRegistryImpl;
struct IZLibCompressor;
class CLoadingProfilerSystem;
class CWatchdogThread;
class CThreadManager;
@@ -437,11 +436,6 @@ public:
uint32 GetUsedMemory();
//! For asset processor, we need to know what kind of assets we're loading. This comes all the way from bootstrap.cfg
//! It will be a string like "pc" or "es3" or such and controls what kind of assets we have access to (its used when for example
//! attempting to open a file when multiple different assets for different platforms are available.)
const char* GetAssetsPlatform() const;
virtual void DumpMemoryUsageStatistics(bool bUseKB);
virtual void DumpMemoryCoverage();
void CollectMemInfo(SCryEngineStatsGlobalMemInfo&);
@@ -685,7 +679,7 @@ private:
bool InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams);
bool InitFont(const SSystemInitParams& initParams);
bool InitFileSystem(const SSystemInitParams& initParams);
bool InitFileSystem();
bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams);
bool InitStreamEngine();
bool Init3DEngine(const SSystemInitParams& initParams);
@@ -792,7 +786,7 @@ public:
const CTimeValue& GetLastTickTime(void) const { return m_lastTickTime; }
const ICVar* GetDedicatedMaxRate(void) const { return m_svDedicatedMaxRate; }
const char* GetRenderingDriverName(void) const
{
if(m_rDriver)
@@ -802,7 +796,7 @@ public:
return nullptr;
}
std::shared_ptr<AZ::IO::FileIOBase> CreateLocalFileIO();
// Gets the dimensions (in pixels) of the primary physical display.
@@ -914,7 +908,6 @@ private: // ------------------------------------------------------
// DLL names
ICVar* m_sys_dll_response_system;
ICVar* m_sys_game_folder;
#if !defined(_RELEASE)
ICVar* m_sys_resource_cache_folder;
#endif
@@ -950,7 +943,6 @@ private: // ------------------------------------------------------
ICVar* m_rFullscreenWindow;
ICVar* m_rFullscreenNativeRes;
ICVar* m_rDriver;
ICVar* m_cvGameName;
ICVar* m_rDisplayInfo;
ICVar* m_rOverscanBordersDrawDebugView;
ICVar* m_sysNoUpdate;
@@ -1040,8 +1032,6 @@ private: // ------------------------------------------------------
uint64 m_nUpdateCounter;
int sys_ProfileLevelLoading, sys_ProfileLevelLoadingDump;
bool m_executedCommandLine = false;
AZStd::unique_ptr<AzFramework::MissingAssetLogger> m_missingAssetLogger;
@@ -1072,18 +1062,6 @@ public:
void CloseLanguageAudioPak(const char* sLanguage);
void UpdateMovieSystem(const int updateFlags, const float fFrameTime, const bool bPreUpdate);
// level loading profiling
virtual void OutputLoadingTimeStats();
virtual struct SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName);
virtual void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler);
virtual const char* GetLoadingProfilerCallstack();
//////////////////////////////////////////////////////////////////////////
virtual CBootProfilerRecord* StartBootSectionProfiler(const char* name, const char* args);
virtual void StopBootSectionProfiler(CBootProfilerRecord* record);
virtual void StartBootProfilerSessionFrames(const char* pName);
virtual void StopBootProfilerSessionFrames();
//////////////////////////////////////////////////////////////////////////
// CryAssert and error related.
virtual bool RegisterErrorObserver(IErrorObserver* errorObserver);
@@ -1139,17 +1117,9 @@ protected: // -------------------------------------------------------------
ITextModeConsole* m_pTextModeConsole;
INotificationNetwork* m_pNotificationNetwork;
string m_binariesDir;
string m_currentLanguageAudio;
string m_assetPlatform; // ("es3" / "pc" / etc) describes the KIND of assets we load and controls where they're loaded from
string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg
// the following variables capture what was set up in the systeminitparams after/during InitFileSystem
// They are not actually to be used except to establish aliases like @user@
string m_userRootDir;
string m_cacheDir;
string m_logsDir;
std::vector< std::pair<CTimeValue, float> > m_updateTimes;
CMemoryFragmentationProfiler m_MemoryFragmentationProfiler;
+3 -9
View File
@@ -23,6 +23,7 @@
#include <AzCore/Console/IConsole.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include "SystemCFG.h"
@@ -252,15 +253,8 @@ void CSystem::LogVersion()
//////////////////////////////////////////////////////////////////////////
void CSystem::LogBuildInfo()
{
ICVar* pGameName = m_env.pConsole->GetCVar("sys_game_name");
if (pGameName)
{
CryLogAlways("GameName: %s", pGameName->GetString());
}
else
{
CryLogAlways("Couldn't find game name in cvar sys_game_name");
}
auto projectName = AZ::Utils::GetProjectName();
CryLogAlways("GameName: %s", projectName.c_str());
CryLogAlways("BuildTime: " __DATE__ " " __TIME__);
}
+44 -297
View File
@@ -68,6 +68,7 @@
#include <LoadScreenBus.h>
#include <LyShine/Bus/UiSystemBus.h>
#include <AzFramework/Logging/MissingAssetLogger.h>
#include <AzFramework/Platform/PlatformDefaults.h>
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Utils/Utils.h>
@@ -115,8 +116,6 @@
#include "SystemCFG.h"
#include "AutoDetectSpec.h"
#include "ResourceManager.h"
#include "LoadingProfiler.h"
#include "BootProfiler.h"
#include "VisRegTest.h"
#include "MTSafeAllocator.h"
#include "NotificationNetwork.h"
@@ -498,7 +497,7 @@ struct SysSpecOverrideSinkConsole
else
{
// If the cvar doesn't exist, calling this function only saves the value in case it's registered later where
// at that point it will be set from the stored value. This is required because otherwise registering the
// at that point it will be set from the stored value. This is required because otherwise registering the
// cvar bypasses any callbacks and uses values directly from the cvar group files.
gEnv->pConsole->LoadConfigVar(szKey, szValue);
}
@@ -618,13 +617,13 @@ static void LoadDetectedSpec(ICVar* pVar)
if (gEnv->IsEditor())
{
ESystemConfigPlatform configPlatform = GetISystem()->GetConfigPlatform();
// Check if the config platform is set first.
// Check if the config platform is set first.
if (configPlatform != CONFIG_INVALID_PLATFORM)
{
platform = configPlatform;
}
}
AZStd::string configFile;
GetSpecConfigFileToLoad(pVar, configFile, platform);
if (configFile.length())
@@ -779,7 +778,7 @@ static void LoadDetectedSpec(ICVar* pVar)
MobileSysInspect::GetSpecForGPUAndAPI(adapterDesc, apiver, gpuConfigFile);
GetISystem()->LoadConfiguration(gpuConfigFile.c_str(), pSysSpecOverrideSinkConsole);
}
#endif
#endif
}
if (bMultiGPUEnabled)
{
@@ -832,23 +831,7 @@ AZStd::unique_ptr<AZ::DynamicModuleHandle> CSystem::LoadDynamiclibrary(const cha
{
AZStd::unique_ptr<AZ::DynamicModuleHandle> handle = AZ::DynamicModuleHandle::Create(dllName);
bool libraryLoaded = false;
#ifdef WIN32
if (m_binariesDir.empty())
{
libraryLoaded = handle->Load(false);
}
else
{
char currentDirectory[1024];
AZ::Utils::GetExecutableDirectory(currentDirectory, AZ_ARRAY_SIZE(currentDirectory));
SetCurrentDirectory(m_binariesDir.c_str());
libraryLoaded = handle->Load(false);
SetCurrentDirectory(currentDirectory);
}
#else
libraryLoaded = handle->Load(false);
#endif
bool libraryLoaded = handle->Load(false);
// We need to inject the environment first thing so that allocators are available immediately
InjectEnvironmentFunction injectEnv = handle->GetFunction<InjectEnvironmentFunction>(INJECT_ENVIRONMENT_FUNCTION);
if (injectEnv)
@@ -974,7 +957,7 @@ bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClas
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
#else
dllfile.append(dllName);
@@ -1007,7 +990,7 @@ bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClas
if (CryCreateClassInstance(moduleClassName, pModule))
{
bResult = pModule->Initialize(m_env, initParams);
// After initializing the module, give it a chance to register any AZ console vars
// declared within the module.
pModule->RegisterConsoleVars();
@@ -1453,7 +1436,7 @@ bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInit
displayWidth *= scaleFactor;
displayHeight *= scaleFactor;
const int maxWidth = m_rMaxWidth->GetIVal();
if (maxWidth > 0 && maxWidth < displayWidth)
{
@@ -1524,7 +1507,7 @@ bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInit
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitFileSystem(const SSystemInitParams& initParams)
bool CSystem::InitFileSystem()
{
LOADING_TIME_PROFILE_SECTION;
using namespace AzFramework::AssetSystem;
@@ -1549,136 +1532,6 @@ bool CSystem::InitFileSystem(const SSystemInitParams& initParams)
}
#endif // !defined(_RELEASE)
bool usingAssetCache = initParams.UseAssetCache();
const char* rootPath = usingAssetCache ? initParams.rootPathCache : initParams.rootPath;
const char* assetsPath = usingAssetCache ? initParams.assetsPathCache : initParams.assetsPath;
if (rootPath == 0)
{
AZ_Assert(false, "No root path specified in SystemInitParams");
return false;
}
if (assetsPath == 0)
{
AZ_Assert(false, "No assets path specified in SystemInitParams");
return false;
}
// establish the root folder and assets folder immediately.
// Other folders that can be computed from the root can be specified later.
m_env.pFileIO->SetAlias("@root@", rootPath);
m_env.pFileIO->SetAlias("@assets@", assetsPath);
if (initParams.userPath[0] == 0)
{
string outPath = PathUtil::Make(m_env.pFileIO->GetAlias("@root@"), "user");
m_env.pFileIO->SetAlias("@user@", outPath.c_str());
}
else
{
m_env.pFileIO->SetAlias("@user@", initParams.userPath);
}
if (initParams.logPath[0] == 0)
{
char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 };
m_env.pFileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN);
string outPath = PathUtil::Make(resolveBuffer, "log");
m_env.pFileIO->SetAlias("@log@", outPath.c_str());
}
else
{
m_env.pFileIO->SetAlias("@log@", initParams.logPath);
}
m_env.pFileIO->CreatePath("@root@");
m_env.pFileIO->CreatePath("@user@");
m_env.pFileIO->CreatePath("@log@");
if ((!m_env.IsInToolMode()) || (m_bShaderCacheGenMode)) // in tool mode, the promise is that you won't access @cache@!
{
string finalCachePath;
if (initParams.cachePath[0] == 0)
{
char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 };
m_env.pFileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN);
finalCachePath = PathUtil::Make(resolveBuffer, "cache");
}
else
{
finalCachePath = initParams.cachePath;
}
#if defined(AZ_PLATFORM_WINDOWS)
// Search for a non-locked cache directory because shaders require separate caches for each running instance.
// We only need to do this check for Windows, because consoles can't have multiple instances running simultaneously.
// Ex: running editor and game, running multiple games, or multiple non-interactive editor instances
// for parallel level exports.
string originalPath = finalCachePath;
#if defined(REMOTE_ASSET_PROCESSOR)
bool allowEngineConnection = !initParams.bToolMode && !initParams.bTestMode;
bool allowRemoteIO = allowEngineConnection && initParams.remoteFileIO && !initParams.bEditor;
if (!allowRemoteIO) // not running on VFS
#endif
{
int attemptNumber = 0;
// The number of max attempts ultimately dictates the number of Lumberyard instances that can run
// simultaneously. This should be a reasonably high number so that it doesn't artificially limit
// the number of instances (ex: parallel level exports via multiple Editor runs). It also shouldn't
// be set *infinitely* high - each cache folder is GBs in size, and finding a free directory is a
// linear search, so the more instances we allow, the longer the search will take.
// 128 seems like a reasonable compromise.
constexpr int maxAttempts = 128;
char workBuffer[AZ_MAX_PATH_LEN] = { 0 };
while (attemptNumber < maxAttempts)
{
finalCachePath = originalPath;
if (attemptNumber != 0)
{
azsnprintf(workBuffer, AZ_MAX_PATH_LEN, "%s%i", originalPath.c_str(), attemptNumber);
finalCachePath = workBuffer;
}
else
{
finalCachePath = originalPath;
}
++attemptNumber; // do this here so we don't forget
m_env.pFileIO->CreatePath(finalCachePath.c_str());
// if the directory already exists, check for locked file
string outLockPath = PathUtil::Make(finalCachePath.c_str(), "lockfile.txt");
// note, the zero here after GENERIC_READ|GENERIC_WRITE indicates no share access at all
g_cacheLock = CreateFileA(outLockPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
if (g_cacheLock != INVALID_HANDLE_VALUE)
{
break;
}
}
if (attemptNumber >= maxAttempts)
{
AZ_Assert(false, "Couldn't find a valid asset cache folder for the Asset Processor after %i attempts.", attemptNumber);
AZ_Printf("FileSystem", "Couldn't find a valid asset cache folder for the Asset Processor after %i attempts.", attemptNumber);
return false;
}
}
#endif // defined(AZ_PLATFORM_WINDOWS)
AZ_Printf("FileSystem", "Using %s folder for asset cache.\n", finalCachePath.c_str());
m_env.pFileIO->SetAlias("@cache@", finalCachePath.c_str());
m_env.pFileIO->CreatePath("@cache@");
}
m_env.pCryPak = AZ::Interface<AZ::IO::IArchive>::Get();
m_env.pFileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(m_env.pCryPak, "CryPak has not been initialized on AZ::Interface");
@@ -1755,7 +1608,6 @@ void CSystem::ShutdownFileSystem()
bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION;
// Load value of sys_game_folder from system.cfg into the sys_game_folder console variable
{
ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink();
LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink);
@@ -1767,17 +1619,19 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initPara
#endif
GetISystem()->SetConfigPlatform(GetDevicePlatform());
#if defined(CRY_ENABLE_RC_HELPER)
if (!m_env.pResourceCompilerHelper)
{
m_env.pResourceCompilerHelper = new CResourceCompilerHelper();
}
#endif
// you may not set these in game.cfg or in system.cfg
m_sys_game_folder->ForceSet(initParams.gameFolderName);
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "GameDir: %s\n", m_sys_game_folder->GetString());
auto projectPath = AZ::Utils::GetProjectPath();
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Path: %s\n", projectPath.empty() ? "None specified" : projectPath.c_str());
auto projectName = AZ::Utils::GetProjectName();
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Name: %s\n", projectName.empty() ? "None specified" : projectName.c_str());
// simply open all paks if fast load pak can't be found
if (!m_pResourceManager->LoadFastLoadPaks(true))
@@ -1857,7 +1711,7 @@ bool CSystem::InitFont(const SSystemInitParams& initParams)
bool CSystem::Init3DEngine(const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
if (!InitializeEngineModule(DLL_3DENGINE, "EngineModule_Cry3DEngine", initParams))
{
return false;
@@ -1930,7 +1784,7 @@ bool CSystem::InitVTuneProfiler()
LOADING_TIME_PROFILE_SECTION(GetISystem());
#ifdef PROFILE_WITH_VTUNE
WIN_HMODULE hModule = LoadDLL("VTuneApi.dll");
if (!hModule)
{
@@ -2033,7 +1887,7 @@ void CSystem::OpenBasicPaks()
bBasicPaksLoaded = true;
LOADING_TIME_PROFILE_SECTION;
// open pak files
constexpr AZStd::string_view paksFolder = "@assets@/*.pak"; // (@assets@ assumed)
m_env.pCryPak->OpenPacks(paksFolder);
@@ -2188,12 +2042,6 @@ string GetUniqueLogFileName(string logFileName)
}
void OnLevelLoadingDump([[maybe_unused]] ICVar* pArgs)
{
gEnv->pSystem->OutputLoadingTimeStats();
}
#if defined(WIN32) || defined(WIN64)
static wstring GetErrorStringUnsupportedCPU()
{
@@ -2415,8 +2263,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
signal(SIGILL, CryEngineSignalHandler);
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
// initialized to this instance's SSystemGlobalEnvironment (m_env), we will force set it again here
// to m_env
if (!gEnv)
@@ -2451,7 +2299,7 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
// Linux is all console for now and so no room for dialog boxes!
m_env.bNoAssertDialog = true;
#endif
m_pCmdLine = new CCmdLine(startupParams.szSystemCmdLine);
AZCoreLogSink::Connect();
@@ -2461,25 +2309,25 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
{
azConsole->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
}
m_assetPlatform = startupParams.assetsPlatform;
// compute system config name
if (m_assetPlatform.empty())
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry)
{
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
R"(This can be set via the via the --regset "%s/assets=<value>" command line option)"
R"(, by setting value at the "%s/assets path" within a *.setreg file that is loaded by the application)"
R"( or by setting the "assets" field in the bootstrap.cfg.)",
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
return false;
}
AZ::SettingsRegistryInterface::FixedValueString assetPlatform;
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, assetPlatform,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "assets"))
{
assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
R"(This typically done by setting he "assets" field in the bootstrap.cfg for within a .setreg file)""\n"
R"(A fallback of %s will be used.)",
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
assetPlatform.c_str());
}
m_systemConfigName = "system_" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_";
m_systemConfigName += m_assetPlatform;
m_systemConfigName += ".cfg";
m_systemConfigName = "system_" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_";
m_systemConfigName += assetPlatform.c_str();
m_systemConfigName += ".cfg";
}
AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit.");
@@ -2518,11 +2366,6 @@ AZ_POP_DISABLE_WARNING
m_hInst = (WIN_HINSTANCE)startupParams.hInstance;
m_hWnd = (WIN_HWND)startupParams.hWnd;
m_userRootDir = startupParams.userPath;
m_logsDir = startupParams.logPath;
m_cacheDir = startupParams.cachePath;
m_binariesDir = startupParams.szBinariesDir;
m_bEditor = startupParams.bEditor;
m_bPreviewMode = startupParams.bPreview;
m_bTestMode = startupParams.bTestMode;
@@ -2666,17 +2509,13 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// File system, must be very early
//////////////////////////////////////////////////////////////////////////
if (!InitFileSystem(startupParams))
if (!InitFileSystem())
{
return false;
}
//////////////////////////////////////////////////////////////////////////
InlineInitializationProcessing("CSystem::Init InitFileSystem");
#if defined(ENABLE_LOADING_PROFILER)
CLoadingProfilerSystem::Init();
#endif
m_missingAssetLogger = AZStd::make_unique<AzFramework::MissingAssetLogger>();
//////////////////////////////////////////////////////////////////////////
@@ -2786,10 +2625,6 @@ AZ_POP_DISABLE_WARNING
GetIRemoteConsole()->RegisterConsoleVariables();
#ifdef ENABLE_LOADING_PROFILER
CBootProfiler::GetInstance().RegisterCVars();
#endif
if (!startupParams.bSkipConsole)
{
// Register system console variables.
@@ -2827,7 +2662,7 @@ AZ_POP_DISABLE_WARNING
m_env.pCryPak->OpenPack("@assets@", "Engine.pak");
#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS)
MobileSysInspect::LoadDeviceSpecMapping();
#endif
#endif
InitFileSystem_LoadEngineFolders(startupParams);
@@ -3472,10 +3307,6 @@ AZ_POP_DISABLE_WARNING
MarkThisThreadForDebugging("Main");
}
#if defined(ENABLE_LOADING_PROFILER)
CLoadingProfilerSystem::SaveTimeContainersToFile("EngineStart.crylp", 0.0, true);
#endif
InlineInitializationProcessing("CSystem::Init End");
#if defined(IS_PROSDK)
@@ -4188,7 +4019,7 @@ static void ScreenshotCmd(IConsoleCmdArgs* pParams)
}
}
// Helper to maintain backwards compatibility with our CVar but not force our new code to
// Helper to maintain backwards compatibility with our CVar but not force our new code to
// pull in CryCommon by routing through an environment variable
void CmdSetAwsLogLevel(IConsoleCmdArgs* pArgs)
{
@@ -4424,7 +4255,6 @@ void CSystem::CreateSystemVars()
// Register DLL names as cvars before we load them
//
EVarFlags dllFlags = (EVarFlags)0;
m_sys_game_folder = REGISTER_STRING("sys_game_folder", "EmptyTemplate", VF_READONLY, "Specifies the game folder to read all data from. Can be fully pathed for external folders or relative path for folders inside the root.");
m_sys_dll_response_system = REGISTER_STRING("sys_dll_response_system", 0, dllFlags, "Specifies the DLL to load for the dynamic response system");
m_sys_initpreloadpacks = REGISTER_STRING("sys_initpreloadpacks", "", 0, "Specifies the paks for an engine initialization");
@@ -4447,8 +4277,6 @@ void CSystem::CreateSystemVars()
m_level_load_screen_minimum_time = REGISTER_FLOAT("level_load_screen_minimum_time", 0.0f, 0, "Minimum amount of time to show the level load screen. Important to prevent short loads from flashing the load screen. 0 means there is no limit.");
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
m_cvGameName = REGISTER_STRING("sys_game_name", "Lumberyard", VF_DUMPTODISK, "Specifies the name to be displayed in the Launcher window title bar");
REGISTER_INT("cvDoVerboseWindowTitle", 0, VF_NULL, "");
m_pCVarQuit = REGISTER_INT("ExitOnQuit", 1, VF_NULL, "");
@@ -4495,7 +4323,7 @@ void CSystem::CreateSystemVars()
}
#endif
attachVariable("sys_PakReadSlice", &g_cvars.archiveVars.nReadSlice, "If non-0, means number of kilobytes to use to read files in portions. Should only be used on Win9x kernels");
attachVariable("sys_PakInMemorySizeLimit", &g_cvars.archiveVars.nInMemoryPerPakSizeLimit, "Individual pak size limit for being loaded into memory (MB)");
@@ -4818,15 +4646,6 @@ void CSystem::CreateSystemVars()
"e.g. LoadConfig lowspec.cfg\n"
"Usage: LoadConfig <filename>");
REGISTER_CVAR(sys_ProfileLevelLoading, 0, VF_CHEAT,
"Output level loading stats into log\n"
"0 = Off\n"
"1 = Output basic info about loading time per function\n"
"2 = Output full statistics including loading time and memory allocations with call stack info");
REGISTER_CVAR_CB(sys_ProfileLevelLoadingDump, 0, VF_CHEAT, "Output level loading dump stats into log\n", OnLevelLoadingDump);
assert(m_env.pConsole);
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot");
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip");
@@ -4871,7 +4690,7 @@ void CSystem::CreateSystemVars()
// adding CVAR to toggle assert verbosity level
const int defaultAssertValue = 1;
REGISTER_CVAR2_CB("sys_asserts", &g_cvars.sys_asserts, defaultAssertValue, VF_CHEAT,
REGISTER_CVAR2_CB("sys_asserts", &g_cvars.sys_asserts, defaultAssertValue, VF_CHEAT,
"0 = Suppress Asserts\n"
"1 = Log Asserts\n"
"2 = Show Assert Dialog\n"
@@ -4957,78 +4776,6 @@ void CSystem::AddCVarGroupDirectory(const string& sPath)
gEnv->pCryPak->FindClose(handle);
}
void CSystem::OutputLoadingTimeStats()
{
#if defined(ENABLE_LOADING_PROFILER)
if (GetIConsole())
{
if (ICVar* pVar = GetIConsole()->GetCVar("sys_ProfileLevelLoading"))
{
CLoadingProfilerSystem::OutputLoadingTimeStats(GetILog(), pVar->GetIVal());
}
}
#endif
}
SLoadingTimeContainer* CSystem::StartLoadingSectionProfiling([[maybe_unused]] CLoadingTimeProfiler* pProfiler, [[maybe_unused]] const char* szFuncName)
{
#if defined(ENABLE_LOADING_PROFILER)
return CLoadingProfilerSystem::StartLoadingSectionProfiling(pProfiler, szFuncName);
#else
return 0;
#endif
}
void CSystem::EndLoadingSectionProfiling([[maybe_unused]] CLoadingTimeProfiler* pProfiler)
{
#if defined(ENABLE_LOADING_PROFILER)
CLoadingProfilerSystem::EndLoadingSectionProfiling(pProfiler);
#endif
}
const char* CSystem::GetLoadingProfilerCallstack()
{
#if defined(ENABLE_LOADING_PROFILER)
return CLoadingProfilerSystem::GetLoadingProfilerCallstack();
#else
return nullptr;
#endif
}
CBootProfilerRecord* CSystem::StartBootSectionProfiler([[maybe_unused]] const char* name, [[maybe_unused]] const char* args)
{
#if defined(ENABLE_LOADING_PROFILER)
CBootProfiler& profiler = CBootProfiler::GetInstance();
return profiler.StartBlock(name, args);
#else
return nullptr;
#endif
}
void CSystem::StopBootSectionProfiler([[maybe_unused]] CBootProfilerRecord* record)
{
#if defined(ENABLE_LOADING_PROFILER)
CBootProfiler& profiler = CBootProfiler::GetInstance();
profiler.StopBlock(record);
#endif
}
void CSystem::StartBootProfilerSessionFrames([[maybe_unused]] const char* pName)
{
#if defined(ENABLE_LOADING_PROFILER)
CBootProfiler& profiler = CBootProfiler::GetInstance();
profiler.StartFrame(pName);
#endif
}
void CSystem::StopBootProfilerSessionFrames()
{
#if defined(ENABLE_LOADING_PROFILER)
CBootProfiler& profiler = CBootProfiler::GetInstance();
profiler.StopFrame();
#endif
}
bool CSystem::RegisterErrorObserver(IErrorObserver* errorObserver)
{
return stl::push_back_unique(m_errorObservers, errorObserver);
-15
View File
@@ -92,13 +92,6 @@ static AZStd::vector<AZStd::string> GetModuleNames()
moduleNames.push_back("CryFont" MODULE_EXTENSION);
moduleNames.push_back("CrySystem" MODULE_EXTENSION);
if (gEnv && gEnv->pConsole)
{
string gameModuleNameRaw = gEnv->pConsole->GetCVar("sys_dll_game")->GetString();
gameModuleNameRaw.append(MODULE_EXTENSION);
moduleNames.push_back(gameModuleNameRaw.c_str());
}
#undef MODULE_EXTENSION
# if defined(LINUX)
@@ -1076,14 +1069,6 @@ void CSystem::FatalError(const char* format, ...)
CryLogAlways("<CrySystem> Last System Error: %s", szSysErrorMessage);
}
if (const char* pLoadingProfilerCallstack = GetLoadingProfilerCallstack())
{
if (pLoadingProfilerCallstack[0])
{
CryLogAlways("<CrySystem> LoadingProfilerCallstack: %s", pLoadingProfilerCallstack);
}
}
if (GetUserCallback())
{
GetUserCallback()->OnError(szBuffer);
@@ -1,115 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "CrySystem_precompiled.h"
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/UnitTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Memory/AllocatorScope.h>
#include <AzCore/std/string/string.h>
#include <BootProfiler.h>
#if defined(ENABLE_LOADING_PROFILER)
namespace UnitTests
{
using BootProfilerTestAllocatorScope = AZ::AllocatorScope<AZ::LegacyAllocator, CryStringAllocator>;
class BootProfilerTest :
public ::testing::Test,
BootProfilerTestAllocatorScope,
UnitTest::TraceBusRedirector
{
public:
BootProfilerTest()
{
BootProfilerTestAllocatorScope::ActivateAllocators();
UnitTest::TraceBusRedirector::BusConnect();
}
~BootProfilerTest()
{
UnitTest::TraceBusRedirector::BusDisconnect();
BootProfilerTestAllocatorScope::DeactivateAllocators();
}
void SetUp() override
{
}
void TearDown() override
{
}
};
TEST_F(BootProfilerTest, BootProfilerTest_StartStopBlocksInThreads_Success)
{
CBootProfiler testProfiler;
const char scopeName[] = "TestScope";
const char blockArg[] = "TestArg";
const int numAttempts = 1000;
const int numThreads = 10;
auto switchSessionFunc = [&]() {
for (int sessionNum = 0; sessionNum < numAttempts; ++sessionNum)
{
auto sessionName = AZStd::string::format("TestSession%d", sessionNum);
testProfiler.StartSession(sessionName.c_str());
testProfiler.StopSession(sessionName.c_str());
}
};
auto testProfileFunc = [&]() {
for (int blockNum = 0; blockNum < numAttempts; ++blockNum)
{
auto someBlock = testProfiler.StartBlock(scopeName, blockArg);
testProfiler.StopBlock(someBlock);
}
};
AZStd::thread threadArray[numThreads];
AZStd::thread sessionThread = AZStd::thread(switchSessionFunc);
for (int i = 0; i < numThreads; ++i)
{
threadArray[i] = AZStd::thread(testProfileFunc);
}
for (int i = 0; i < numThreads; ++i)
{
threadArray[i].join();
}
sessionThread.join();
}
class FrameTestBootProfiler : public CBootProfiler
{
public:
FrameTestBootProfiler(int frameCount) : CBootProfiler()
{
SetFrameCount(frameCount);
}
};
TEST_F(BootProfilerTest, BootProfilerTest_FrameStartStop_Success)
{
const int numTestFrames = 10;
FrameTestBootProfiler testProfiler(numTestFrames);
for (int i = 0; i < numTestFrames; ++i)
{
testProfiler.StartFrame("TestFrame");
testProfiler.StopFrame();
}
}
} // namespace UnitTests
#endif
@@ -75,15 +75,10 @@ TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestPrefixes)
TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestGameName)
{
char tempBuffer[AZ_MAX_PATH_LEN];
ICVar* pGameNameCVar = nullptr;
if ((gEnv)&&(gEnv->pConsole))
{
pGameNameCVar = gEnv->pConsole->GetCVar("sys_game_folder");
}
azsnprintf(tempBuffer, AZ_MAX_PATH_LEN, ".\\%s\\materials\\blahblah.mat.mat.abc.test", pGameNameCVar ? pGameNameCVar->GetString() : "SamplesProject");
auto projectName = AZ::Utils::GetProjectName();
azsnprintf(tempBuffer, AZ_MAX_PATH_LEN, ".\\%s\\materials\\blahblah.mat.mat.abc.test", projectName.c_str());
MaterialUtils::UnifyMaterialName(tempBuffer);
EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0);
}
}
@@ -60,7 +60,7 @@ namespace CryPakUnitTests
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
ASSERT_NE(nullptr, fileIo);
constexpr const char* testPakPath = "@cache@/archivecontainerlevel.pak";
constexpr const char* testPakPath = "@usercache@/archivecontainerlevel.pak";
char resolvedArchivePath[AZ_MAX_PATH_LEN] = { 0 };
EXPECT_TRUE(fileIo->ResolvePath(testPakPath, resolvedArchivePath, AZ_MAX_PATH_LEN));
@@ -116,7 +116,7 @@ namespace CryPakUnitTests
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds{ 100 });
// helper paths and strings
AZStd::string gameFolder = fileIo->GetAlias("@cache@");
AZStd::string gameFolder = fileIo->GetAlias("@usercache@");
AZStd::string testFile = "unittest.bin";
AZStd::string testFilePath = gameFolder + "\\" + testFile;
+2 -2
View File
@@ -297,7 +297,7 @@ void CVisRegTest::CaptureSample(const SCmd& cmd)
if (m_cmdFreq == 1) // Final sample
{
// Screenshot
stack_string filename("@cache@/TestResults/VisReg/"); // the default unaliased assets folder is read-only!
stack_string filename("@usercache@/TestResults/VisReg/"); // the default unaliased assets folder is read-only!
filename += m_testName + "/" + cmd.args.c_str();
gEnv->pRenderer->ScreenShot(filename);
@@ -335,7 +335,7 @@ void CVisRegTest::Finish()
bool CVisRegTest::WriteResults()
{
stack_string filename("@cache@/TestResults/VisReg/");
stack_string filename("@usercache@/TestResults/VisReg/");
filename += m_testName + "/visreg_results.xml";
AZ::IO::HandleType fileHandle = fxopen(filename.c_str(), "wb");
@@ -26,7 +26,6 @@ set(FILES
IDebugCallStack.cpp
AsyncPakManager.cpp
Log.cpp
BootProfiler.cpp
SystemRender.cpp
NotificationNetwork.cpp
PhysRenderer.cpp
@@ -91,7 +90,6 @@ set(FILES
WindowsConsole.h
XConsole.h
XConsoleVariable.h
BootProfiler.h
crash_face.bmp
ImageHandler.h
ImageHandler.cpp
@@ -121,11 +119,9 @@ set(FILES
XML/WriteXMLSource.cpp
ZipFile.h
ZipFileFormat_info.h
LoadingProfiler.cpp
PerfHUD.cpp
ProfileLogSystem.cpp
Sampler.cpp
LoadingProfiler.h
PerfHUD.h
ProfileLogSystem.h
Sampler.h
+2 -2
View File
@@ -902,7 +902,7 @@ void ShadersOptimizeHelper(CallableT setupParserBin, const char* logString)
{
setupParserBin();
CryLogAlways("\nStarting shaders optimizing for %s...", logString);
AZStd::string str = "@cache@/" + gRenDev->m_cEF.m_ShadersCache;
AZStd::string str = "@usercache@/" + gRenDev->m_cEF.m_ShadersCache;
iLog->Log("Optimize shader cache folder: '%s'", gRenDev->m_cEF.m_ShadersCache.c_str());
gRenDev->m_cEF.mfOptimiseShaders(str.c_str(), false);
}
@@ -2396,7 +2396,7 @@ void CRenderer::InitRenderer()
CV_r_ShaderCompilerFolderSuffix = REGISTER_STRING("r_ShaderCompilerFolderSuffix", "", VF_NULL,
"Usage: r_ShaderCompilerFolderSuffix suffix \n"
"Default is empty. Set to some other value to append this suffix to the sys_game_folder when compiling shaders");
"Default is empty. Set to some other value to append this suffix to the project name when compiling shaders");
{
const SFileVersion& ver = gEnv->pSystem->GetFileVersion();
@@ -20,6 +20,7 @@
#include <AzCore/Socket/AzSocket.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/PlatformId/PlatformId.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/Network/SocketConnection.h>
#include <AzFramework/Asset/AssetSystemTypes.h>
@@ -306,23 +307,20 @@ namespace NRemoteCompiler
m_RequestLineRootFolder = "";
ICVar* pGameFolder = gEnv->pConsole->GetCVar("sys_game_folder");
auto projectName = AZ::Utils::GetProjectName();
ICVar* pCompilerFolderSuffix = CRenderer::CV_r_ShaderCompilerFolderSuffix;
if (pGameFolder)
if (!projectName.empty())
{
string folder = pGameFolder->GetString();
folder.Trim();
if (!folder.empty())
if (pCompilerFolderSuffix)
{
if (pCompilerFolderSuffix)
{
string suffix = pCompilerFolderSuffix->GetString();
suffix.Trim();
folder.append(suffix);
}
m_RequestLineRootFolder = folder + string("/");
string suffix = pCompilerFolderSuffix->GetString();
suffix.Trim();
projectName.append(suffix);
}
projectName.append("/");
m_RequestLineRootFolder.assign(projectName.c_str(), projectName.size());
}
if (m_RequestLineRootFolder.empty())
@@ -13,16 +13,61 @@
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Memory/AllocatorScope.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/UnitTest/UnitTest.h>
#include "Mocks/IConsoleMock.h"
#include "Mocks/ICVarMock.h"
#include "Mocks/ISystemMock.h"
#include "RemoteCompiler.h"
namespace AZ
{
class SettingsRegistrySimpleMock;
using NiceSettingsRegistrySimpleMock = ::testing::NiceMock<SettingsRegistrySimpleMock>;
class SettingsRegistrySimpleMock : public AZ::SettingsRegistryInterface
{
public:
MOCK_CONST_METHOD1(GetType, Type(AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(Visitor&, AZStd::string_view));
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(u64&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(double&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(AZStd::string&, AZStd::string_view));
MOCK_CONST_METHOD2(Get, bool(FixedValueString&, AZStd::string_view));
MOCK_CONST_METHOD3(GetObject, bool(void*, Uuid, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, bool));
MOCK_METHOD2(Set, bool(AZStd::string_view, s64));
MOCK_METHOD2(Set, bool(AZStd::string_view, u64));
MOCK_METHOD2(Set, bool(AZStd::string_view, double));
MOCK_METHOD2(Set, bool(AZStd::string_view, AZStd::string_view));
MOCK_METHOD2(Set, bool(AZStd::string_view, const char*));
MOCK_METHOD3(SetObject, bool(AZStd::string_view, const void*, Uuid));
MOCK_METHOD1(Remove, bool(AZStd::string_view));
MOCK_METHOD3(MergeCommandLineArgument, bool(AZStd::string_view, AZStd::string_view, const CommandLineArgumentSettings&));
MOCK_METHOD2(MergeSettings, bool(AZStd::string_view, Format));
MOCK_METHOD4(MergeSettingsFile, bool(AZStd::string_view, Format, AZStd::string_view, AZStd::vector<char>*));
MOCK_METHOD5(
MergeSettingsFolder,
bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector<char>*));
};
} // namespace AZ
namespace NRemoteCompiler
{
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::DoAll;
using SystemAllocatorScope = AZ::AllocatorScope<AZ::LegacyAllocator, CryStringAllocator>;
@@ -65,9 +110,12 @@ namespace NRemoteCompiler
SystemAllocatorScope::ActivateAllocators();
m_priorEnv = gEnv;
m_priorSettingsRegistry = AZ::SettingsRegistry::Get();
m_data.reset(new DataMembers);
AZ::SettingsRegistry::Register(&m_data->m_settings);
ON_CALL(m_data->m_console, GetCVar(_))
.WillByDefault(Return(&m_data->m_cvarMock));
@@ -89,6 +137,11 @@ namespace NRemoteCompiler
void TearDown() override
{
gEnv = m_priorEnv;
AZ::SettingsRegistry::Unregister(&m_data->m_settings);
if (m_priorSettingsRegistry)
{
AZ::SettingsRegistry::Register(m_priorSettingsRegistry);
}
m_data.reset();
SystemAllocatorScope::DeactivateAllocators();
AllocatorsTestFixture::TearDown();
@@ -99,12 +152,14 @@ namespace NRemoteCompiler
NiceMock<SystemMock> m_system;
NiceMock<ConsoleMock> m_console;
NiceMock<CVarMock> m_cvarMock;
AZ::NiceSettingsRegistrySimpleMock m_settings;
SSystemGlobalEnvironment m_stubEnv;
};
AZStd::unique_ptr<DataMembers> m_data;
SSystemGlobalEnvironment* m_priorEnv = nullptr;
AZ::SettingsRegistryInterface* m_priorSettingsRegistry = nullptr;
};
// allow punch through to PRIVATE functions so that they do not need to be made PUBLIC.
@@ -130,7 +185,9 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithNoGameName_Fails)
{
EXPECT_CALL(m_data->m_cvarMock, GetString());
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString regResult;
EXPECT_CALL(m_data->m_settings, Get(regResult, _));
AZ_TEST_START_TRACE_SUPPRESSION;
ShaderSrvUnitTestAccessor srv;
@@ -140,8 +197,10 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithValidGameName_Succeeds)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
}
@@ -149,11 +208,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_EmptyData_Fails)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
std::vector<uint8> testVector;
@@ -165,11 +225,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidData_EmptyServerList_Fails)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillRepeatedly(Return("")); // empty server list
@@ -186,11 +247,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidInputs_Succeeds)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -207,11 +269,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_EmptyData_Fails)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -221,7 +284,7 @@ namespace NRemoteCompiler
std::vector<uint8> testVector;
std::string testString("empty");
// test for empty data - recvfailed expected (error emitted)
// test for empty data - RecvFailed expected (error emitted)
AZ_TEST_START_TRACE_SUPPRESSION;
testString = "empty";
testVector.assign(testString.begin(), testString.end());
@@ -232,11 +295,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_IncompleteData_Fails)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -247,7 +311,7 @@ namespace NRemoteCompiler
std::string testString("incomplete");
testVector.assign(testString.begin(), testString.end());
// test for incomplete data - recvfailed expected
// test for incomplete data - RecvFailed expected
AZ_TEST_START_TRACE_SUPPRESSION;
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
@@ -256,11 +320,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CorruptData_Fails)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -271,7 +336,7 @@ namespace NRemoteCompiler
std::string testString("corrupt");
testVector.assign(testString.begin(), testString.end());
// test for incomplete data - recvfailed expected
// test for incomplete data - RecvFailed expected
AZ_TEST_START_TRACE_SUPPRESSION;
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
@@ -280,11 +345,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CompileError_Fails_ReturnsText)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -294,11 +360,11 @@ namespace NRemoteCompiler
std::vector<uint8> testVector;
std::string testString("corrupt");
testVector.assign(testString.begin(), testString.end());
// test for an actual compile error - decompressed compile erro rexpected to be attached.
// test for an actual compile error - decompressed compile error expected to be attached.
testString = "compile_failure";
testVector.assign(testString.begin(), testString.end());
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESCompileError);
// validate hte compile erorr decompressed successfully
// validate the compile error decompressed successfully
const char* expected_decode = "decompressed_plaintext";
EXPECT_EQ(testVector.size(), strlen(expected_decode));
EXPECT_EQ(memcmp(testVector.data(), expected_decode, strlen(expected_decode)), 0);
@@ -307,11 +373,12 @@ namespace NRemoteCompiler
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_ValidInput_Succeeds_ReturnsText)
{
// when we construct the server it calls get on the game name
EXPECT_CALL(m_data->m_cvarMock, GetString())
.WillOnce(Return("StarterGame"));
using namespace ::testing;
AZ::SettingsRegistryInterface::FixedValueString projectName;
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
ShaderSrvUnitTestAccessor srv;
// After this, it will repeatedly call get cvar to get the server address:
const char* testList = "10.20.30.40";
@@ -375,7 +375,7 @@ void CShaderMan::mfInitShadersCacheMissLog()
// create valid path
gEnv->pCryPak->MakeDir(g_szTestResults);
m_ShaderCacheMissPath = string("@cache@\\Shaders\\ShaderCacheMisses.txt"); // do we want this here, or maybe in @log@ ?
m_ShaderCacheMissPath = string("@usercache@\\Shaders\\ShaderCacheMisses.txt"); // do we want this here, or maybe in @log@ ?
// load data which is already stored
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
@@ -2175,9 +2175,10 @@ void CShaderMan::mfOptimiseShaders(const char* szFolder, bool bForce)
for (i = 0; i < Names.size(); i++)
{
const char* szName = Names[i].c_str();
if (!strncmp(szName, "@cache@/", 7))
constexpr AZStd::string_view userCache = "@usercache@/";
if (szName == userCache)
{
szName += 7;
szName += userCache.size();
}
pCache = CHWShader::mfInitCache(szName, NULL, false, 0, false);
if (!pCache || !pCache->m_pRes[CACHE_USER])
@@ -1589,7 +1589,7 @@ void CShaderMan::mfInit (void)
#else
m_ShadersCache = CONCAT_PATHS(g_shaderCache, "D3D11");
#endif
m_szCachePath = "@cache@/";
m_szCachePath = "@usercache@/";
if (CRenderer::CV_r_shadersImport == 3)
{
@@ -162,7 +162,7 @@ bool CShaderSerialize::OpenSResource(const char* szName, SSShaderRes* pSR, CSha
stack_string szReadOnly = szName;
// ShaderCacheGen behavior:
// CACHE_READONLY is not really used when exporting the .fxb, so we append the @cache@ alias to the relative shader path
// CACHE_READONLY is not really used when exporting the .fxb, so we append the @usercache@ alias to the relative shader path
// here as well. We cannot just leave this as the relative Shaders/Cache/Foo.fxb value because then it creates a new
// file in the asset cache as @assets@/Shaders/Cache/Foo.fxb, which is illegal (since only AP has the authority to write here)
// Game runtime behavior:
@@ -3490,7 +3490,7 @@ void CHWShader_D3D::mfSaveCGFile(const char* scr, const char* path)
}
else
{
sprintf_s(name, "@cache@/shaders/fxerror/%s(GL%llx)/(LT%x)(RT%llx)/(MD%x)(MDV%x)(PSS%llx)(ST%llx).cg", GetName(), m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask);
sprintf_s(name, "@usercache@/shaders/fxerror/%s(GL%llx)/(LT%x)(RT%llx)/(MD%x)(MDV%x)(PSS%llx)(ST%llx).cg", GetName(), m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask);
}
AZ::IO::HandleType fileHandle;
@@ -4672,7 +4672,7 @@ bool CAsyncShaderTask::CompileAsyncShader(SShaderAsyncInfo* pAsync)
CryFixedStringT<1024> hlslPath;
// Create a directory for this shader type, strip the .fxcb extension from the folder name
shaderSourceOutputFolder.Format("@cache@/%s",pAsync->m_pShader->m_pDevCache->m_Name.c_str());
shaderSourceOutputFolder.Format("@usercache@/%s",pAsync->m_pShader->m_pDevCache->m_Name.c_str());
PathUtil::RemoveExtension(shaderSourceOutputFolder);
gEnv->pFileIO->CreatePath(shaderSourceOutputFolder);
@@ -70,6 +70,7 @@
#endif
#include "../Common/RenderCapabilities.h"
#include <AzCore/Utils/Utils.h>
#ifdef WIN32
// Count monitors helper
@@ -1634,8 +1635,8 @@ WIN_HWND CD3D9Renderer::Init([[maybe_unused]] int x, [[maybe_unused]] int y, int
iLog->Log ("Direct3D driver is creating...");
iLog->Log ("Crytek Direct3D driver version %4.2f (%s <%s>)", VERSION_D3D, __DATE__, __TIME__);
const char* sGameName = iConsole->GetCVar("sys_game_name")->GetString();
cry_strcpy(m_WinTitle, sGameName);
auto projectName = AZ::Utils::GetProjectName();
cry_strcpy(m_WinTitle, projectName.c_str());
iLog->Log ("Creating window called '%s' (%dx%d)", m_WinTitle, width, height);