Add support to the HLSL translator to output interface blocks to constant…

Add support to the HLSL translator to output interface blocks to constant buffers, using HLSL register packing rules. 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@2344 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 61aaf24d
......@@ -7,6 +7,7 @@
#include "compiler/OutputHLSL.h"
#include "common/angleutils.h"
#include "common/utilities.h"
#include "compiler/debug.h"
#include "compiler/DetectDiscontinuity.h"
#include "compiler/InfoSink.h"
......@@ -113,6 +114,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
}
mSamplerRegister = 0;
mInterfaceBlockRegister = 2; // Reserve registers for the default uniform block and driver constants
}
OutputHLSL::~OutputHLSL()
......@@ -141,6 +143,11 @@ const ActiveUniforms &OutputHLSL::getUniforms()
return mActiveUniforms;
}
const ActiveInterfaceBlocks &OutputHLSL::getInterfaceBlocks() const
{
return mActiveInterfaceBlocks;
}
int OutputHLSL::vectorSize(const TType &type) const
{
int elementSize = type.isMatrix() ? type.getNominalSize() : 1;
......@@ -165,6 +172,7 @@ void OutputHLSL::header()
}
TString uniforms;
TString interfaceBlocks;
TString varyings;
TString attributes;
......@@ -180,7 +188,7 @@ void OutputHLSL::header()
uniforms += "uniform SamplerState sampler_" + decorateUniform(name, type) + arrayString(type) +
" : register(s" + str(index) + ");\n";
uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
" : register(t" + str(index) + ");\n";
}
else
......@@ -190,6 +198,36 @@ void OutputHLSL::header()
}
}
for (ReferencedSymbols::const_iterator interfaceBlockIt = mReferencedInterfaceBlocks.begin(); interfaceBlockIt != mReferencedInterfaceBlocks.end(); interfaceBlockIt++)
{
const TType &interfaceBlockType = *interfaceBlockIt->second->getType().getInterfaceBlockType();
const TString &blockName = interfaceBlockType.getTypeName();
const TTypeList &typeList = *interfaceBlockType.getStruct();
sh::InterfaceBlock interfaceBlock(blockName.c_str(), 0, mInterfaceBlockRegister++);
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
{
const TType &memberType = *typeList[typeIndex].type;
declareUniformToList(memberType, memberType.getFieldName(), typeIndex, interfaceBlock.activeUniforms);
}
// TODO: handle other block layouts
interfaceBlock.setPackedBlockLayout();
mActiveInterfaceBlocks.push_back(interfaceBlock);
interfaceBlocks += "cbuffer " + blockName + " : register(b" + str(interfaceBlock.registerIndex) + ")\n"
"{\n";
for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
{
// TODO: padding for standard layout
const TType &memberType = *typeList[typeIndex].type;
interfaceBlocks += " " + typeString(memberType) + " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
}
interfaceBlocks += "};\n\n";
}
for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
{
const TType &type = varying->second->getType();
......@@ -310,6 +348,12 @@ void OutputHLSL::header()
out << uniforms;
out << "\n";
if (!interfaceBlocks.empty())
{
out << interfaceBlocks;
out << "\n";
}
if (mUsesTexture2D)
{
if (mOutputType == SH_HLSL9_OUTPUT)
......@@ -678,6 +722,12 @@ void OutputHLSL::header()
out << uniforms;
out << "\n";
if (!interfaceBlocks.empty())
{
out << interfaceBlocks;
out << "\n";
}
if (mUsesTexture2D)
{
if (mOutputType == SH_HLSL9_OUTPUT)
......@@ -1148,8 +1198,17 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
if (qualifier == EvqUniform)
{
mReferencedUniforms[name] = node;
out << decorateUniform(name, node->getType());
if (node->getType().isInterfaceBlockMember())
{
const TString& interfaceBlockTypeName = node->getType().getInterfaceBlockType()->getTypeName();
mReferencedInterfaceBlocks[interfaceBlockTypeName] = node;
out << decorateUniform(name, node->getType());
}
else
{
mReferencedUniforms[name] = node;
out << decorateUniform(name, node->getType());
}
}
else if (qualifier == EvqAttribute)
{
......
......@@ -33,6 +33,7 @@ class OutputHLSL : public TIntermTraverser
TInfoSinkBase &getBodyStream();
const ActiveUniforms &getUniforms();
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
TString typeString(const TType &type);
TString textureString(const TType &type);
......@@ -84,6 +85,7 @@ class OutputHLSL : public TIntermTraverser
typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
ReferencedSymbols mReferencedUniforms;
ReferencedSymbols mReferencedInterfaceBlocks;
ReferencedSymbols mReferencedAttributes;
ReferencedSymbols mReferencedVaryings;
......@@ -163,6 +165,7 @@ class OutputHLSL : public TIntermTraverser
TIntermSymbol *mExcessiveLoopIndex;
int mUniformRegister;
int mInterfaceBlockRegister;
int mSamplerRegister;
TString registerString(TIntermSymbol *operand);
......@@ -178,6 +181,7 @@ class OutputHLSL : public TIntermTraverser
static bool isVarying(TQualifier qualifier);
ActiveUniforms mActiveUniforms;
ActiveInterfaceBlocks mActiveInterfaceBlocks;
};
}
......
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