6e8fbca745
match the genesis editor version 1.3.0.653.
262 lines
5.8 KiB
C++
262 lines
5.8 KiB
C++
/****************************************************************************
|
||
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
||
http://www.genesis-3d.com.cn
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
THE SOFTWARE.
|
||
****************************************************************************/
|
||
#include "stdneb.h"
|
||
#include "ShaderCompiler.h"
|
||
#include "util/array.h"
|
||
|
||
#include "ShaderElement.h"
|
||
#include "ShaderMarcro.h"
|
||
#include "ShadercompilerConfig.h"
|
||
|
||
namespace ShaderProgramCompiler
|
||
{
|
||
|
||
__ImplementAbstractClass(GpuProgramCompiler,'GPCP',Core::RefCounted);
|
||
|
||
GpuProgramCompiler::GpuProgramCompiler()
|
||
{
|
||
|
||
}
|
||
|
||
GpuProgramCompiler::~GpuProgramCompiler()
|
||
{
|
||
|
||
}
|
||
|
||
void GpuProgramCompiler::InitCompiler()
|
||
{
|
||
|
||
}
|
||
|
||
void GpuProgramCompiler::_BeforeCompile(const ShaderPass* pPass)
|
||
{
|
||
m_sResultCode.Clear();
|
||
m_sRegisterBinds.Clear();
|
||
m_sCompiledCode.Clear();
|
||
m_Macros.Clear();
|
||
|
||
const ShadingTemplateSetting& shadeSetting = pPass->GetShadingSetting();
|
||
const CommonShaderSetting& cs = pPass->GetCommonSetting();
|
||
|
||
|
||
m_sProgramStartString = "RenderAPI \"" + CommonShaderSetting::GpuSdkAsString(cs.GetGpuSDK()) + "\" {\n";
|
||
|
||
m_sResultCode += m_sProgramStartString;
|
||
}
|
||
|
||
void GpuProgramCompiler::_AfterCompile(bool bForwardPass)
|
||
{
|
||
|
||
SizeT nCount;
|
||
|
||
if (bForwardPass)
|
||
{
|
||
nCount = m_SubShaderMarcroPermuation.Size();
|
||
}
|
||
else
|
||
{
|
||
nCount = 1;
|
||
}
|
||
|
||
for (IndexT i = 0; i < nCount; ++i)
|
||
{
|
||
Util::String nSub;
|
||
IndexT mask = m_SubShaderMarcroPermuation.KeyAtIndex(i);
|
||
nSub.AppendInt(mask);
|
||
m_sResultCode += "SubGpuProgram \"" + nSub + "\" {\n";
|
||
|
||
if (!m_sRegisterBinds.IsEmpty())
|
||
{
|
||
m_sResultCode += m_sRegisterBinds[i];
|
||
}
|
||
|
||
|
||
Util::String sCompiledCode = m_sCompiledCode[i];
|
||
|
||
SizeT maxLength = 5000;
|
||
|
||
if (sCompiledCode.Length() > maxLength)
|
||
{
|
||
IndexT departs = sCompiledCode.Length()/ maxLength;
|
||
Util::String tmpStr;
|
||
for (SizeT i = 0; i < departs; ++i)
|
||
{
|
||
if (i != 0)
|
||
{
|
||
tmpStr += "\"\nSetShaderCode \"";
|
||
}
|
||
tmpStr += sCompiledCode.ExtractRange(i * maxLength, maxLength);
|
||
}
|
||
tmpStr += "\"\nSetShaderCode \"" + sCompiledCode.ExtractToEnd(departs * maxLength);
|
||
sCompiledCode = tmpStr;
|
||
|
||
}
|
||
|
||
m_sResultCode += "SetShaderCode \"" + sCompiledCode + "\"\n\n";
|
||
|
||
//right bracket of SubGpuProgram
|
||
m_sResultCode += "}\n";
|
||
}
|
||
|
||
//right bracket of RenderAPI
|
||
m_sResultCode += "}\n";
|
||
}
|
||
|
||
void GpuProgramCompiler::_CreatePermutation(const Util::Array<Util::String>& marcroName, bool bTemplate)
|
||
{
|
||
SizeT nCount = marcroName.Size();
|
||
|
||
SizeT nPermutation = (SizeT)Math::n_pow((float)2, (float)nCount);
|
||
|
||
Util::Array<IndexT> permutation;
|
||
permutation.Resize(nCount, 0);
|
||
|
||
if (!nCount)
|
||
{
|
||
m_Permutation.Add(0, permutation);
|
||
return;
|
||
}
|
||
|
||
for (IndexT n=1; n <= nPermutation; ++n)
|
||
{
|
||
int temp = n;
|
||
|
||
for(IndexT i=0; i < nCount; ++i)
|
||
|
||
{
|
||
permutation[nCount-1-i] = temp % 2;
|
||
|
||
temp /= 2 ;
|
||
|
||
}
|
||
|
||
if (bTemplate)
|
||
{
|
||
SizeT nLignt = permutation[0];
|
||
|
||
IndexT nLightMap = marcroName.FindIndex("LIGHTMAP_ON");
|
||
IndexT nShadow = marcroName.FindIndex("SHADOW_ON");
|
||
|
||
if (nShadow != InvalidIndex)
|
||
{
|
||
//<2F><EFBFBD><DEB3><EFBFBD><EFBFBD><EFBFBD>Ӱû<D3B0>еƹ<D0B5><C6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (permutation[nShadow] && (!nLignt) && (!permutation[nLightMap]))
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
|
||
if (nLightMap != InvalidIndex)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>lightmap<61>Ͳ<EFBFBD><CDB2><EFBFBD>Ҫƴ<D2AA><C6B4>lighting<6E>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||
if (permutation[nLightMap] + nLignt > 1)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
m_Permutation.Add(n-1, permutation);
|
||
}
|
||
}
|
||
|
||
void GpuProgramCompiler::CreateAllShaderMacrosPermutation(const Util::Array<Util::String>& marcroName, const GPtr<ShaderMarcro>& pMarcro, bool bTemplate)
|
||
{
|
||
_CreatePermutation(marcroName, bTemplate);
|
||
|
||
SizeT nCount = m_Permutation.Size();
|
||
|
||
for (IndexT i = 0; i < nCount; ++i)
|
||
{
|
||
const Util::Array<IndexT>& permutation = m_Permutation.ValueAtIndex(i);
|
||
|
||
ShaderMarcros marcros;
|
||
|
||
SizeT nPermu = permutation.Size();
|
||
uint shaderMask = 0;
|
||
|
||
for (IndexT j = 0; j < nPermu; ++j)
|
||
{
|
||
|
||
if (permutation[j])
|
||
{
|
||
const Util::String& name = marcroName[j];
|
||
shaderMask |= pMarcro->CreateMask(name);
|
||
ShaderMarcroInfo info;
|
||
info.name = name;
|
||
info.value = "1";
|
||
marcros.Append(info);
|
||
}
|
||
}
|
||
|
||
m_SubShaderMarcroPermuation.Add(shaderMask, marcros);
|
||
|
||
|
||
}
|
||
}
|
||
|
||
void GpuProgramCompiler::CreateBuiltInMarcro(const uint iPass, const Util::Array<Util::String>& customMacros, const ShadingTemplateSetting* pSetting)
|
||
{
|
||
GPtr<ShaderMarcro> pMacro = ShaderMarcro::Create();
|
||
pMacro->Init(customMacros, pSetting);
|
||
|
||
bool bTemplate = true;
|
||
if (!pSetting)
|
||
{
|
||
bTemplate = false;
|
||
}
|
||
|
||
if (iPass == 0)
|
||
{
|
||
const Util::Array<Util::String>& allNames = pMacro->GetAllMarcroName();
|
||
CreateAllShaderMacrosPermutation(allNames, pMacro, bTemplate);
|
||
}
|
||
|
||
const Util::Array<Util::String>& builtIn = pMacro->GetBuiltInMacroName();
|
||
|
||
Util::String sBuiltIn;
|
||
sBuiltIn += "\"";
|
||
|
||
if (iPass == 0 && bTemplate)
|
||
{
|
||
for (IndexT i = 0; i < builtIn.Size(); ++i)
|
||
{
|
||
sBuiltIn += builtIn[i] + " ";
|
||
}
|
||
}
|
||
|
||
|
||
sBuiltIn += "\"";
|
||
|
||
m_BuiltInMacro.Add(iPass, sBuiltIn);
|
||
|
||
|
||
}
|
||
|
||
} |