You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
852 lines
24 KiB
C++
852 lines
24 KiB
C++
/*
|
|
* 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.
|
|
|
|
// Description : implementation of the Shaders parser part of shaders manager.
|
|
|
|
|
|
#include "RenderDll_precompiled.h"
|
|
#include "I3DEngine.h"
|
|
#include "CryHeaders.h"
|
|
#include "CryPath.h"
|
|
#include <AzFramework/Archive/IArchive.h>
|
|
|
|
#if defined(WIN32) || defined(WIN64)
|
|
#include <direct.h>
|
|
#include <io.h>
|
|
#elif defined(LINUX)
|
|
#endif
|
|
|
|
|
|
//============================================================
|
|
// Compile functions
|
|
//============================================================
|
|
|
|
SShaderGenBit* CShaderMan::mfCompileShaderGenProperty(char* scr)
|
|
{
|
|
char* name;
|
|
long cmd;
|
|
char* params;
|
|
char* data;
|
|
|
|
SShaderGenBit* shgm = new SShaderGenBit;
|
|
|
|
enum
|
|
{
|
|
eName = 1, eProperty, eDescription, eMask, eHidden, eRuntime, ePrecache, eDependencySet, eDependencyReset, eDependFlagSet, eDependFlagReset, eAutoPrecache, eLowSpecAutoPrecache
|
|
};
|
|
static STokenDesc commands[] =
|
|
{
|
|
{eName, "Name"},
|
|
{eProperty, "Property"},
|
|
{eDescription, "Description"},
|
|
{eMask, "Mask"},
|
|
{eHidden, "Hidden"},
|
|
{ePrecache, "Precache"},
|
|
{eRuntime, "Runtime"},
|
|
{eAutoPrecache, "AutoPrecache"},
|
|
{eLowSpecAutoPrecache, "LowSpecAutoPrecache"},
|
|
{eDependencySet, "DependencySet"},
|
|
{eDependencyReset, "DependencyReset"},
|
|
{eDependFlagSet, "DependFlagSet"},
|
|
{eDependFlagReset, "DependFlagReset"},
|
|
|
|
{0, 0}
|
|
};
|
|
|
|
shgm->m_PrecacheNames.reserve(45);
|
|
|
|
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
|
{
|
|
data = NULL;
|
|
if (name)
|
|
{
|
|
data = name;
|
|
}
|
|
else
|
|
if (params)
|
|
{
|
|
data = params;
|
|
}
|
|
|
|
switch (cmd)
|
|
{
|
|
case eName:
|
|
shgm->m_ParamName = data;
|
|
shgm->m_dwToken = CCrc32::Compute(data);
|
|
break;
|
|
|
|
case eProperty:
|
|
if (gRenDev->IsEditorMode())
|
|
{
|
|
shgm->m_ParamProp = data;
|
|
}
|
|
break;
|
|
|
|
case eDescription:
|
|
if (gRenDev->IsEditorMode())
|
|
{
|
|
shgm->m_ParamDesc = data;
|
|
}
|
|
break;
|
|
|
|
case eHidden:
|
|
shgm->m_Flags |= SHGF_HIDDEN;
|
|
break;
|
|
|
|
case eRuntime:
|
|
shgm->m_Flags |= SHGF_RUNTIME;
|
|
break;
|
|
|
|
case eAutoPrecache:
|
|
shgm->m_Flags |= SHGF_AUTO_PRECACHE;
|
|
break;
|
|
case eLowSpecAutoPrecache:
|
|
shgm->m_Flags |= SHGF_LOWSPEC_AUTO_PRECACHE;
|
|
break;
|
|
|
|
case ePrecache:
|
|
shgm->m_PrecacheNames.push_back(CParserBin::GetCRC32(data));
|
|
shgm->m_Flags |= SHGF_PRECACHE;
|
|
break;
|
|
|
|
case eDependFlagSet:
|
|
shgm->m_DependSets.push_back(data);
|
|
break;
|
|
|
|
case eDependFlagReset:
|
|
shgm->m_DependResets.push_back(data);
|
|
break;
|
|
|
|
case eMask:
|
|
if (data && data[0])
|
|
{
|
|
if (data[0] == '0' && (data[1] == 'x' || data[1] == 'X'))
|
|
{
|
|
shgm->m_Mask = shGetHex64(&data[2]);
|
|
}
|
|
else
|
|
{
|
|
shgm->m_Mask = shGetInt(data);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eDependencySet:
|
|
if (data && data[0])
|
|
{
|
|
if (!azstricmp(data, "$LM_Diffuse"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_LM_DIFFUSE;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Detail"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_DETAIL;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Normals"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_NORMALS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Height"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_HEIGHT;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_SecondSmoothness"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Specular"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SPECULAR;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_EnvCM"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_ENVCM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Subsurface"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SUBSURFACE;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_BilinearFP16"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_BILINEARFP16;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SeparateFP16"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_SEPARATEFP16;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Custom"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_CUSTOM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_CustomSecondary"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_CUSTOM_SECONDARY;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Occ"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_OCC;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_WaterTessellation"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_WATER_TESSELLATION;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SilhouettePom"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_SILHOUETTE_POM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SpecularAntialiasing"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_SAA;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$UserEnabled"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_USER_ENABLED;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_ORBIS"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_ORBIS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_DX11"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_DX11;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_GL4"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_GL4;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_GLES3"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_GLES3;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Emittance"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_EMITTANCE;
|
|
}
|
|
|
|
// backwards compatible names
|
|
else if (!azstricmp(data, "$HW_METAL"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_HW_METAL;
|
|
}
|
|
else if (!azstricmp(data, "$TEX_Bump"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_NORMALS;
|
|
}
|
|
else if (!azstricmp(data, "$TEX_BumpHeight"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_HEIGHT;
|
|
}
|
|
else if (!azstricmp(data, "$TEX_Translucency"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else if (!azstricmp(data, "$TEX_BumpDif"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else if (!azstricmp(data, "$TEX_Gloss"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SPECULAR;
|
|
}
|
|
|
|
else
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eDependencyReset:
|
|
if (data && data[0])
|
|
{
|
|
if (!azstricmp(data, "$LM_Diffuse"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_LM_DIFFUSE;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Detail"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_DETAIL;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Normals"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_NORMALS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Height"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_HEIGHT;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_SecondSmoothness"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Specular"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_SPECULAR;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_EnvCM"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_ENVCM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Subsurface"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_SUBSURFACE;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_BilinearFP16"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_BILINEARFP16;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SeparateFP16"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_SEPARATEFP16;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Custom"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_CUSTOM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_CustomSecondary"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_CUSTOM_SECONDARY;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Occ"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_OCC;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Decal"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_DECAL;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_WaterTessellation"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_WATER_TESSELLATION;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SilhouettePom"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_SILHOUETTE_POM;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_SpecularAntialiasing"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_SAA;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$UserEnabled"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_USER_ENABLED;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_DX11"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_DX11;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_GL4"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_GL4;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_GLES3"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_GLES3;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_METAL"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_METAL;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$HW_ORBIS"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_HW_ORBIS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Emittance"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_EMITTANCE;
|
|
}
|
|
|
|
// backwards compatible names
|
|
else
|
|
if (!azstricmp(data, "$TEX_Bump"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_NORMALS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_BumpHeight"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_HEIGHT;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Translucency"))
|
|
{
|
|
shgm->m_nDependencyReset |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_BumpDif"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS;
|
|
}
|
|
else
|
|
if (!azstricmp(data, "$TEX_Gloss"))
|
|
{
|
|
shgm->m_nDependencySet |= SHGD_TEX_SPECULAR;
|
|
}
|
|
|
|
else
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
shgm->m_NameLength = strlen(shgm->m_ParamName.c_str());
|
|
|
|
return shgm;
|
|
}
|
|
|
|
bool CShaderMan::mfCompileShaderGen(SShaderGen* shg, char* scr)
|
|
{
|
|
char* name;
|
|
long cmd;
|
|
char* params;
|
|
char* data;
|
|
|
|
SShaderGenBit* shgm;
|
|
|
|
enum
|
|
{
|
|
eProperty = 1, eVersion, eUsesCommonGlobalFlags
|
|
};
|
|
static STokenDesc commands[] =
|
|
{
|
|
{eProperty, "Property"},
|
|
{eVersion, "Version"},
|
|
{eUsesCommonGlobalFlags, "UsesCommonGlobalFlags"},
|
|
{0, 0}
|
|
};
|
|
|
|
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
|
{
|
|
data = NULL;
|
|
if (name)
|
|
{
|
|
data = name;
|
|
}
|
|
else
|
|
if (params)
|
|
{
|
|
data = params;
|
|
}
|
|
|
|
switch (cmd)
|
|
{
|
|
case eProperty:
|
|
shgm = mfCompileShaderGenProperty(params);
|
|
if (shgm)
|
|
{
|
|
shg->m_BitMask.AddElem(shgm);
|
|
}
|
|
break;
|
|
|
|
case eUsesCommonGlobalFlags:
|
|
break;
|
|
|
|
case eVersion:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return shg->m_BitMask.Num() != 0;
|
|
}
|
|
|
|
void CShaderMan::mfCompileLevelsList(std::vector<string>& List, char* scr)
|
|
{
|
|
char* name;
|
|
long cmd;
|
|
char* params;
|
|
char* data;
|
|
|
|
enum
|
|
{
|
|
eName = 1, eVersion
|
|
};
|
|
static STokenDesc commands[] =
|
|
{
|
|
{eName, "Name"},
|
|
{0, 0}
|
|
};
|
|
|
|
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
|
{
|
|
data = NULL;
|
|
if (name)
|
|
{
|
|
data = name;
|
|
}
|
|
else
|
|
if (params)
|
|
{
|
|
data = params;
|
|
}
|
|
|
|
switch (cmd)
|
|
{
|
|
case eName:
|
|
if (data && data[0])
|
|
{
|
|
List.push_back(string("Levels/") + string(data) + string("/"));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CShaderMan::mfCompileShaderLevelPolicies(SShaderLevelPolicies* pPL, char* scr)
|
|
{
|
|
char* name;
|
|
long cmd;
|
|
char* params;
|
|
char* data;
|
|
|
|
enum
|
|
{
|
|
eGlobalList = 1, ePerLevelList, eVersion
|
|
};
|
|
static STokenDesc commands[] =
|
|
{
|
|
{eGlobalList, "GlobalList"},
|
|
{ePerLevelList, "PerLevelList"},
|
|
{eVersion, "Version"},
|
|
{0, 0}
|
|
};
|
|
|
|
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
|
{
|
|
data = NULL;
|
|
if (name)
|
|
{
|
|
data = name;
|
|
}
|
|
else
|
|
if (params)
|
|
{
|
|
data = params;
|
|
}
|
|
|
|
switch (cmd)
|
|
{
|
|
case eGlobalList:
|
|
mfCompileLevelsList(pPL->m_WhiteGlobalList, params);
|
|
break;
|
|
case ePerLevelList:
|
|
mfCompileLevelsList(pPL->m_WhitePerLevelList, params);
|
|
break;
|
|
|
|
case eVersion:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pPL->m_WhiteGlobalList.size() != 0;
|
|
}
|
|
|
|
string CShaderMan::mfGetShaderBitNamesFromMaskGen(const char* szFileName, uint64 nMaskGen)
|
|
{
|
|
// debug/helper function: returns ShaderGen bit names string based on nMaskGen
|
|
|
|
if (!nMaskGen)
|
|
{
|
|
return "NO_FLAGS";
|
|
}
|
|
|
|
string pszShaderName = PathUtil::GetFileName(szFileName);
|
|
pszShaderName.MakeUpper();
|
|
|
|
ShaderMapNameFlagsItor pShaderRmp = m_pShadersGlobalFlags.find(pszShaderName.c_str());
|
|
if (pShaderRmp == m_pShadersGlobalFlags.end() || !pShaderRmp->second)
|
|
{
|
|
return "NO_FLAGS";
|
|
}
|
|
|
|
string pszShaderBitNames;
|
|
|
|
// get shader bit names
|
|
MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin();
|
|
MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end();
|
|
for (; pIter != pEnd; ++pIter)
|
|
{
|
|
if (nMaskGen & pIter->second)
|
|
{
|
|
pszShaderBitNames += pIter->first.c_str();
|
|
}
|
|
}
|
|
|
|
return pszShaderBitNames;
|
|
}
|
|
|
|
void CShaderMan::mfRemapShaderGenInfoBits(const char* szName, SShaderGen* pShGen)
|
|
{
|
|
// No data to proceed
|
|
if (!pShGen || pShGen->m_BitMask.empty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check if shader uses common flags at all
|
|
string pszShaderName = PathUtil::GetFileName(szName);
|
|
pszShaderName.MakeUpper();
|
|
if ((int32) m_pShadersRemapList.find(pszShaderName.c_str()) < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
MapNameFlags* pOldShaderFlags = 0;
|
|
if (m_pShadersGlobalFlags.find(pszShaderName.c_str()) == m_pShadersGlobalFlags.end())
|
|
{
|
|
AZStd::unique_lock<AZStd::mutex> lock(m_shaderLoadMutex);
|
|
|
|
pOldShaderFlags = new MapNameFlags;
|
|
m_pShadersGlobalFlags.insert(ShaderMapNameFlagsItor::value_type(pszShaderName.c_str(), pOldShaderFlags));
|
|
}
|
|
|
|
uint32 nBitCount = pShGen->m_BitMask.size();
|
|
for (uint32 b = 0; b < nBitCount; ++b)
|
|
{
|
|
SShaderGenBit* pGenBit = pShGen->m_BitMask[b];
|
|
if (!pGenBit)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Store old shader flags
|
|
if (pOldShaderFlags)
|
|
{
|
|
pOldShaderFlags->insert(MapNameFlagsItor::value_type(pGenBit->m_ParamName.c_str(), pGenBit->m_Mask));
|
|
}
|
|
|
|
// lookup for name - and update mask value
|
|
MapNameFlagsItor pRemaped = m_pShaderCommonGlobalFlag.find(pGenBit->m_ParamName.c_str());
|
|
if (pRemaped != m_pShaderCommonGlobalFlag.end())
|
|
{
|
|
pGenBit->m_Mask = pRemaped->second;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
bool CShaderMan::mfUsesGlobalFlags(const char* szShaderName)
|
|
{
|
|
// Check if shader uses common flags at all
|
|
string pszName = PathUtil::GetFileName(szShaderName);
|
|
|
|
AZStd::unique_lock<AZStd::mutex> lock(m_shaderLoadMutex);
|
|
|
|
string pszShaderNameUC = pszName;
|
|
pszShaderNameUC.MakeUpper();
|
|
if ((int32) m_pShadersRemapList.find(pszShaderNameUC.c_str()) < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
uint64 CShaderMan::mfGetShaderGlobalMaskGenFromString(const char* szShaderGen)
|
|
{
|
|
assert(szShaderGen);
|
|
if (!szShaderGen || szShaderGen[0] == '\0')
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AZStd::unique_lock<AZStd::mutex> lock(m_shaderLoadMutex);
|
|
|
|
uint64 nMaskGen = 0;
|
|
MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end();
|
|
|
|
char* pCurrOffset = (char*)szShaderGen;
|
|
while (pCurrOffset)
|
|
{
|
|
char* pBeginOffset = (char*)strstr(pCurrOffset, "%");
|
|
assert(pBeginOffset);
|
|
PREFAST_ASSUME(pBeginOffset);
|
|
pCurrOffset = (char*)strstr(pBeginOffset + 1, "%");
|
|
|
|
char pCurrFlag[64] = "\0";
|
|
int nLen = pCurrOffset ? pCurrOffset - pBeginOffset : strlen(pBeginOffset);
|
|
memcpy(pCurrFlag, pBeginOffset, nLen);
|
|
|
|
MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.find(pCurrFlag);
|
|
if (pIter != pEnd)
|
|
{
|
|
nMaskGen |= pIter->second;
|
|
}
|
|
}
|
|
|
|
return nMaskGen;
|
|
}
|
|
|
|
AZStd::string CShaderMan::mfGetShaderBitNamesFromGlobalMaskGen(uint64 nMaskGen)
|
|
{
|
|
if (!nMaskGen)
|
|
{
|
|
return "\0";
|
|
}
|
|
|
|
AZStd::string shaderBitNames = "\0";
|
|
MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin();
|
|
MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end();
|
|
for (; pIter != pEnd; ++pIter)
|
|
{
|
|
if (nMaskGen & pIter->second)
|
|
{
|
|
shaderBitNames += pIter->first.c_str();
|
|
}
|
|
}
|
|
|
|
return shaderBitNames;
|
|
}
|
|
|
|
uint64 CShaderMan::mfGetRemapedShaderMaskGen(const char* szName, uint64 nMaskGen, bool bFixup)
|
|
{
|
|
if (!nMaskGen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AZStd::unique_lock<AZStd::mutex> lock(m_shaderLoadMutex);
|
|
|
|
uint64 nMaskGenRemaped = 0;
|
|
string szShaderName = PathUtil::GetFileName(szName);// some shaders might be using concatenated names (eg: terrain.layer), get only first name
|
|
szShaderName.MakeUpper();
|
|
ShaderMapNameFlagsItor pShaderRmp = m_pShadersGlobalFlags.find(szShaderName.c_str());
|
|
|
|
if (pShaderRmp == m_pShadersGlobalFlags.end() || !pShaderRmp->second)
|
|
{
|
|
return nMaskGen;
|
|
}
|
|
|
|
if (bFixup)
|
|
{
|
|
// if some flag was removed, disable in mask
|
|
nMaskGen = nMaskGen & m_nSGFlagsFix;
|
|
return nMaskGen;
|
|
}
|
|
|
|
// old bitmask - remap to common shared bitmasks
|
|
for (uint64 j = 0; j < 64; ++j)
|
|
{
|
|
uint64 nMask = (((uint64)1) << j);
|
|
if (nMaskGen & nMask)
|
|
{
|
|
MapNameFlagsItor pIter = pShaderRmp->second->begin();
|
|
MapNameFlagsItor pEnd = pShaderRmp->second->end();
|
|
for (; pIter != pEnd; ++pIter)
|
|
{
|
|
// found match - enable bit for remapped mask
|
|
if ((pIter->second) & nMask)
|
|
{
|
|
MapNameFlagsItor pMatchIter = m_pShaderCommonGlobalFlag.find(pIter->first);
|
|
if (pMatchIter != m_pShaderCommonGlobalFlag.end())
|
|
{
|
|
nMaskGenRemaped |= pMatchIter->second;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nMaskGenRemaped;
|
|
}
|
|
|
|
|
|
SShaderGen* CShaderMan::mfCreateShaderGenInfo(const char* szName, bool bRuntime)
|
|
{
|
|
CCryNameTSCRC s = szName;
|
|
if (!bRuntime)
|
|
{
|
|
ShaderExtItor it = m_ShaderExts.find(s);
|
|
if (it != m_ShaderExts.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
}
|
|
SShaderGen* pShGen = NULL;
|
|
char szN[256];
|
|
cry_strcpy(szN, "Shaders/");
|
|
cry_strcat(szN, szName);
|
|
cry_strcat(szN, ".ext");
|
|
AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(szN, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET);
|
|
if (fileHandle != AZ::IO::InvalidHandle)
|
|
{
|
|
pShGen = new SShaderGen;
|
|
AZ::u64 fileSize = 0;
|
|
AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileSize);
|
|
char* buf = new char [fileSize + 1];
|
|
if (buf)
|
|
{
|
|
buf[fileSize] = 0;
|
|
gEnv->pCryPak->FRead(buf, fileSize, fileHandle);
|
|
mfCompileShaderGen(pShGen, buf);
|
|
mfRemapShaderGenInfoBits(szName, pShGen);
|
|
delete [] buf;
|
|
}
|
|
gEnv->pCryPak->FClose(fileHandle);
|
|
}
|
|
if (pShGen && !bRuntime)
|
|
{
|
|
pShGen->m_BitMask.Shrink();
|
|
m_ShaderExts.insert(std::pair<CCryNameTSCRC, SShaderGen*>(s, pShGen));
|
|
}
|
|
|
|
return pShGen;
|
|
}
|