12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001 |
- /*
- * 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 "RenderDll_precompiled.h"
- #ifdef SHADERS_SERIALIZING
- bool CShaderSerialize::_OpenSResource(float fVersion, SSShaderRes* pSR, CShader* pSH, int nCache, CResFile* pRF, bool bReadOnly)
- {
- assert(nCache == CACHE_USER || nCache == CACHE_READONLY);
- SSShaderCacheHeader hd;
- ZeroStruct(hd);
- bool bValid = true;
- bool bCheckValid = true;
- if (!CRenderer::CV_r_shadersAllowCompilation)
- {
- bCheckValid = false;
- }
- //uint64 writeTimeCFX=0;
- //See if resfile is in assets dir
- if (!pRF->mfOpen(RA_READ | (CParserBin::m_bEndians ? RA_ENDIANS : 0), NULL, NULL))
- {
- pRF->mfClose();
- bValid = false;
- }
- if (bValid)
- {
- pRF->mfFileSeek(CShaderMan::s_cNameHEAD, 0, SEEK_SET);
- pRF->mfFileRead2(CShaderMan::s_cNameHEAD, sizeof(SSShaderCacheHeader), &hd);
- if (CParserBin::m_bEndians)
- {
- SwapEndian(hd, eBigEndian);
- }
- if (hd.m_SizeOf != sizeof(SSShaderCacheHeader))
- {
- bValid = false;
- }
- else if (fVersion && (hd.m_MajorVer != (int)fVersion || hd.m_MinorVer != (int)(((float)fVersion - (float)(int)fVersion) * 10.1f)))
- {
- bValid = false;
- //if (CRenderer::CV_r_shadersdebug==2)
- {
- LogWarning("WARNING: Shader resource '%s' version mismatch (Resource: %s, Expected: %.1f)", pRF->mfGetFileName(), hd.m_szVer, fVersion);
- }
- }
- if (bCheckValid)
- {
- char nameSrc[256];
- sprintf_s(nameSrc, "%sCryFX/%s.%s", gRenDev->m_cEF.m_ShadersPath.c_str(), pSH->GetName(), "cfx");
- uint32 srcCRC = pSH->m_SourceCRC32;
- if (!srcCRC)
- {
- srcCRC = gEnv->pCryPak->ComputeCRC(nameSrc);
- pSH->m_SourceCRC32 = srcCRC; //Propagate to shader, prevent recalculation
- }
- if (srcCRC && srcCRC != hd.m_SourceCRC32)
- {
- bValid = false;
- //if (CRenderer::CV_r_shadersdebug==2)
- {
- LogWarning("WARNING: Shader resource '%s' src CRC mismatch", pRF->mfGetFileName());
- }
- }
- }
- // If we failed a version or CRC check, close our resource file since we may try opening it again later
- if (!bValid)
- {
- pRF->mfClose();
- }
- if (bValid && nCache == CACHE_USER)
- {
- pRF->mfClose();
- if (!pRF->mfOpen(RA_READ | (CParserBin::m_bEndians ? RA_ENDIANS : 0) | RA_WRITE, NULL, NULL))
- {
- pRF->mfClose();
- bValid = false;
- }
- }
- }
- if (!bValid && nCache == CACHE_USER && !bReadOnly && pSH->m_CRC32) //Create ResFile
- {
- if (!pRF->mfOpen(RA_CREATE | (CParserBin::m_bEndians ? RA_ENDIANS : 0), NULL, NULL))
- {
- return false;
- }
- SDirEntry de;
- de.Name = CShaderMan::s_cNameHEAD;
- de.size = sizeof(SSShaderCacheHeader);
- hd.m_SizeOf = sizeof(SSShaderCacheHeader);
- hd.m_MinorVer = (int)(((float)fVersion - (float)(int)fVersion) * 10.1f);
- hd.m_MajorVer = (int)fVersion;
- hd.m_CRC32 = pSH->m_CRC32;
- hd.m_SourceCRC32 = pSH->m_SourceCRC32;
- sprintf_s(hd.m_szVer, "Ver: %.1f", fVersion);
- SSShaderCacheHeader hdTemp, * pHD;
- pHD = &hd;
- if (CParserBin::m_bEndians)
- {
- hdTemp = hd;
- SwapEndian(hdTemp, eBigEndian);
- pHD = &hdTemp;
- }
- //create dir
- pRF->mfFileAdd(&de);
- //open dir and populate data
- SDirEntryOpen* pOpenDir = pRF->mfOpenEntry(&de);
- pOpenDir->pData = pHD;
- pOpenDir->nSize = de.size;
- pRF->mfFlush();
- bValid = true;
- }
- if (!bValid)
- {
- SAFE_DELETE(pRF);
- }
- if (pSR->m_pRes[nCache] && (pSR->m_pRes[nCache] != pRF))
- {
- SAFE_DELETE(pSR->m_pRes[nCache]);
- }
- pSR->m_pRes[nCache] = pRF;
- pSR->m_Header[nCache] = hd;
- pSR->m_bReadOnly[nCache] = bReadOnly;
- if (bValid && !pSH->m_CRC32)
- {
- pSH->m_CRC32 = hd.m_CRC32;
- }
- return bValid;
- }
- bool CShaderSerialize::OpenSResource(const char* szName, SSShaderRes* pSR, CShader* pSH, bool bDontUseUserFolder, bool bReadOnly)
- {
- stack_string szReadOnly = szName;
- // ShaderCacheGen behavior:
- // 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:
- // We can't simply set both the CACHE_READONLY and CACHE_USER entries to be the same file path because then the shader caching
- // system treats these entries the same. CACHE_READONLY acts more as a template while CACHE_USER is the actual file with all
- // of the shader permutation entries. They need different file names (that have the same relative shader path) in order
- // for the CResFiles to be treated differently by the caching system.
- if (gRenDev->IsShaderCacheGenMode())
- {
- szReadOnly = stack_string(gRenDev->m_cEF.m_szCachePath.c_str()) + stack_string(szName);
- }
- CResFile* rfRO = new CResFile(szReadOnly);
- float fVersion = FX_CACHE_VER + FX_SER_CACHE_VER;
- bool bValidRO = _OpenSResource(fVersion, pSR, pSH, bDontUseUserFolder ? CACHE_READONLY : CACHE_USER, rfRO, bReadOnly);
- bool bValidUser = false;
- #if !defined(SHADER_NO_SOURCES)
- CResFile* rfUser;
- if (!bDontUseUserFolder)
- {
- stack_string szUser = stack_string(gRenDev->m_cEF.m_szCachePath.c_str()) + stack_string(szName);
- rfUser = new CResFile(szUser.c_str());
- bValidUser = _OpenSResource(fVersion, pSR, pSH, CACHE_USER, rfUser, bReadOnly);
- }
- #endif
- return (bValidRO || bValidUser);
- }
- bool CShaderSerialize::CreateSResource(CShader* pSH, SSShaderRes* pSR, [[maybe_unused]] CCryNameTSCRC& SName, bool bDontUseUserFolder, bool bReadOnly)
- {
- AZStd::string dstName;
- dstName.reserve(512);
- if (m_customSerialisePath.size())
- {
- dstName = m_customSerialisePath.c_str();
- }
- dstName += gRenDev->m_cEF.m_ShadersCache;
- dstName += pSH->GetName();
- dstName += ".fxb";
- bool bRes = OpenSResource(dstName.c_str(), pSR, pSH, bDontUseUserFolder, bReadOnly);
- AZ_Error("CShaderSerialize", bRes, "Failed to open '%s' with bDontUseUserFolder=%s and bReadOnly=%s", dstName.c_str(), bDontUseUserFolder ? "True" : "False", bReadOnly ? "True" : "False");
- return bRes;
- }
- SSShaderRes* CShaderSerialize::InitSResource(CShader* pSH, bool bDontUseUserFolder, bool bReadOnly)
- {
- SSShaderRes* pSR = NULL;
- stack_string shaderName = pSH->GetName();
- shaderName += "_GLOBAL";
- CCryNameTSCRC SName = CCryNameTSCRC(shaderName.c_str());
- FXSShaderResItor itS = m_SShaderResources.find(SName);
- #if SHADER_NO_SOURCES
- bool bCheckValid = false;
- #else
- bool bCheckValid = true;
- #endif
- if (itS != m_SShaderResources.end())
- {
- pSR = itS->second;
- pSR->m_nRefCount++;
- if (bCheckValid)
- {
- int nCache[2] = {-1, -1};
- if (!bReadOnly || bDontUseUserFolder)
- {
- nCache[0] = CACHE_USER;
- }
- else
- if (!bDontUseUserFolder || bReadOnly)
- {
- nCache[0] = CACHE_USER;
- nCache[1] = CACHE_READONLY;
- }
- for (int i = 0; i < 2; i++)
- {
- if (nCache[i] < 0 || !pSR->m_pRes[i])
- {
- continue;
- }
- //if the shader has a CRC then we can test, generally it is only valid during cache gen
- if (pSH->m_CRC32 != 0 && pSR->m_Header[i].m_CRC32 != pSH->m_CRC32)
- {
- //CryLogAlways("CRC check failed in serialise: 0x%x source: 0x%x\n", pSR->m_Header[i].m_CRC32, pSH->m_CRC32);
- SAFE_DELETE(pSR->m_pRes[i]);
- }
- }
- bool bValid = true;
- if (!bReadOnly && !pSR->m_pRes[CACHE_USER])
- {
- bValid = false;
- }
- else
- if ((!bDontUseUserFolder || bReadOnly) && !pSR->m_pRes[CACHE_READONLY] && !pSR->m_pRes[CACHE_USER])
- {
- bValid = false;
- }
- if (!bValid)
- {
- CreateSResource(pSH, pSR, SName, bDontUseUserFolder, bReadOnly);
- }
- else
- {
- //printf("Reusing existing .fxb for %s\n", pSH->GetName() );
- }
- }
- }
- else
- {
- pSR = new SSShaderRes;
- bool bRes = CreateSResource(pSH, pSR, SName, bDontUseUserFolder, bReadOnly);
- if (bRes)
- {
- m_SShaderResources.insert(FXSShaderResItor::value_type(SName, pSR));
- }
- else
- {
- SAFE_DELETE(pSR);
- }
- }
- if (pSH->m_CRC32 == 0 && pSR)
- {
- if (pSR->m_pRes[CACHE_READONLY])
- {
- pSH->m_CRC32 = pSR->m_Header[CACHE_READONLY].m_CRC32;
- }
- else if (pSR->m_pRes[CACHE_USER])
- {
- pSH->m_CRC32 = pSR->m_Header[CACHE_USER].m_CRC32;
- }
- }
- return pSR;
- }
- void CShaderSerialize::ClearSResourceCache()
- {
- const FXSShaderResItor end_it = m_SShaderResources.end();
- FXSShaderResItor it = m_SShaderResources.begin();
- for (; it != end_it; it++)
- {
- SAFE_DELETE(it->second);
- }
- m_SShaderResources.clear();
- }
- bool CShaderSerialize::DoesSResourceExist(CShader* pSH)
- {
- SSShaderRes* pSR = NULL;
- stack_string shaderName = pSH->GetName();
- shaderName += "_GLOBAL";
- CCryNameTSCRC SName = CCryNameTSCRC(shaderName.c_str());
- FXSShaderResItor itS = m_SShaderResources.find(SName);
- if (itS != m_SShaderResources.end())
- {
- return true;
- }
-
- return false;
- }
- bool CShaderSerialize::ExportHWShader(CHWShader* pShader, SShaderSerializeContext& SC)
- {
- if (!pShader)
- {
- return false;
- }
- bool bRes = pShader->Export(SC);
- return bRes;
- }
- CHWShader* CShaderSerialize::ImportHWShader(SShaderSerializeContext& SC, int nOffs, uint32 CRC32, CShader* pSH)
- {
- CHWShader* pRes = CHWShader::Import(SC, nOffs, CRC32, pSH);
- return pRes;
- }
- void CShaderSerialize::ExportHWShaderStage(SShaderSerializeContext& SC, CHWShader* shader, uint32& outShaderOffset)
- {
- if ( shader )
- {
- outShaderOffset = SC.Data.Num();
- if ( !ExportHWShader(shader,SC) )
- {
- outShaderOffset = -1;
- CryFatalError("Shader export failed.");
- }
- }
- else
- {
- outShaderOffset = -1;
- }
- }
- bool CShaderSerialize::ExportShader(CShader* pSH, CShaderManBin& binShaderMgr)
- {
- #ifdef SHADER_SERIALIZE_VERBOSE
- CryLogAlways("[CShaderSerialize] ExportShader: %s flags: 0x%llx mdvFlags: 0x%x\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV);
- #endif
- bool bRes = true;
- //Use user folder on export?
- SSShaderRes* pSR = InitSResource(pSH, false /*((gRenDev->m_cEF.m_nCombinations > 0) || !CRenderer::CV_r_shadersuserfolder)*/, false);
- uint32 i;
- int j;
- if (!pSR || !pSR->m_pRes[CACHE_USER])
- {
- return false;
- }
- SShaderSerializeContext SC;
- SC.SSR.m_eSHDType = pSH->m_eSHDType;
- SC.SSR.m_Flags = pSH->m_Flags;
- SC.SSR.m_Flags2 = pSH->m_Flags2;
- SC.SSR.m_nMDV = pSH->m_nMDV;
- SC.SSR.m_vertexFormatEnum = pSH->m_vertexFormat.GetEnum();
- SC.SSR.m_eCull = pSH->m_eCull;
- //SC.SSR.m_nMaskCB = pSH->m_nMaskCB; //maskCB generated on HW shader activation
- SC.SSR.m_eShaderType = pSH->m_eShaderType;
- SC.SSR.m_nMaskGenFX = pSH->m_nMaskGenFX;
- SC.SSR.m_nTechniques = pSH->m_HWTechniques.Num();
- SShaderFXParams& params = binShaderMgr.mfGetFXParams(pSH);
- SC.SSR.m_nPublicParams = params.m_PublicParams.size();
- for (i = 0; i < SC.SSR.m_nPublicParams; i++)
- {
- SSShaderParam PR;
- SShaderParam& P = params.m_PublicParams[i];
- PR.m_nameIdx = SC.AddString(P.m_Name.c_str());
- PR.m_Type = P.m_Type;
- PR.m_Value = P.m_Value;
- PR.m_nScriptOffs = SC.AddString(P.m_Script.c_str());
- PR.m_eSemantic = P.m_eSemantic;
- SC.Params.Add(PR);
- }
- SC.SSR.m_nFXParams = params.m_FXParams.size();
- for (i = 0; i < SC.SSR.m_nFXParams; i++)
- {
- params.m_FXParams[i].Export(SC);
- }
- SC.SSR.m_nFXSamplers = params.m_FXSamplers.size();
- for (i = 0; i < SC.SSR.m_nFXSamplers; i++)
- {
- params.m_FXSamplers[i].Export(SC);
- }
- SC.SSR.m_nFXTextures = params.m_FXTextures.size();
- for (i = 0; i < SC.SSR.m_nFXTextures; i++)
- {
- params.m_FXTextures[i].Export(SC);
- }
- SC.SSR.m_nFXTexSamplers = params.m_FXSamplersOld.size();
- for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++)
- {
- params.m_FXSamplersOld[i].Export(SC);
- }
- SC.SSR.m_nFXTexRTs = SC.FXTexRTs.Num();
- for (i = 0; i < SC.SSR.m_nTechniques; i++)
- {
- SSShaderTechnique ST;
- SShaderTechnique* pT = pSH->m_HWTechniques[i];
- ST.m_nPreprocessFlags = pT->m_nPreprocessFlags;
- ST.m_nNameOffs = SC.AddString(pT->m_NameStr.c_str());
- ST.m_Flags = pT->m_Flags;
- int TECH_MAX = TTYPE_MAX;
- for (j = 0; j < TECH_MAX; j++)
- {
- ST.m_nTechnique[j] = pT->m_nTechnique[j];
- }
- ST.m_nREs = pT->m_REs.Num();
- ST.m_nPassesOffs = SC.Passes.Num();
- ST.m_nPasses = pT->m_Passes.Num();
- SC.SSR.m_nPasses += ST.m_nPasses;
- for (j = 0; j < ST.m_nPasses; j++)
- {
- SSShaderPass PS;
- SShaderPass& P = pT->m_Passes[j];
- PS.m_RenderState = P.m_RenderState;
- PS.m_eCull = P.m_eCull;
- PS.m_AlphaRef = P.m_AlphaRef;
- PS.m_PassFlags = P.m_PassFlags;
- assert(!(SC.Data.Num() & 0x3));
- ExportHWShaderStage( SC, P.m_VShader, PS.m_nVShaderOffs );
- ExportHWShaderStage( SC, P.m_HShader, PS.m_nHShaderOffs );
- ExportHWShaderStage( SC, P.m_DShader, PS.m_nDShaderOffs );
- ExportHWShaderStage( SC, P.m_GShader, PS.m_nGShaderOffs );
- ExportHWShaderStage( SC, P.m_PShader, PS.m_nPShaderOffs );
- ExportHWShaderStage( SC, P.m_CShader, PS.m_nCShaderOffs );
- SC.Passes.Add(PS);
- }
- ST.m_nREsOffs = (ST.m_nREs > 0) ? SC.Data.Num() : -1;
- for (j = 0; j < ST.m_nREs; j++)
- {
- CRendElementBase* pRE = pT->m_REs[j];
- uint32 type = pRE->m_Type;
- sAddData(SC.Data, type);
- pRE->mfExport(SC);
- sAlignData(SC.Data, 4);
- }
- SC.Techniques.AddElem(ST);
- }
- TArray<byte> Data;
- //DEBUG - prevent Data reallocs
- //Data.Alloc(1024*1024);
- uint32 nPublicParamsOffset;
- uint32 nFXParamsOffset;
- uint32 nFXSamplersOffset;
- uint32 nFXTexturesOffset;
- uint32 nFXTexSamplersOffset;
- uint32 nFXTexRTsOffset;
- uint32 nTechOffset;
- uint32 nPassOffset;
- uint32 nStringsOffset;
- uint32 nDataOffset;
- //sAddData(Data, SC.SSR);
- SC.SSR.Export(Data);
- sAddDataArray(Data, SC.Params, nPublicParamsOffset);
- sAddDataArray(Data, SC.FXParams, nFXParamsOffset);
- sAddDataArray(Data, SC.FXSamplers, nFXSamplersOffset);
- sAddDataArray(Data, SC.FXTextures, nFXTexturesOffset);
- sAddDataArray(Data, SC.FXTexSamplers, nFXTexSamplersOffset);
- sAddDataArray(Data, SC.FXTexRTs, nFXTexRTsOffset);
- sAddDataArray(Data, SC.Techniques, nTechOffset);
- sAddDataArray(Data, SC.Passes, nPassOffset);
- sAddDataArray_POD(Data, SC.Strings, nStringsOffset);
- sAddDataArray_POD(Data, SC.Data, nDataOffset);
- SSShader* pSSR = (SSShader*)&Data[0];
- pSSR->m_nPublicParamsOffset = nPublicParamsOffset;
- pSSR->m_nFXParamsOffset = nFXParamsOffset;
- pSSR->m_nFXSamplersOffset = nFXSamplersOffset;
- pSSR->m_nFXTexturesOffset = nFXTexturesOffset;
- pSSR->m_nFXTexSamplersOffset = nFXTexSamplersOffset;
- pSSR->m_nFXTexRTsOffset = nFXTexRTsOffset;
- pSSR->m_nTechOffset = nTechOffset;
- pSSR->m_nPassOffset = nPassOffset;
- pSSR->m_nStringsOffset = nStringsOffset;
- pSSR->m_nDataOffset = nDataOffset;
- pSSR->m_nDataSize = SC.Data.Num();
- pSSR->m_nStringsSize = SC.Strings.Num();
- if (CParserBin::m_bEndians)
- {
- SwapEndian(pSSR->m_nPublicParamsOffset, eBigEndian);
- SwapEndian(pSSR->m_nFXParamsOffset, eBigEndian);
- SwapEndian(pSSR->m_nFXSamplersOffset, eBigEndian);
- SwapEndian(pSSR->m_nFXTexturesOffset, eBigEndian);
- SwapEndian(pSSR->m_nFXTexRTsOffset, eBigEndian);
- SwapEndian(pSSR->m_nTechOffset, eBigEndian);
- SwapEndian(pSSR->m_nPassOffset, eBigEndian);
- SwapEndian(pSSR->m_nStringsOffset, eBigEndian);
- SwapEndian(pSSR->m_nDataOffset, eBigEndian);
- SwapEndian(pSSR->m_nDataSize, eBigEndian);
- SwapEndian(pSSR->m_nStringsSize, eBigEndian);
- }
- int nLen = Data.Num();
- SDirEntry de;
- char sName[128];
- sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic);
- de.Name = CCryNameTSCRC(sName);
- de.size = nLen;
- de.flags |= RF_COMPRESS;
- pSR->m_pRes[CACHE_USER]->mfFileAdd(&de);
- //create open dir and populate data
- SDirEntryOpen* pOpenDir = pSR->m_pRes[CACHE_USER]->mfOpenEntry(&de);
- pOpenDir->pData = &Data[0];
- pOpenDir->nSize = de.size;
- //Preserve modification time
- uint64 modTime = pSR->m_pRes[CACHE_USER]->mfGetModifTime();
- pSR->m_pRes[CACHE_USER]->mfFlush();
- return bRes;
- }
- float g_fTime0;
- float g_fTime1;
- float g_fTime2;
- bool CShaderSerialize::CheckFXBExists(CShader* pSH)
- {
- SSShaderRes* pSR = InitSResource(pSH, false, true);
- if (!pSR || (!pSR->m_Header[CACHE_USER].m_CRC32 && !pSR->m_Header[CACHE_READONLY].m_CRC32))
- {
- return false;
- }
- char sName[128];
- sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic);
- CCryNameTSCRC CName = CCryNameTSCRC(sName);
- SDirEntry* pDE = NULL;
- CResFile* pRes = NULL;
- for (int i = 0; i < 2; i++)
- {
- pRes = pSR->m_pRes[i];
- if (!pRes)
- {
- continue;
- }
- pDE = pRes->mfGetEntry(CName);
- if (pDE)
- {
- return true;
- }
- }
- return false;
- }
- CShaderSerialize::ShaderImportResults CShaderSerialize::ImportShader(CShader* pSH, CShaderManBin& binShaderMgr)
- {
- if (CParserBin::m_bEndians)
- {
- CryFatalError("CShaderSerialize - cross platform import not supported");
- }
- float fTime0 = iTimer->GetAsyncCurTime();
- SSShaderRes* pSR = NULL;
- uint32 i;
- int j;
- char sName[128];
- sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic);
- CCryNameTSCRC CName = CCryNameTSCRC(sName);
- SDirEntry* pDE = NULL;
- CResFile* pRes = NULL;
- // Not found yet
- if (!pDE || !pRes)
- {
- //try global cache
- pSR = InitSResource(pSH, !CRenderer::CV_r_shadersAllowCompilation, true);
- if (pSR && (pSR->m_Header[CACHE_USER].m_CRC32 != 0 || pSR->m_Header[CACHE_READONLY].m_CRC32 != 0))
- {
- for (i = 0; i < 2; i++)
- {
- pRes = pSR->m_pRes[i];
- if (!pRes)
- {
- continue;
- }
- pDE = pRes->mfGetEntry(CName);
- if (pDE)
- {
- break;
- }
- }
- }
- if (!pDE && !pSR)
- {
- // The .cfx has no associated .fxb, so this is a guaranteed failure on import.
- return SHADER_IMPORT_FAILURE;
- }
- else if (!pDE)
- {
- // We have a shader import table but this specific permutation is missing
- return SHADER_IMPORT_MISSING_ENTRY;
- }
- }
- CShader* pSave = gRenDev->m_RP.m_pShader;
- gRenDev->m_RP.m_pShader = pSH;
- assert(gRenDev->m_RP.m_pShader != 0);
- int nSize = pRes->mfFileRead(pDE);
- byte* pData = (byte*)pRes->mfFileGetBuf(pDE);
- if (!pData)
- {
- // Malformed fxb
- return SHADER_IMPORT_FAILURE;
- }
- //printf("[CShaderSerialize] Import Shader: %s flags: 0x%llx mdvFlags: 0x%x from %s cache %s\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV, bLoadedFromLevel ? "LEVEL" : "GLOBAL", pSR->m_pRes[i]->mfGetFileName());
- byte* pSrc = pData;
- g_fTime0 += iTimer->GetAsyncCurTime() - fTime0;
- float fTime1 = iTimer->GetAsyncCurTime();
- SShaderFXParams& fxParams = binShaderMgr.mfGetFXParams(pSH);
- SShaderSerializeContext SC;
- SC.SSR.Import(pSrc);
-
- #ifdef SHADER_SERIALIZE_VERBOSE
- CryLog("[CShaderSerialize] Import Shader: %s flags: 0x%llx mdvFlags: 0x%x from global cache %s\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV, pSR->m_pRes[i]->mfGetFileName());
- #endif
- if (SC.SSR.m_nPublicParams)
- {
- SC.Params.ReserveNoClear(SC.SSR.m_nPublicParams);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.Params[0], &pSrc[SC.SSR.m_nPublicParamsOffset], sizeof(SSShaderParam) * SC.SSR.m_nPublicParams);
- }
- else
- {
- uint32 offset = SC.SSR.m_nPublicParamsOffset;
- for (i = 0; i < SC.SSR.m_nPublicParams; i++)
- {
- SC.Params[i].Import(&pSrc[offset]);
- offset += sizeof(SSShaderParam);
- }
- }
- }
- if (SC.SSR.m_nFXParams)
- {
- SC.FXParams.ReserveNoClear(SC.SSR.m_nFXParams);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.FXParams[0], &pSrc[SC.SSR.m_nFXParamsOffset], sizeof(SSFXParam) * SC.SSR.m_nFXParams);
- }
- else
- {
- uint32 offset = SC.SSR.m_nFXParamsOffset;
- for (i = 0; i < SC.SSR.m_nFXParams; i++)
- {
- SC.FXParams[i].Import(&pSrc[offset]);
- offset += sizeof(SSFXParam);
- }
- }
- }
-
- if (SC.SSR.m_nFXSamplers)
- {
- SC.FXSamplers.ReserveNoClear(SC.SSR.m_nFXSamplers);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.FXSamplers[0], &pSrc[SC.SSR.m_nFXSamplersOffset], sizeof(SSFXSampler) * SC.SSR.m_nFXSamplers);
- }
- else
- {
- uint32 offset = SC.SSR.m_nFXSamplersOffset;
- for (i = 0; i < SC.SSR.m_nFXSamplers; i++)
- {
- SC.FXSamplers[i].Import(&pSrc[offset]);
- offset += sizeof(SSTexSamplerFX);
- }
- }
- }
-
- if (SC.SSR.m_nFXTextures)
- {
- SC.FXTextures.ReserveNoClear(SC.SSR.m_nFXTextures);
- memcpy(&SC.FXTextures[0], &pSrc[SC.SSR.m_nFXTexturesOffset], sizeof(SSFXTexture) * SC.SSR.m_nFXTextures);
- }
- if (SC.SSR.m_nFXTexSamplers)
- {
- SC.FXTexSamplers.ReserveNoClear(SC.SSR.m_nFXTexSamplers);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.FXTexSamplers[0], &pSrc[SC.SSR.m_nFXTexSamplersOffset], sizeof(SSTexSamplerFX) * SC.SSR.m_nFXTexSamplers);
- }
- else
- {
- uint32 offset = SC.SSR.m_nFXTexSamplersOffset;
- for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++)
- {
- SC.FXTexSamplers[i].Import(&pSrc[offset]);
- offset += sizeof(SSTexSamplerFX);
- }
- }
- }
- if (SC.SSR.m_nFXTexRTs)
- {
- SC.FXTexRTs.ReserveNoClear(SC.SSR.m_nFXTexRTs);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.FXTexRTs[0], &pSrc[SC.SSR.m_nFXTexRTsOffset], sizeof(SSHRenderTarget) * SC.SSR.m_nFXTexRTs);
- }
- else
- {
- uint32 offset = SC.SSR.m_nFXTexRTsOffset;
- for (i = 0; i < SC.SSR.m_nFXTexRTs; i++)
- {
- SC.FXTexRTs[i].Import(&pSrc[offset]);
- offset += sizeof(SSHRenderTarget);
- }
- }
- }
- if (SC.SSR.m_nTechniques)
- {
- SC.Techniques.ReserveNoClear(SC.SSR.m_nTechniques);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.Techniques[0], &pSrc[SC.SSR.m_nTechOffset], sizeof(SSShaderTechnique) * SC.SSR.m_nTechniques);
- }
- else
- {
- uint32 offset = SC.SSR.m_nTechOffset;
- for (i = 0; i < SC.SSR.m_nTechniques; i++)
- {
- SC.Techniques[i].Import(&pSrc[offset]);
- offset += sizeof(SSShaderTechnique);
- }
- }
- }
- if (SC.SSR.m_nPasses)
- {
- SC.Passes.ReserveNoClear(SC.SSR.m_nPasses);
- if (!CParserBin::m_bEndians)
- {
- memcpy(&SC.Passes[0], &pSrc[SC.SSR.m_nPassOffset], sizeof(SSShaderPass) * SC.SSR.m_nPasses);
- }
- else
- {
- uint32 offset = SC.SSR.m_nPassOffset;
- for (i = 0; i < SC.SSR.m_nPasses; i++)
- {
- SC.Passes[i].Import(&pSrc[offset]);
- offset += sizeof(SSShaderPass);
- }
- }
- }
- if (SC.SSR.m_nStringsSize)
- {
- SC.Strings.ReserveNoClear(SC.SSR.m_nStringsSize);
- memcpy(&SC.Strings[0], &pSrc[SC.SSR.m_nStringsOffset], SC.SSR.m_nStringsSize);
- }
- if (SC.SSR.m_nDataSize)
- {
- SC.Data.ReserveNoClear(SC.SSR.m_nDataSize);
- memcpy(&SC.Data[0], &pSrc[SC.SSR.m_nDataOffset], SC.SSR.m_nDataSize);
- }
- pRes->mfFileClose(pDE);
- g_fTime1 += iTimer->GetAsyncCurTime() - fTime1;
- float fTime2 = iTimer->GetAsyncCurTime();
- pSH->m_eSHDType = SC.SSR.m_eSHDType;
- //TODO |= on flags? will we lose flags at runtime
- pSH->m_Flags = SC.SSR.m_Flags;
- pSH->m_Flags2 = SC.SSR.m_Flags2;
- pSH->m_nMDV = SC.SSR.m_nMDV;
- AZ_Assert(SC.SSR.m_vertexFormatEnum < eVF_Max, "Bad vertex format index. Is the shader cache out of date?");
- pSH->m_vertexFormat = gRenDev->m_RP.m_vertexFormats[SC.SSR.m_vertexFormatEnum];
- pSH->m_eCull = SC.SSR.m_eCull;
- pSH->m_eShaderType = SC.SSR.m_eShaderType;
- pSH->m_nMaskGenFX = SC.SSR.m_nMaskGenFX;
- fxParams.m_PublicParams.reserve(fxParams.m_PublicParams.size() + SC.SSR.m_nPublicParams);
- for (i = 0; i < SC.SSR.m_nPublicParams; i++)
- {
- SSShaderParam& PR = SC.Params[i];
- SShaderParam P;
- const char* pName = sString(PR.m_nameIdx, SC.Strings);
- P.m_Name = pName;
- P.m_Type = PR.m_Type;
- P.m_Value = PR.m_Value;
- P.m_Script = sString(PR.m_nScriptOffs, SC.Strings);
- fxParams.m_PublicParams.push_back(P);
- }
- fxParams.m_FXParams.reserve(fxParams.m_FXParams.size() + SC.SSR.m_nFXParams);
- for (i = 0; i < SC.SSR.m_nFXParams; i++)
- {
- SFXParam fxParam;
- fxParam.Import(SC, &SC.FXParams[i]);
- fxParams.m_FXParams.push_back(fxParam);
- }
- fxParams.m_FXSamplersOld.reserve(fxParams.m_FXSamplersOld.size() + SC.SSR.m_nFXTexSamplers);
- for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++)
- {
- STexSamplerFX fxTexSampler;
- fxTexSampler.Import(SC, &SC.FXTexSamplers[i]);
- fxParams.m_FXSamplersOld.push_back(fxTexSampler);
- }
- fxParams.m_FXSamplers.reserve(fxParams.m_FXSamplers.size() + SC.SSR.m_nFXSamplers);
- for (i = 0; i < SC.SSR.m_nFXSamplers; i++)
- {
- SFXSampler fxSampler;
- fxSampler.Import(SC, &SC.FXSamplers[i]);
- fxParams.m_FXSamplers.push_back(fxSampler);
- }
- fxParams.m_FXTextures.reserve(fxParams.m_FXTextures.size() + SC.SSR.m_nFXTextures);
- for (i = 0; i < SC.SSR.m_nFXTextures; i++)
- {
- SFXTexture fxTexture;
- fxTexture.Import(SC, &SC.FXTextures[i]);
- fxParams.m_FXTextures.push_back(fxTexture);
- }
- for (i = 0; i < SC.SSR.m_nTechniques; i++)
- {
- SSShaderTechnique& ST = SC.Techniques[i];
- SShaderTechnique* pT = new SShaderTechnique(pSH);
- pT->m_NameStr = sString(ST.m_nNameOffs, SC.Strings);
- pT->m_NameCRC = pT->m_NameStr.c_str();
- pT->m_Flags = ST.m_Flags;
- pT->m_nPreprocessFlags = ST.m_nPreprocessFlags;
- for (j = 0; j < TTYPE_MAX; j++)
- {
- pT->m_nTechnique[j] = ST.m_nTechnique[j];
- }
- if (ST.m_nPasses)
- {
- int nOffs = ST.m_nPassesOffs;
- pT->m_Passes.reserve(ST.m_nPasses);
- for (j = 0; j < ST.m_nPasses; j++)
- {
- SSShaderPass& PS = SC.Passes[j + nOffs];
- SShaderPass* P = pT->m_Passes.AddIndex(1);
- P->m_RenderState = PS.m_RenderState;
- P->m_eCull = PS.m_eCull;
- P->m_AlphaRef = PS.m_AlphaRef;
- P->m_PassFlags = PS.m_PassFlags;
- P->m_VShader = ImportHWShader(SC, PS.m_nVShaderOffs, pSH->m_CRC32, pSH);
- P->m_PShader = ImportHWShader(SC, PS.m_nPShaderOffs, pSH->m_CRC32, pSH);
- P->m_GShader = ImportHWShader(SC, PS.m_nGShaderOffs, pSH->m_CRC32, pSH);
- P->m_HShader = ImportHWShader(SC, PS.m_nHShaderOffs, pSH->m_CRC32, pSH);
- P->m_DShader = ImportHWShader(SC, PS.m_nDShaderOffs, pSH->m_CRC32, pSH);
- P->m_CShader = ImportHWShader(SC, PS.m_nCShaderOffs, pSH->m_CRC32, pSH);
- }
- }
- uint32 nREOffset = ST.m_nREsOffs;
- for (j = 0; j < ST.m_nREs; j++)
- {
- EDataType dataType = *((EDataType*)&SC.Data[nREOffset]);
- if (CParserBin::m_bEndians)
- {
- SwapEndianEnum(dataType, eBigEndian);
- }
- nREOffset += sizeof(EDataType);
- switch (dataType)
- {
- case eDATA_LensOptics:
- {
- CRELensOptics* pLensOptics = new CRELensOptics;
- pLensOptics->mfImport(SC, nREOffset);
- pT->m_REs.push_back(pLensOptics);
- }
- break;
- case eDATA_Beam:
- {
- CREBeam* pBeam = new CREBeam;
- pBeam->mfImport(SC, nREOffset);
- pT->m_REs.push_back(pBeam);
- }
- break;
- default:
- CryFatalError("Render element not supported for shader serialising");
- break;
- }
- //expects 4 byte aligned
- assert(!(nREOffset & 3));
- }
- pSH->m_HWTechniques.AddElem(pT);
- }
- gRenDev->m_RP.m_pShader = pSave;
- g_fTime2 += iTimer->GetAsyncCurTime() - fTime2;
- return SHADER_IMPORT_SUCCESS;
- }
- #endif
|