Commit 54ad4f81 by Jamie Madill

Use the CollectVariables path on the HLSL translator.

This approach consolidates our two methods, and lets us reuse the same code for both methods of variable collection. BUG=angle:466 Change-Id: Ie92f76ff0b6d0d0dbfd211a234d0ab86290fa798 Reviewed-on: https://chromium-review.googlesource.com/213504Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent 2ad1dc48
......@@ -83,6 +83,9 @@ class TCompiler : public TShHandleBase
ShShaderOutput getOutputType() const { return outputType; }
std::string getBuiltInResourcesString() const { return builtInResourcesString; }
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
protected:
sh::GLenum getShaderType() const { return shaderType; }
// Initialize symbol-table with built-in symbols.
......@@ -128,8 +131,6 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
const ArrayBoundsClamper& getArrayBoundsClamper() const;
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
......
......@@ -21,6 +21,7 @@
#include "compiler/translator/util.h"
#include "compiler/translator/UniformHLSL.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/TranslatorHLSL.h"
#include <algorithm>
#include <cfloat>
......@@ -29,18 +30,6 @@
namespace sh
{
static sh::Attribute MakeAttributeFromType(const TType &type, const TString &name)
{
sh::Attribute attributeVar;
attributeVar.type = GLVariableType(type);
attributeVar.precision = GLVariablePrecision(type);
attributeVar.name = name.c_str();
attributeVar.arraySize = static_cast<unsigned int>(type.getArraySize());
attributeVar.location = type.getLayoutQualifier().location;
return attributeVar;
}
TString OutputHLSL::TextureFunction::name() const
{
TString name = "gl_texture";
......@@ -105,8 +94,10 @@ bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
return false;
}
OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType)
: TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
: TIntermTraverser(true, true, true),
mContext(context),
mOutputType(parentTranslator->getOutputType())
{
mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
mInsideFunction = false;
......@@ -138,6 +129,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
const ShBuiltInResources &resources = parentTranslator->getResources();
mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
mUniqueIndex = 0;
......@@ -150,7 +142,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mExcessiveLoopIndex = NULL;
mStructureHLSL = new StructureHLSL;
mUniformHLSL = new UniformHLSL(mStructureHLSL, mOutputType);
mUniformHLSL = new UniformHLSL(mStructureHLSL, parentTranslator);
if (mOutputType == SH_HLSL9_OUTPUT)
{
......@@ -224,31 +216,6 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
return mBody;
}
const std::vector<sh::Uniform> &OutputHLSL::getUniforms()
{
return mUniformHLSL->getUniforms();
}
const std::vector<sh::InterfaceBlock> &OutputHLSL::getInterfaceBlocks() const
{
return mUniformHLSL->getInterfaceBlocks();
}
const std::vector<sh::Attribute> &OutputHLSL::getOutputVariables() const
{
return mActiveOutputVariables;
}
const std::vector<sh::Attribute> &OutputHLSL::getAttributes() const
{
return mActiveAttributes;
}
const std::vector<sh::Varying> &OutputHLSL::getVaryings() const
{
return mActiveVaryings;
}
const std::map<std::string, unsigned int> &OutputHLSL::getInterfaceBlockRegisterMap() const
{
return mUniformHLSL->getInterfaceBlockRegisterMap();
......@@ -336,8 +303,6 @@ void OutputHLSL::header()
// Program linking depends on this exact format
varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + " " +
Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
declareVaryingToList(type, type.getQualifier(), name, mActiveVaryings);
}
for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
......@@ -346,9 +311,6 @@ void OutputHLSL::header()
const TString &name = attribute->second->getSymbol();
attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n";
sh::Attribute attributeVar = MakeAttributeFromType(type, name);
mActiveAttributes.push_back(attributeVar);
}
out << mStructureHLSL->structsHeader();
......@@ -384,9 +346,6 @@ void OutputHLSL::header()
out << "static " + TypeString(variableType) + " out_" + variableName + ArrayString(variableType) +
" = " + initializer(variableType) + ";\n";
sh::Attribute outputVar = MakeAttributeFromType(variableType, variableName);
mActiveOutputVariables.push_back(outputVar);
}
}
else
......@@ -2922,12 +2881,4 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion;
}
void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier,
const TString &name, std::vector<Varying> &fieldsOut)
{
GetVariableTraverser traverser;
traverser.traverse(type, name, &fieldsOut);
fieldsOut.back().interpolation = GetInterpolationType(baseTypeQualifier);
}
}
......@@ -27,17 +27,12 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
class OutputHLSL : public TIntermTraverser
{
public:
OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator);
~OutputHLSL();
void output();
TInfoSinkBase &getBodyStream();
const std::vector<sh::Uniform> &getUniforms();
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
const std::vector<sh::Attribute> &getOutputVariables() const;
const std::vector<sh::Attribute> &getAttributes() const;
const std::vector<sh::Varying> &getVaryings() const;
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
......@@ -155,13 +150,8 @@ class OutputHLSL : public TIntermTraverser
TIntermSymbol *mExcessiveLoopIndex;
void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<sh::Varying>& fieldsOut);
TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
std::vector<sh::Attribute> mActiveOutputVariables;
std::vector<sh::Attribute> mActiveAttributes;
std::vector<sh::Varying> mActiveVaryings;
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
......
......@@ -17,16 +17,10 @@ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutpu
void TranslatorHLSL::translate(TIntermNode *root)
{
TParseContext& parseContext = *GetGlobalParseContext();
sh::OutputHLSL outputHLSL(parseContext, getResources(), getOutputType());
sh::OutputHLSL outputHLSL(parseContext, this);
outputHLSL.output();
attributes = outputHLSL.getAttributes();
outputVariables = outputHLSL.getOutputVariables();
uniforms = outputHLSL.getUniforms();
varyings = outputHLSL.getVaryings();
interfaceBlocks = outputHLSL.getInterfaceBlocks();
mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap();
mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
}
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/util.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/TranslatorHLSL.h"
namespace sh
{
......@@ -60,12 +61,13 @@ static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
return DecoratePrivate(interfaceBlock.name()) + "_type";
}
UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType)
UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator)
: mUniformRegister(0),
mInterfaceBlockRegister(0),
mSamplerRegister(0),
mStructureHLSL(structureHLSL),
mOutputType(outputType)
mOutputType(translator->getOutputType()),
mUniforms(translator->getUniforms())
{}
void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
......@@ -78,18 +80,32 @@ void UniformHLSL::reserveInterfaceBlockRegisters(unsigned int registerCount)
mInterfaceBlockRegister = registerCount;
}
const Uniform *UniformHLSL::findUniformByName(const TString &name) const
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
if (mUniforms[uniformIndex].name == name.c_str())
{
return &mUniforms[uniformIndex];
}
}
UNREACHABLE();
return NULL;
}
unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
{
unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
GetVariableTraverser traverser;
traverser.traverse(type, name, &mActiveUniforms);
const Uniform *uniform = findUniformByName(name);
ASSERT(uniform);
const sh::Uniform &activeUniform = mActiveUniforms.back();
mUniformRegisterMap[activeUniform.name] = registerIndex;
mUniformRegisterMap[uniform->name] = registerIndex;
unsigned int registerCount = HLSLVariableRegisterCount(activeUniform, mOutputType);
if (IsSampler(type.getBasicType()))
unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
if (gl::IsSampler(uniform->type))
{
mSamplerRegister += registerCount;
}
......@@ -154,23 +170,10 @@ TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedIn
unsigned int arraySize = static_cast<unsigned int>(interfaceBlock.arraySize());
unsigned int activeRegister = mInterfaceBlockRegister;
InterfaceBlock activeBlock;
activeBlock.name = interfaceBlock.name().c_str();
activeBlock.arraySize = arraySize;
GetInterfaceBlockFields(interfaceBlock, &activeBlock.fields);
mInterfaceBlockRegisterMap[activeBlock.name] = activeRegister;
mInterfaceBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister;
mInterfaceBlockRegister += std::max(1u, arraySize);
activeBlock.layout = GetBlockLayoutType(interfaceBlock.blockStorage());
if (interfaceBlock.matrixPacking() == EmpRowMajor)
{
activeBlock.isRowMajorLayout = true;
}
mActiveInterfaceBlocks.push_back(activeBlock);
// FIXME: interface block field names
if (interfaceBlock.hasInstanceName())
{
......
......@@ -19,7 +19,7 @@ class StructureHLSL;
class UniformHLSL
{
public:
UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType);
UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator);
void reserveUniformRegisters(unsigned int registerCount);
void reserveInterfaceBlockRegisters(unsigned int registerCount);
......@@ -29,8 +29,6 @@ class UniformHLSL
// Used for direct index references
static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
const std::vector<Uniform> &getUniforms() const { return mActiveUniforms; }
const std::vector<InterfaceBlock> &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const
{
return mInterfaceBlockRegisterMap;
......@@ -44,6 +42,7 @@ class UniformHLSL
TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
TString interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
const Uniform *findUniformByName(const TString &name) const;
// Returns the uniform's register index
unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name);
......@@ -54,8 +53,7 @@ class UniformHLSL
StructureHLSL *mStructureHLSL;
ShShaderOutput mOutputType;
std::vector<Uniform> mActiveUniforms;
std::vector<InterfaceBlock> mActiveInterfaceBlocks;
const std::vector<Uniform> &mUniforms;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;
};
......
......@@ -9,17 +9,43 @@
#include "compiler/translator/util.h"
#include "common/utilities.h"
static void ExpandUserDefinedVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded);
static void ExpandVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded)
namespace
{
TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
sh::BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return sh::BLOCKLAYOUT_PACKED;
case EbsShared: return sh::BLOCKLAYOUT_SHARED;
case EbsStd140: return sh::BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return sh::BLOCKLAYOUT_SHARED;
}
}
void ExpandUserDefinedVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded);
void ExpandVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded)
{
if (variable.isStruct())
{
......@@ -60,11 +86,11 @@ static void ExpandVariable(const sh::ShaderVariable &variable,
}
}
static void ExpandUserDefinedVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded)
void ExpandUserDefinedVariable(const sh::ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<sh::ShaderVariable> *expanded)
{
ASSERT(variable.isStruct());
......@@ -82,8 +108,8 @@ static void ExpandUserDefinedVariable(const sh::ShaderVariable &variable,
}
template <class VarT>
static VarT *FindVariable(const TString &name,
std::vector<VarT> *infoList)
VarT *FindVariable(const TString &name,
std::vector<VarT> *infoList)
{
// TODO(zmo): optimize this function.
for (size_t ii = 0; ii < infoList->size(); ++ii)
......@@ -95,6 +121,8 @@ static VarT *FindVariable(const TString &name,
return NULL;
}
}
CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Attribute> *outputVariables,
std::vector<sh::Uniform> *uniforms,
......@@ -270,10 +298,22 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
interfaceBlock.arraySize = variable->getArraySize();
interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
interfaceBlock.layout = sh::GetBlockLayoutType(blockType->blockStorage());
interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
// Gather field information
sh::GetInterfaceBlockFields(*blockType, &interfaceBlock.fields);
const TFieldList &fieldList = blockType->fields();
for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
{
const TField &field = *fieldList[fieldIndex];
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
const TType &fieldType = *field.type();
sh::GetVariableTraverser traverser;
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
}
infoList->push_back(interfaceBlock);
}
......
......@@ -320,44 +320,4 @@ template void GetVariableTraverser::traverse(const TType &, const TString &, std
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
{
switch (blockStorage)
{
case EbsPacked: return BLOCKLAYOUT_PACKED;
case EbsShared: return BLOCKLAYOUT_SHARED;
case EbsStd140: return BLOCKLAYOUT_STANDARD;
default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
}
}
static TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
{
if (interfaceBlock.hasInstanceName())
{
return interfaceBlock.name() + "." + field.name();
}
else
{
return field.name();
}
}
void GetInterfaceBlockFields(const TInterfaceBlock &interfaceBlock, std::vector<InterfaceBlockField> *fieldsOut)
{
const TFieldList &fieldList = interfaceBlock.fields();
for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
{
const TField &field = *fieldList[fieldIndex];
const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
const TType &fieldType = *field.type();
GetVariableTraverser traverser;
traverser.traverse(fieldType, fullFieldName, fieldsOut);
fieldsOut->back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
}
}
}
......@@ -33,7 +33,6 @@ bool IsVaryingIn(TQualifier qualifier);
bool IsVaryingOut(TQualifier qualifier);
bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage);
TString ArrayString(const TType &type);
class GetVariableTraverser
......@@ -52,8 +51,6 @@ class GetVariableTraverser
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};
void GetInterfaceBlockFields(const TInterfaceBlock &interfaceBlock, std::vector<InterfaceBlockField> *fieldsOut);
}
#endif // COMPILER_UTIL_H
......@@ -1068,6 +1068,12 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
bool matched = false;
// Built-in varyings obey special rules
if (input->isBuiltIn())
{
continue;
}
for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
{
PackedVarying *output = &vertexVaryings[vertVaryingIndex];
......@@ -1085,7 +1091,8 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
}
}
if (!matched)
// We permit unmatched, unreferenced varyings
if (!matched && input->staticUse)
{
infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
return false;
......@@ -1721,12 +1728,15 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
unsigned int usedLocations = 0;
const std::vector<sh::Attribute> &activeAttributes = vertexShader->getActiveAttributes();
const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
// Link attributes that have a binding location
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
const sh::Attribute &attribute = activeAttributes[attributeIndex];
const sh::Attribute &attribute = shaderAttributes[attributeIndex];
ASSERT(attribute.staticUse);
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
mShaderAttributes[attributeIndex] = attribute;
......@@ -1765,9 +1775,12 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
}
// Link attributes that don't have a binding location
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
const sh::Attribute &attribute = activeAttributes[attributeIndex];
const sh::Attribute &attribute = shaderAttributes[attributeIndex];
ASSERT(attribute.staticUse);
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
......@@ -1930,13 +1943,21 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, c
for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = vertexUniforms[uniformIndex];
defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
if (uniform.staticUse)
{
defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
}
}
for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
if (uniform.staticUse)
{
defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
}
}
if (!indexUniforms(infoLog, caps))
......@@ -2197,17 +2218,27 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShad
for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
if (!defineUniformBlock(infoLog, vertexShader, vertexInterfaceBlocks[blockIndex], caps))
const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
if (interfaceBlock.staticUse)
{
return false;
if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
{
return false;
}
}
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
if (!defineUniformBlock(infoLog, fragmentShader, fragmentInterfaceBlocks[blockIndex], caps))
const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
if (interfaceBlock.staticUse)
{
return false;
if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
{
return false;
}
}
}
......
......@@ -42,6 +42,7 @@ struct PackedVarying : public sh::Varying
{}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
void resetRegisterAssignment()
{
......
......@@ -223,6 +223,13 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++)
{
PackedVarying *varying = &fragmentVaryings[varyingIndex];
// Do not assign registers to built-in or unreferenced varyings
if (varying->isBuiltIn() || !varying->staticUse)
{
continue;
}
if (packVarying(varying, maxVaryingVectors, packing))
{
packedVaryings.insert(varying->name);
......@@ -278,17 +285,19 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
return registers;
}
std::string DynamicHLSL::generateVaryingHLSL(rx::ShaderD3D *shader) const
std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
{
std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize);
std::string varyingHLSL;
std::vector<gl::PackedVarying> &varyings = shader->getVaryings();
const std::vector<gl::PackedVarying> &varyings = shader->getVaryings();
for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++)
{
const PackedVarying &varying = varyings[varyingIndex];
if (varying.registerAssigned())
{
ASSERT(!varying.isBuiltIn());
GLenum transposedType = TransposeMatrixType(varying.type);
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
......@@ -616,8 +625,10 @@ void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++)
{
const PackedVarying &varying = varyings[varyingIndex];
if (varying.registerAssigned())
{
ASSERT(!varying.isBuiltIn());
GLenum transposedType = TransposeMatrixType(varying.type);
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
......@@ -825,6 +836,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
const std::string &variableName = "out_" + outputLocation.name;
const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
ASSERT(outputVariable.staticUse);
PixelShaderOuputVariable outputKeyVariable;
outputKeyVariable.type = outputVariable.type;
outputKeyVariable.name = variableName + elementString;
......@@ -907,6 +920,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
const PackedVarying &varying = fragmentVaryings[varyingIndex];
if (varying.registerAssigned())
{
ASSERT(!varying.isBuiltIn());
for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
{
GLenum transposedType = TransposeMatrixType(varying.type);
......@@ -944,7 +958,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
}
}
}
else UNREACHABLE();
else
{
ASSERT(varying.isBuiltIn() || !varying.staticUse);
}
}
pixelHLSL += "\n"
......@@ -965,6 +982,8 @@ void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<
const sh::Attribute &outputVariable = shaderOutputVars[outputVariableIndex];
const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location;
ASSERT(outputVariable.staticUse);
if (outputVariable.arraySize > 0)
{
for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++)
......
......@@ -87,7 +87,7 @@ class DynamicHLSL
SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(rx::ShaderD3D *shader) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const;
void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
......
......@@ -16,13 +16,30 @@
namespace rx
{
template <typename VarT>
void FilterInactiveVariables(std::vector<VarT> *variableList)
{
ASSERT(variableList);
for (size_t varIndex = 0; varIndex < variableList->size();)
{
if (!(*variableList)[varIndex].staticUse)
{
variableList->erase(variableList->begin() + varIndex);
}
else
{
varIndex++;
}
}
}
void *ShaderD3D::mFragmentCompiler = NULL;
void *ShaderD3D::mVertexCompiler = NULL;
template <typename VarT>
const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList)
{
// TODO: handle staticUse. for now, assume all returned variables are active.
ASSERT(variableList);
return variableList;
}
......@@ -111,12 +128,12 @@ void ShaderD3D::parseVaryings(void *compiler)
{
if (!mHlsl.empty())
{
const std::vector<sh::Varying> *activeVaryings = ShGetVaryings(compiler);
ASSERT(activeVaryings);
const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
ASSERT(varyings);
for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++)
for (size_t varyingIndex = 0; varyingIndex < varyings->size(); varyingIndex++)
{
mVaryings.push_back(gl::PackedVarying((*activeVaryings)[varyingIndex]));
mVaryings.push_back(gl::PackedVarying((*varyings)[varyingIndex]));
}
mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos;
......@@ -173,7 +190,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
// ensure the compiler is loaded
initializeCompiler();
int compileOptions = SH_OBJECT_CODE;
int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
std::string sourcePath;
if (gl::perfActive())
{
......@@ -251,12 +268,15 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
{
const sh::Uniform &uniform = mUniforms[uniformIndex];
unsigned int index = -1;
bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
if (uniform.staticUse)
{
unsigned int index = -1;
bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
mUniformRegisterMap[uniform.name] = index;
mUniformRegisterMap[uniform.name] = index;
}
}
mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler));
......@@ -265,12 +285,15 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
{
const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex];
unsigned int index = -1;
bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
if (interfaceBlock.staticUse)
{
unsigned int index = -1;
bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
}
}
}
else
......@@ -393,6 +416,7 @@ bool ShaderD3D::compile(const std::string &source)
if (!hlsl.empty())
{
mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler));
FilterInactiveVariables(&mActiveOutputVariables);
}
}
......@@ -405,6 +429,7 @@ void ShaderD3D::parseAttributes(void *compiler)
if (!hlsl.empty())
{
mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler));
FilterInactiveVariables(&mActiveAttributes);
}
}
......
......@@ -16,6 +16,7 @@
namespace rx
{
class DynamicHLSL;
class Renderer;
class ShaderD3D : public ShaderImpl
......
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