Add support to the HLSL translator for arrays of named interface blocks.

TRAC #22930 Signed-off-by: Nicolas Capens Signed-off-by: Geoff Lang Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2347 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 3f68bf0e
......@@ -168,6 +168,81 @@ TString OutputHLSL::interfaceBlockUniformName(const TType &interfaceBlockType, c
}
}
TString OutputHLSL::decoratePrivate(const TString &privateText)
{
return "dx_" + privateText;
}
TString OutputHLSL::interfaceBlockStructName(const TType &interfaceBlockType)
{
return decoratePrivate(interfaceBlockType.getTypeName()) + "_type";
}
TString OutputHLSL::interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex)
{
if (!interfaceBlockType.hasInstanceName())
{
return "";
}
else if (interfaceBlockType.isArray())
{
return decoratePrivate(interfaceBlockType.getInstanceName()) + "_" + str(arrayIndex);
}
else
{
return decorate(interfaceBlockType.getInstanceName());
}
}
TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList)
{
TString hlsl;
// TODO: padding for standard layout
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
{
const TType &memberType = *typeList[typeIndex].type;
hlsl += " " + typeString(memberType) + " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
}
return hlsl;
}
TString OutputHLSL::interfaceBlockStructString(const TType &interfaceBlockType)
{
const TTypeList &typeList = *interfaceBlockType.getStruct();
return "struct " + interfaceBlockStructName(interfaceBlockType) + "\n"
"{\n" +
interfaceBlockMemberString(typeList) +
"};\n\n";
}
TString OutputHLSL::interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex)
{
const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? decorate(str(arrayIndex)) : "");
const TString &blockName = interfaceBlockType.getTypeName() + arrayIndexString;
TString hlsl;
hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n"
"{\n";
if (interfaceBlockType.hasInstanceName())
{
hlsl += " " + interfaceBlockStructName(interfaceBlockType) + " " + interfaceBlockInstanceString(interfaceBlockType, arrayIndex) + ";\n";
}
else
{
const TTypeList &typeList = *interfaceBlockType.getStruct();
hlsl += interfaceBlockMemberString(typeList);
}
hlsl += "};\n\n";
return hlsl;
}
void OutputHLSL::header()
{
ShShaderType shaderType = mContext.shaderType;
......@@ -185,6 +260,7 @@ void OutputHLSL::header()
TString uniforms;
TString interfaceBlocks;
TString interfaceBlockInit;
TString varyings;
TString attributes;
......@@ -217,7 +293,8 @@ void OutputHLSL::header()
const TString &blockName = interfaceBlockType.getTypeName();
const TTypeList &typeList = *interfaceBlockType.getStruct();
sh::InterfaceBlock interfaceBlock(blockName.c_str(), 0, mInterfaceBlockRegister++);
const unsigned int arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getArraySize() : 0;
sh::InterfaceBlock interfaceBlock(blockName.c_str(), arraySize, mInterfaceBlockRegister);
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
{
const TType &memberType = *typeList[typeIndex].type;
......@@ -225,31 +302,43 @@ void OutputHLSL::header()
declareUniformToList(memberType, fullUniformName, typeIndex, interfaceBlock.activeUniforms);
}
mInterfaceBlockRegister += std::max(1u, interfaceBlock.arraySize);
// TODO: handle other block layouts
interfaceBlock.setPackedBlockLayout();
mActiveInterfaceBlocks.push_back(interfaceBlock);
interfaceBlocks += "cbuffer " + blockName + " : register(b" + str(interfaceBlock.registerIndex) + ")\n"
"{\n";
if (interfaceBlockType.hasInstanceName())
{
interfaceBlocks += " struct {\n";
interfaceBlocks += interfaceBlockStructString(interfaceBlockType);
}
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
if (arraySize > 0)
{
// TODO: padding for standard layout
const TType &memberType = *typeList[typeIndex].type;
interfaceBlocks += " " + typeString(memberType) + " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
}
interfaceBlocks += "static " + interfaceBlockStructName(interfaceBlockType) + " " + decorate(interfaceBlockType.getInstanceName()) +
arrayString(interfaceBlockType) + ";\n\n";
if (interfaceBlockType.hasInstanceName())
for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex + arrayIndex, arrayIndex);
const TString &instanceName = interfaceBlockType.getInstanceName();
interfaceBlockInit += " " + decorate(instanceName) + "[" + str(arrayIndex) + "] = " +
interfaceBlockInstanceString(interfaceBlockType, arrayIndex) + ";\n";
}
}
else
{
interfaceBlocks += " } " + decorate(interfaceBlockType.getInstanceName()) + ";\n";
interfaceBlocks += interfaceBlockString(interfaceBlockType, interfaceBlock.registerIndex, GL_INVALID_INDEX);
}
}
interfaceBlocks += "};\n\n";
if (!interfaceBlockInit.empty())
{
interfaceBlocks += "void dx_initConstantBuffers()\n"
"{\n" +
interfaceBlockInit +
"}\n\n";
}
for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
......
......@@ -175,6 +175,12 @@ class OutputHLSL : public TIntermTraverser
void declareUniform(const TType &type, const TString &name, int index);
TString interfaceBlockUniformName(const TType &interfaceBlockType, const TType &uniformType);
TString decoratePrivate(const TString &privateText);
TString interfaceBlockStructName(const TType &interfaceBlockType);
TString interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex);
TString interfaceBlockMemberString(const TTypeList &typeList);
TString interfaceBlockStructString(const TType &interfaceBlockType);
TString interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex);
static GLenum glVariableType(const TType &type);
static GLenum glVariablePrecision(const TType &type);
......
......@@ -1686,6 +1686,11 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, TS
error(location, "", "[", "array must be redeclared with a size before being indexed with a variable");
recover();
}
else if (baseExpression->getBasicType() == EbtInterfaceBlock)
{
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
recover();
}
indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
}
......@@ -1700,7 +1705,9 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, TS
{
if (baseExpression->getType().getStruct())
{
indexedExpression->setType(TType(baseExpression->getType().getStruct(), baseExpression->getType().getTypeName()));
TType copyOfType(baseExpression->getType().getStruct(), baseExpression->getType().getTypeName());
copyOfType.setBasicType(baseExpression->getType().getBasicType()); // necessary to preserve interface block basic type
indexedExpression->setType(copyOfType);
}
else
{
......
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2013 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.
//
......@@ -208,7 +208,7 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
const TIntermSymbol* variable = (*i)->getAsSymbolNode();
// The only case in which the sequence will not contain a
// TIntermSymbol node is initialization. It will contain a
// TInterBinary node in that case. Since attributes and unifroms
// TIntermBinary node in that case. Since attributes and uniforms
// cannot be initialized in a shader, we must have only
// TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
......
......@@ -1178,6 +1178,12 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
}
if (vertexHLSL.find("dx_initConstantBuffers") != std::string::npos)
{
vertexHLSL += "\n"
" dx_initConstantBuffers();\n";
}
if (shaderModel >= 4)
{
vertexHLSL += "\n"
......@@ -1421,6 +1427,12 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
else UNREACHABLE();
}
if (pixelHLSL.find("dx_initConstantBuffers") != std::string::npos)
{
pixelHLSL += "\n"
" dx_initConstantBuffers();\n";
}
pixelHLSL += "\n"
" gl_main();\n"
"\n"
......
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