Commit f91ce811 by Jamie Madill

Split OutputHLSL uniform code into new module.

Refactoring patch only, should have no externally visible changes. BUG=angle:466 Change-Id: I01088a3b2979b96702d0a3c424d26928eb72b5b2 Reviewed-on: https://chromium-review.googlesource.com/203731Reviewed-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8daaba15
...@@ -180,6 +180,7 @@ ...@@ -180,6 +180,7 @@
<ClInclude Include="..\..\src\compiler\translator\InitializeParseContext.h"/> <ClInclude Include="..\..\src\compiler\translator\InitializeParseContext.h"/>
<ClInclude Include="..\..\src\compiler\translator\VariableInfo.h"/> <ClInclude Include="..\..\src\compiler\translator\VariableInfo.h"/>
<ClInclude Include="..\..\src\compiler\translator\LoopInfo.h"/> <ClInclude Include="..\..\src\compiler\translator\LoopInfo.h"/>
<ClInclude Include="..\..\src\compiler\translator\UniformHLSL.h"/>
<ClInclude Include="..\..\src\compiler\translator\glslang_tab.h"/> <ClInclude Include="..\..\src\compiler\translator\glslang_tab.h"/>
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"/> <ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"/>
<ClInclude Include="..\..\src\compiler\translator\ExtensionBehavior.h"/> <ClInclude Include="..\..\src\compiler\translator\ExtensionBehavior.h"/>
...@@ -252,6 +253,7 @@ ...@@ -252,6 +253,7 @@
<ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp"/> <ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\StructureHLSL.cpp"/> <ClCompile Include="..\..\src\compiler\translator\StructureHLSL.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\UnfoldShortCircuit.cpp"/> <ClCompile Include="..\..\src\compiler\translator\UnfoldShortCircuit.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\UniformHLSL.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp"/> <ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\VariableInfo.cpp"/> <ClCompile Include="..\..\src\compiler\translator\VariableInfo.cpp"/>
<ClCompile Include="..\..\src\compiler\translator\Compiler.cpp"/> <ClCompile Include="..\..\src\compiler\translator\Compiler.cpp"/>
......
...@@ -390,6 +390,9 @@ ...@@ -390,6 +390,9 @@
<ClInclude Include="..\..\src\compiler\translator\LoopInfo.h"> <ClInclude Include="..\..\src\compiler\translator\LoopInfo.h">
<Filter>src\compiler\translator</Filter> <Filter>src\compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\compiler\translator\UniformHLSL.h">
<Filter>src\compiler\translator</Filter>
</ClInclude>
<ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp"> <ClCompile Include="..\..\src\compiler\translator\DetectDiscontinuity.cpp">
<Filter>src\compiler\translator</Filter> <Filter>src\compiler\translator</Filter>
</ClCompile> </ClCompile>
...@@ -405,6 +408,9 @@ ...@@ -405,6 +408,9 @@
<ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h"> <ClInclude Include="..\..\src\compiler\translator\RewriteElseBlocks.h">
<Filter>src\compiler\translator</Filter> <Filter>src\compiler\translator</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\compiler\translator\UniformHLSL.cpp">
<Filter>src\compiler\translator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp"> <ClCompile Include="..\..\src\compiler\translator\compilerdebug.cpp">
<Filter>src\compiler\translator</Filter> <Filter>src\compiler\translator</Filter>
</ClCompile> </ClCompile>
......
...@@ -69,7 +69,7 @@ class Std140BlockEncoder : public BlockLayoutEncoder ...@@ -69,7 +69,7 @@ class Std140BlockEncoder : public BlockLayoutEncoder
// Block layout packed according to the D3D9 or default D3D10+ register packing rules // Block layout packed according to the D3D9 or default D3D10+ register packing rules
// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
// The strategy should be ENCODE_LOOSE for D3D9 constnat blocks, and ENCODE_PACKED // The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
// for everything else (D3D10+ constant blocks and all attributes/varyings). // for everything else (D3D10+ constant blocks and all attributes/varyings).
class HLSLBlockEncoder : public BlockLayoutEncoder class HLSLBlockEncoder : public BlockLayoutEncoder
......
...@@ -58,9 +58,11 @@ struct ShaderVariable ...@@ -58,9 +58,11 @@ struct ShaderVariable
// Uniform registers (and element indices) are assigned when outputting shader code // Uniform registers (and element indices) are assigned when outputting shader code
struct Uniform : public ShaderVariable struct Uniform : public ShaderVariable
{ {
std::vector<Uniform> fields;
// HLSL-specific members
unsigned int registerIndex; unsigned int registerIndex;
unsigned int elementIndex; // Offset within a register, for struct members unsigned int elementIndex; // Offset within a register, for struct members
std::vector<Uniform> fields;
Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn,
unsigned int registerIndexIn, unsigned int elementIndexIn) unsigned int registerIndexIn, unsigned int elementIndexIn)
...@@ -146,6 +148,7 @@ struct InterfaceBlock ...@@ -146,6 +148,7 @@ struct InterfaceBlock
std::vector<InterfaceBlockField> fields; std::vector<InterfaceBlockField> fields;
std::vector<BlockMemberInfo> blockInfo; std::vector<BlockMemberInfo> blockInfo;
// HLSL-specific members
unsigned int registerIndex; unsigned int registerIndex;
InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex) InterfaceBlock(const char *name, unsigned int arraySize, unsigned int registerIndex)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "compiler/translator/RewriteElseBlocks.h" #include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/UtilsHLSL.h" #include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
#include "compiler/translator/UniformHLSL.h"
#include "compiler/translator/StructureHLSL.h" #include "compiler/translator/StructureHLSL.h"
#include <algorithm> #include <algorithm>
...@@ -72,18 +73,6 @@ TString OutputHLSL::TextureFunction::name() const ...@@ -72,18 +73,6 @@ TString OutputHLSL::TextureFunction::name() const
return name + "("; return name + "(";
} }
const char *RegisterPrefix(const TType &type)
{
if (IsSampler(type.getBasicType()))
{
return "s";
}
else
{
return "c";
}
}
bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
{ {
if (sampler < rhs.sampler) return true; if (sampler < rhs.sampler) return true;
...@@ -149,31 +138,31 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc ...@@ -149,31 +138,31 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mExcessiveLoopIndex = NULL; mExcessiveLoopIndex = NULL;
mStructureHLSL = new StructureHLSL; mStructureHLSL = new StructureHLSL;
mUniformHLSL = new UniformHLSL(mStructureHLSL, mOutputType);
if (mOutputType == SH_HLSL9_OUTPUT) if (mOutputType == SH_HLSL9_OUTPUT)
{ {
if (mContext.shaderType == SH_FRAGMENT_SHADER) if (mContext.shaderType == SH_FRAGMENT_SHADER)
{ {
mUniformRegister = 3; // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
mUniformHLSL->reserveUniformRegisters(3);
} }
else else
{ {
mUniformRegister = 2; // Reserve registers for dx_DepthRange and dx_ViewAdjust // Reserve registers for dx_DepthRange and dx_ViewAdjust
mUniformHLSL->reserveUniformRegisters(2);
} }
} }
else
{
mUniformRegister = 0;
}
mSamplerRegister = 0; // Reserve registers for the default uniform block and driver constants
mInterfaceBlockRegister = 2; // Reserve registers for the default uniform block and driver constants mUniformHLSL->reserveInterfaceBlockRegisters(2);
} }
OutputHLSL::~OutputHLSL() OutputHLSL::~OutputHLSL()
{ {
SafeDelete(mUnfoldShortCircuit); SafeDelete(mUnfoldShortCircuit);
SafeDelete(mStructureHLSL); SafeDelete(mStructureHLSL);
SafeDelete(mUniformHLSL);
} }
void OutputHLSL::output() void OutputHLSL::output()
...@@ -225,12 +214,12 @@ TInfoSinkBase &OutputHLSL::getBodyStream() ...@@ -225,12 +214,12 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
const std::vector<gl::Uniform> &OutputHLSL::getUniforms() const std::vector<gl::Uniform> &OutputHLSL::getUniforms()
{ {
return mActiveUniforms; return mUniformHLSL->getUniforms();
} }
const std::vector<gl::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const const std::vector<gl::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const
{ {
return mActiveInterfaceBlocks; return mUniformHLSL->getInterfaceBlocks();
} }
const std::vector<gl::Attribute> &OutputHLSL::getOutputVariables() const const std::vector<gl::Attribute> &OutputHLSL::getOutputVariables() const
...@@ -256,170 +245,6 @@ int OutputHLSL::vectorSize(const TType &type) const ...@@ -256,170 +245,6 @@ int OutputHLSL::vectorSize(const TType &type) const
return elementSize * arraySize; return elementSize * arraySize;
} }
TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
TString OutputHLSL::interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlock)
{
return DecoratePrivate(interfaceBlock.name()) + "_type";
}
TString OutputHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex)
{
if (!interfaceBlock.hasInstanceName())
{
return "";
}
else if (interfaceBlock.isArray())
{
return DecoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
}
else
{
return Decorate(interfaceBlock.instanceName());
}
}
TString OutputHLSL::interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
{
const TType &fieldType = *field.type();
const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
ASSERT(matrixPacking != EmpUnspecified);
if (fieldType.isMatrix())
{
// Use HLSL row-major packing for GLSL column-major matrices
const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
return matrixPackString + " " + TypeString(fieldType);
}
else if (fieldType.getStruct())
{
// Use HLSL row-major packing for GLSL column-major matrices
return QualifiedStructNameString(*fieldType.getStruct(), matrixPacking == EmpColumnMajor,
blockStorage == EbsStd140);
}
else
{
return TypeString(fieldType);
}
}
TString OutputHLSL::interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage)
{
TString hlsl;
Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
{
const TField &field = *interfaceBlock.fields()[typeIndex];
const TType &fieldType = *field.type();
if (blockStorage == EbsStd140)
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += padHelper.prePaddingString(fieldType);
}
hlsl += " " + interfaceBlockFieldTypeString(field, blockStorage) +
" " + Decorate(field.name()) + ArrayString(fieldType) + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
if (blockStorage == EbsStd140)
{
const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking);
}
}
return hlsl;
}
TString OutputHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock)
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
return "struct " + interfaceBlockStructNameString(interfaceBlock) + "\n"
"{\n" +
interfaceBlockFieldString(interfaceBlock, blockStorage) +
"};\n\n";
}
TString OutputHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex)
{
const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : "");
const TString &blockName = interfaceBlock.name() + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
"{\n";
if (interfaceBlock.hasInstanceName())
{
hlsl += " " + interfaceBlockStructNameString(interfaceBlock) + " " + interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
}
else
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
hlsl += interfaceBlockFieldString(interfaceBlock, blockStorage);
}
hlsl += "};\n\n";
return hlsl;
}
// Use the same layout for packed and shared
void setBlockLayout(gl::InterfaceBlock *interfaceBlock, gl::BlockLayoutType newLayout)
{
interfaceBlock->layout = newLayout;
interfaceBlock->blockInfo.clear();
switch (newLayout)
{
case gl::BLOCKLAYOUT_SHARED:
case gl::BLOCKLAYOUT_PACKED:
{
gl::HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo, gl::HLSLBlockEncoder::ENCODE_PACKED);
hlslEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = hlslEncoder.getBlockSize();
}
break;
case gl::BLOCKLAYOUT_STANDARD:
{
gl::Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo);
stdEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = stdEncoder.getBlockSize();
}
break;
default:
UNREACHABLE();
break;
}
}
gl::BlockLayoutType convertBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return gl::BLOCKLAYOUT_PACKED;
case EbsShared: return gl::BLOCKLAYOUT_SHARED;
case EbsStd140: return gl::BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return gl::BLOCKLAYOUT_SHARED;
}
}
TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName) TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName)
{ {
TString init; TString init;
...@@ -465,84 +290,10 @@ void OutputHLSL::header() ...@@ -465,84 +290,10 @@ void OutputHLSL::header()
{ {
TInfoSinkBase &out = mHeader; TInfoSinkBase &out = mHeader;
TString uniforms;
TString interfaceBlocks;
TString varyings; TString varyings;
TString attributes; TString attributes;
TString flaggedStructs; TString flaggedStructs;
for (ReferencedSymbols::const_iterator uniformIt = mReferencedUniforms.begin(); uniformIt != mReferencedUniforms.end(); uniformIt++)
{
const TIntermSymbol &uniform = *uniformIt->second;
const TType &type = uniform.getType();
const TString &name = uniform.getSymbol();
int registerIndex = declareUniformAndAssignRegister(type, name);
if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture
{
uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) +
" : register(s" + str(registerIndex) + ");\n";
uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) +
" : register(t" + str(registerIndex) + ");\n";
}
else
{
const TStructure *structure = type.getStruct();
const TString &typeName = (structure ? QualifiedStructNameString(*structure, false, false) : TypeString(type));
const TString &registerString = TString("register(") + RegisterPrefix(type) + str(registerIndex) + ")";
uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n";
}
}
for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++)
{
const TType &nodeType = interfaceBlockIt->second->getType();
const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
const TFieldList &fieldList = interfaceBlock.fields();
unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
gl::InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize, mInterfaceBlockRegister);
for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{
const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = interfaceBlockFieldString(interfaceBlock, field);
declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
}
mInterfaceBlockRegister += std::max(1u, arraySize);
gl::BlockLayoutType blockLayoutType = convertBlockLayoutType(interfaceBlock.blockStorage());
setBlockLayout(&activeBlock, blockLayoutType);
if (interfaceBlock.matrixPacking() == EmpRowMajor)
{
activeBlock.isRowMajorLayout = true;
}
mActiveInterfaceBlocks.push_back(activeBlock);
if (interfaceBlock.hasInstanceName())
{
interfaceBlocks += interfaceBlockStructString(interfaceBlock);
}
if (arraySize > 0)
{
for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex + arrayIndex, arrayIndex);
}
}
else
{
interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex, GL_INVALID_INDEX);
}
}
for (std::map<TIntermTyped*, TString>::const_iterator flaggedStructIt = mFlaggedStructMappedNames.begin(); flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++) for (std::map<TIntermTyped*, TString>::const_iterator flaggedStructIt = mFlaggedStructMappedNames.begin(); flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++)
{ {
TIntermTyped *structNode = flaggedStructIt->first; TIntermTyped *structNode = flaggedStructIt->first;
...@@ -581,6 +332,9 @@ void OutputHLSL::header() ...@@ -581,6 +332,9 @@ void OutputHLSL::header()
out << mStructureHLSL->structsHeader(); out << mStructureHLSL->structsHeader();
out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms);
out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks);
if (mUsesDiscardRewriting) if (mUsesDiscardRewriting)
{ {
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
...@@ -715,22 +469,13 @@ void OutputHLSL::header() ...@@ -715,22 +469,13 @@ void OutputHLSL::header()
out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
"\n"; "\n";
} }
out << uniforms;
out << "\n";
if (!interfaceBlocks.empty()) if (!flaggedStructs.empty())
{ {
out << interfaceBlocks; out << "// Std140 Structures accessed by value\n";
out << "\n";
out << flaggedStructs;
out << "\n"; out << "\n";
if (!flaggedStructs.empty())
{
out << "// Std140 Structures accessed by value\n";
out << "\n";
out << flaggedStructs;
out << "\n";
}
} }
if (usingMRTExtension && mNumRenderTargets > 1) if (usingMRTExtension && mNumRenderTargets > 1)
...@@ -754,7 +499,7 @@ void OutputHLSL::header() ...@@ -754,7 +499,7 @@ void OutputHLSL::header()
out << attributes; out << attributes;
out << "\n" out << "\n"
"static float4 gl_Position = float4(0, 0, 0, 0);\n"; "static float4 gl_Position = float4(0, 0, 0, 0);\n";
if (mUsesPointSize) if (mUsesPointSize)
{ {
out << "static float gl_PointSize = float(1);\n"; out << "static float gl_PointSize = float(1);\n";
...@@ -804,21 +549,12 @@ void OutputHLSL::header() ...@@ -804,21 +549,12 @@ void OutputHLSL::header()
"\n"; "\n";
} }
out << uniforms; if (!flaggedStructs.empty())
out << "\n";
if (!interfaceBlocks.empty())
{ {
out << interfaceBlocks; out << "// Std140 Structures accessed by value\n";
out << "\n";
out << flaggedStructs;
out << "\n"; out << "\n";
if (!flaggedStructs.empty())
{
out << "// Std140 Structures accessed by value\n";
out << "\n";
out << flaggedStructs;
out << "\n";
}
} }
} }
...@@ -1288,7 +1024,7 @@ void OutputHLSL::header() ...@@ -1288,7 +1024,7 @@ void OutputHLSL::header()
case 3: out << "int4("; break; case 3: out << "int4("; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
// Convert from normalized floating-point to integer // Convert from normalized floating-point to integer
if (textureFunction->method != TextureFunction::FETCH) if (textureFunction->method != TextureFunction::FETCH)
{ {
...@@ -1323,7 +1059,7 @@ void OutputHLSL::header() ...@@ -1323,7 +1059,7 @@ void OutputHLSL::header()
} }
TString proj = ""; // Only used for projected textures TString proj = ""; // Only used for projected textures
if (textureFunction->proj) if (textureFunction->proj)
{ {
switch(textureFunction->coords) switch(textureFunction->coords)
...@@ -1507,7 +1243,7 @@ void OutputHLSL::header() ...@@ -1507,7 +1243,7 @@ void OutputHLSL::header()
"}\n" "}\n"
"\n"; "\n";
} }
if (mUsesMod3v) if (mUsesMod3v)
{ {
out << "float3 mod(float3 x, float3 y)\n" out << "float3 mod(float3 x, float3 y)\n"
...@@ -1811,7 +1547,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1811,7 +1547,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{ {
out << " = mul("; out << " = mul(";
node->getLeft()->traverse(this); node->getLeft()->traverse(this);
out << ", transpose("; out << ", transpose(";
} }
else else
{ {
...@@ -1827,7 +1563,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1827,7 +1563,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{ {
out << " = mul("; out << " = mul(";
node->getLeft()->traverse(this); node->getLeft()->traverse(this);
out << ", "; out << ", ";
} }
else else
{ {
...@@ -1844,10 +1580,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1844,10 +1580,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{ {
TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock(); TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock();
const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0); const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode(); mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode();
out << interfaceBlockInstanceString(*interfaceBlock, arrayIndex); out << mUniformHLSL->interfaceBlockInstanceString(*interfaceBlock, arrayIndex);
return false; return false;
} }
} }
...@@ -2282,14 +2016,14 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2282,14 +2016,14 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
out << ")\n" out << ")\n"
"{\n"; "{\n";
if (sequence.size() > 1) if (sequence.size() > 1)
{ {
mInsideFunction = true; mInsideFunction = true;
sequence[1]->traverse(this); sequence[1]->traverse(this);
mInsideFunction = false; mInsideFunction = false;
} }
out << "}\n"; out << "}\n";
if (mContainsLoopDiscontinuity && !mOutputLod0Function) if (mContainsLoopDiscontinuity && !mOutputLod0Function)
...@@ -2542,7 +2276,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2542,7 +2276,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case 4: mUsesFaceforward4 = true; break; case 4: mUsesFaceforward4 = true; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
outputTriplet(visit, "faceforward(", ", ", ")"); outputTriplet(visit, "faceforward(", ", ", ")");
} }
break; break;
...@@ -2572,7 +2306,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) ...@@ -2572,7 +2306,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine().first_line); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
...@@ -2655,7 +2389,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2655,7 +2389,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
else else
{ {
out << "{for("; out << "{for(";
if (node->getInit()) if (node->getInit())
{ {
node->getInit()->traverse(this); node->getInit()->traverse(this);
...@@ -2676,7 +2410,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2676,7 +2410,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
} }
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine().first_line); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
} }
...@@ -2851,7 +2585,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2851,7 +2585,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (index != NULL && node->getCondition()) if (index != NULL && node->getCondition())
{ {
TIntermBinary *test = node->getCondition()->getAsBinaryNode(); TIntermBinary *test = node->getCondition()->getAsBinaryNode();
if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId()) if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
{ {
TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion(); TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
...@@ -2872,7 +2606,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2872,7 +2606,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
{ {
TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode(); TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
if (binaryTerminal) if (binaryTerminal)
{ {
TOperator op = binaryTerminal->getOp(); TOperator op = binaryTerminal->getOp();
...@@ -2952,7 +2686,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2952,7 +2686,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
{ {
mExcessiveLoopIndex = NULL; // Stops setting the Break flag mExcessiveLoopIndex = NULL; // Stops setting the Break flag
} }
// for(int index = initial; index < clampedLimit; index += increment) // for(int index = initial; index < clampedLimit; index += increment)
out << "for("; out << "for(";
...@@ -2970,7 +2704,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2970,7 +2704,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
out << " += "; out << " += ";
out << increment; out << increment;
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine().first_line); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
...@@ -2992,7 +2726,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2992,7 +2726,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
initial += MAX_LOOP_ITERATIONS * increment; initial += MAX_LOOP_ITERATIONS * increment;
iterations -= MAX_LOOP_ITERATIONS; iterations -= MAX_LOOP_ITERATIONS;
} }
out << "}"; out << "}";
mExcessiveLoopIndex = restoreIndex; mExcessiveLoopIndex = restoreIndex;
...@@ -3034,7 +2768,7 @@ void OutputHLSL::outputLineDirective(int line) ...@@ -3034,7 +2768,7 @@ void OutputHLSL::outputLineDirective(int line)
{ {
mBody << " \"" << mContext.sourcePath << "\""; mBody << " \"" << mContext.sourcePath << "\"";
} }
mBody << "\n"; mBody << "\n";
} }
} }
...@@ -3057,7 +2791,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) ...@@ -3057,7 +2791,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))
{ {
return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + name + ArrayString(type) + ", " + return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + name + ArrayString(type) + ", " +
QualifierString(qualifier) + " " + SamplerString(type) + " sampler_" + name + ArrayString(type); QualifierString(qualifier) + " " + SamplerString(type) + " sampler_" + name + ArrayString(type);
} }
return QualifierString(qualifier) + " " + TypeString(type) + " " + name + ArrayString(type); return QualifierString(qualifier) + " " + TypeString(type) + " " + name + ArrayString(type);
...@@ -3109,13 +2843,12 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3109,13 +2843,12 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
if (structure) if (structure)
{ {
out << StructNameString(*structure) + "_ctor("; out << StructNameString(*structure) + "_ctor(";
const TFieldList& fields = structure->fields(); const TFieldList& fields = structure->fields();
for (size_t i = 0; i < fields.size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
const TType *fieldType = fields[i]->type(); const TType *fieldType = fields[i]->type();
constUnion = writeConstantUnion(*fieldType, constUnion); constUnion = writeConstantUnion(*fieldType, constUnion);
if (i != fields.size() - 1) if (i != fields.size() - 1)
...@@ -3130,7 +2863,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3130,7 +2863,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
{ {
size_t size = type.getObjectSize(); size_t size = type.getObjectSize();
bool writeType = size > 1; bool writeType = size > 1;
if (writeType) if (writeType)
{ {
out << TypeString(type) << "("; out << TypeString(type) << "(";
...@@ -3162,74 +2895,6 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3162,74 +2895,6 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion; return constUnion;
} }
void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
gl::InterfaceBlockField field(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), isRowMajorMatrix);
output.push_back(field);
}
else
{
gl::InterfaceBlockField structField(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), false);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
// make sure to copy matrix packing information
fieldType->setLayoutQualifier(type.getLayoutQualifier());
declareInterfaceBlockField(*fieldType, field->name(), structField.fields);
}
output.push_back(structField);
}
}
gl::Uniform OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
gl::Uniform uniform(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0);
output.push_back(uniform);
return uniform;
}
else
{
gl::Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(),
(unsigned int)registerIndex, GL_INVALID_INDEX);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, structUniform.fields);
}
// assign register offset information -- this will override the information in any sub-structures.
HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType);
output.push_back(structUniform);
return structUniform;
}
}
void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut) void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut)
{ {
const TStructure *structure = type.getStruct(); const TStructure *structure = type.getStruct();
...@@ -3257,22 +2922,4 @@ void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQual ...@@ -3257,22 +2922,4 @@ void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQual
} }
} }
int OutputHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
{
int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
const gl::Uniform &uniform = declareUniformToList(type, name, registerIndex, mActiveUniforms);
if (IsSampler(type.getBasicType()))
{
mSamplerRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
}
else
{
mUniformRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
}
return registerIndex;
}
} }
...@@ -22,6 +22,9 @@ namespace sh ...@@ -22,6 +22,9 @@ namespace sh
{ {
class UnfoldShortCircuit; class UnfoldShortCircuit;
class StructureHLSL; class StructureHLSL;
class UniformHLSL;
typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
class OutputHLSL : public TIntermTraverser class OutputHLSL : public TIntermTraverser
{ {
...@@ -74,7 +77,6 @@ class OutputHLSL : public TIntermTraverser ...@@ -74,7 +77,6 @@ class OutputHLSL : public TIntermTraverser
TInfoSinkBase mBody; TInfoSinkBase mBody;
TInfoSinkBase mFooter; TInfoSinkBase mFooter;
typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
ReferencedSymbols mReferencedUniforms; ReferencedSymbols mReferencedUniforms;
ReferencedSymbols mReferencedInterfaceBlocks; ReferencedSymbols mReferencedInterfaceBlocks;
ReferencedSymbols mReferencedAttributes; ReferencedSymbols mReferencedAttributes;
...@@ -82,6 +84,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -82,6 +84,7 @@ class OutputHLSL : public TIntermTraverser
ReferencedSymbols mReferencedOutputVariables; ReferencedSymbols mReferencedOutputVariables;
StructureHLSL *mStructureHLSL; StructureHLSL *mStructureHLSL;
UniformHLSL *mUniformHLSL;
struct TextureFunction struct TextureFunction
{ {
...@@ -150,32 +153,10 @@ class OutputHLSL : public TIntermTraverser ...@@ -150,32 +153,10 @@ class OutputHLSL : public TIntermTraverser
TIntermSymbol *mExcessiveLoopIndex; TIntermSymbol *mExcessiveLoopIndex;
int mUniformRegister;
int mInterfaceBlockRegister;
int mSamplerRegister;
TString registerString(TIntermSymbol *operand);
int samplerRegister(TIntermSymbol *sampler);
int uniformRegister(TIntermSymbol *uniform);
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output);
gl::Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output);
void declareUniform(const TType &type, const TString &name, int index);
void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut); void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut);
// Returns the uniform's register index
int declareUniformAndAssignRegister(const TType &type, const TString &name);
TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType);
TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
TString interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage);
TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName); TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
std::vector<gl::Uniform> mActiveUniforms;
std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks;
std::vector<gl::Attribute> mActiveOutputVariables; std::vector<gl::Attribute> mActiveOutputVariables;
std::vector<gl::Attribute> mActiveAttributes; std::vector<gl::Attribute> mActiveAttributes;
std::vector<gl::Varying> mActiveVaryings; std::vector<gl::Varying> mActiveVaryings;
......
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UniformHLSL.cpp:
// Methods for GLSL to HLSL translation for uniforms and interface blocks.
//
#include "OutputHLSL.h"
#include "common/blocklayout.h"
#include "common/utilities.h"
#include "compiler/translator/UniformHLSL.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/util.h"
#include "compiler/translator/UtilsHLSL.h"
namespace sh
{
// Use the same layout for packed and shared
static void SetBlockLayout(gl::InterfaceBlock *interfaceBlock, gl::BlockLayoutType newLayout)
{
interfaceBlock->layout = newLayout;
interfaceBlock->blockInfo.clear();
switch (newLayout)
{
case gl::BLOCKLAYOUT_SHARED:
case gl::BLOCKLAYOUT_PACKED:
{
gl::HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo, gl::HLSLBlockEncoder::ENCODE_PACKED);
hlslEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = hlslEncoder.getBlockSize();
}
break;
case gl::BLOCKLAYOUT_STANDARD:
{
gl::Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo);
stdEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = stdEncoder.getBlockSize();
}
break;
default:
UNREACHABLE();
break;
}
}
static gl::BlockLayoutType ConvertBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return gl::BLOCKLAYOUT_PACKED;
case EbsShared: return gl::BLOCKLAYOUT_SHARED;
case EbsStd140: return gl::BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return gl::BLOCKLAYOUT_SHARED;
}
}
static const char *UniformRegisterPrefix(const TType &type)
{
if (IsSampler(type.getBasicType()))
{
return "s";
}
else
{
return "c";
}
}
static TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
{
const TType &fieldType = *field.type();
const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
ASSERT(matrixPacking != EmpUnspecified);
TStructure *structure = fieldType.getStruct();
if (fieldType.isMatrix())
{
// Use HLSL row-major packing for GLSL column-major matrices
const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
return matrixPackString + " " + TypeString(fieldType);
}
else if (structure)
{
// Use HLSL row-major packing for GLSL column-major matrices
return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
blockStorage == EbsStd140);
}
else
{
return TypeString(fieldType);
}
}
static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
{
return DecoratePrivate(interfaceBlock.name()) + "_type";
}
UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType)
: mUniformRegister(0),
mInterfaceBlockRegister(0),
mSamplerRegister(0),
mStructureHLSL(structureHLSL),
mOutputType(outputType)
{}
void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
{
mUniformRegister = registerCount;
}
void UniformHLSL::reserveInterfaceBlockRegisters(unsigned int registerCount)
{
mInterfaceBlockRegister = registerCount;
}
int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
{
int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
const gl::Uniform &uniform = declareUniformToList(type, name, registerIndex, &mActiveUniforms);
if (IsSampler(type.getBasicType()))
{
mSamplerRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
}
else
{
mUniformRegister += gl::HLSLVariableRegisterCount(uniform, mOutputType);
}
return registerIndex;
}
gl::Uniform UniformHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform> *output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
gl::Uniform uniform(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0);
output->push_back(uniform);
return uniform;
}
else
{
gl::Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(),
(unsigned int)registerIndex, GL_INVALID_INDEX);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, &structUniform.fields);
}
// assign register offset information -- this will override the information in any sub-structures.
HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType);
output->push_back(structUniform);
return structUniform;
}
}
TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms)
{
TString uniforms;
for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin();
uniformIt != referencedUniforms.end(); uniformIt++)
{
const TIntermSymbol &uniform = *uniformIt->second;
const TType &type = uniform.getType();
const TString &name = uniform.getSymbol();
int registerIndex = declareUniformAndAssignRegister(type, name);
if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture
{
uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) +
" : register(s" + str(registerIndex) + ");\n";
uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) +
" : register(t" + str(registerIndex) + ");\n";
}
else
{
const TStructure *structure = type.getStruct();
const TString &typeName = (structure ? QualifiedStructNameString(*structure, false, false) : TypeString(type));
const TString &registerString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n";
}
}
return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms));
}
TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
{
TString interfaceBlocks;
for (ReferencedSymbols::const_iterator interfaceBlockIt = referencedInterfaceBlocks.begin();
interfaceBlockIt != referencedInterfaceBlocks.end(); interfaceBlockIt++)
{
const TType &nodeType = interfaceBlockIt->second->getType();
const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock();
const TFieldList &fieldList = interfaceBlock.fields();
unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
gl::InterfaceBlock activeBlock(interfaceBlock.name().c_str(), arraySize, mInterfaceBlockRegister);
for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{
const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = InterfaceBlockFieldName(interfaceBlock, field);
declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
}
mInterfaceBlockRegister += std::max(1u, arraySize);
gl::BlockLayoutType blockLayoutType = ConvertBlockLayoutType(interfaceBlock.blockStorage());
SetBlockLayout(&activeBlock, blockLayoutType);
if (interfaceBlock.matrixPacking() == EmpRowMajor)
{
activeBlock.isRowMajorLayout = true;
}
mActiveInterfaceBlocks.push_back(activeBlock);
if (interfaceBlock.hasInstanceName())
{
interfaceBlocks += interfaceBlockStructString(interfaceBlock);
}
if (arraySize > 0)
{
for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex + arrayIndex, arrayIndex);
}
}
else
{
interfaceBlocks += interfaceBlockString(interfaceBlock, activeBlock.registerIndex, GL_INVALID_INDEX);
}
}
return (interfaceBlocks.empty() ? "" : ("// Interface Blocks\n\n" + interfaceBlocks));
}
TString UniformHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex)
{
const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : "");
const TString &blockName = interfaceBlock.name() + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
"{\n";
if (interfaceBlock.hasInstanceName())
{
hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " +
interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n";
}
else
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
hlsl += interfaceBlockMembersString(interfaceBlock, blockStorage);
}
hlsl += "};\n\n";
return hlsl;
}
TString UniformHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex)
{
if (!interfaceBlock.hasInstanceName())
{
return "";
}
else if (interfaceBlock.isArray())
{
return DecoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex);
}
else
{
return Decorate(interfaceBlock.instanceName());
}
}
TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage)
{
TString hlsl;
Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
{
const TField &field = *interfaceBlock.fields()[typeIndex];
const TType &fieldType = *field.type();
if (blockStorage == EbsStd140)
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += padHelper.prePadding(fieldType);
}
hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) +
" " + Decorate(field.name()) + ArrayString(fieldType) + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
if (blockStorage == EbsStd140)
{
const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking);
}
}
return hlsl;
}
TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock)
{
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
return "struct " + InterfaceBlockStructName(interfaceBlock) + "\n"
"{\n" +
interfaceBlockMembersString(interfaceBlock, blockStorage) +
"};\n\n";
}
void UniformHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
gl::InterfaceBlockField field(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), isRowMajorMatrix);
output.push_back(field);
}
else
{
gl::InterfaceBlockField structField(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), false);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
// make sure to copy matrix packing information
fieldType->setLayoutQualifier(type.getLayoutQualifier());
declareInterfaceBlockField(*fieldType, field->name(), structField.fields);
}
output.push_back(structField);
}
}
}
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UniformHLSL.h:
// Methods for GLSL to HLSL translation for uniforms and interface blocks.
//
#ifndef TRANSLATOR_UNIFORMHLSL_H_
#define TRANSLATOR_UNIFORMHLSL_H_
#include "common/shadervars.h"
#include "compiler/translator/Types.h"
namespace sh
{
class StructureHLSL;
class UniformHLSL
{
public:
UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType);
void reserveUniformRegisters(unsigned int registerCount);
void reserveInterfaceBlockRegisters(unsigned int registerCount);
TString uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms);
TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
// Used for direct index references
static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
const std::vector<gl::Uniform> &getUniforms() const { return mActiveUniforms; }
const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
private:
TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
TString interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
// Returns the uniform's register index
int declareUniformAndAssignRegister(const TType &type, const TString &name);
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output);
gl::Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform> *output);
unsigned int mUniformRegister;
unsigned int mInterfaceBlockRegister;
unsigned int mSamplerRegister;
StructureHLSL *mStructureHLSL;
ShShaderOutput mOutputType;
std::vector<gl::Uniform> mActiveUniforms;
std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks;
};
}
#endif // TRANSLATOR_UNIFORMHLSL_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment