Commit c2141fb3 by Jamie Madill

Consolidate the register counting functions to a single location in the HLSL layout encoder source.

This new method explicitly depends on HLSL packing rules, instead of a GL idiom. TRAC #23748 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens
parent 77456f28
......@@ -84,4 +84,32 @@ void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool i
}
}
template <class ShaderVarType>
unsigned int HLSLRegisterCount(const ShaderVarType &variable)
{
if (variable.isStruct())
{
unsigned int totalCount = 0;
for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++)
{
totalCount += HLSLVariableRegisterCount(variable.fields[fieldIndex]);
}
return totalCount * variable.elementCount();
}
else
{
return gl::VariableRowCount(variable.type) * variable.elementCount();
}
}
unsigned int HLSLVariableRegisterCount(const Varying &variable)
{
return HLSLRegisterCount(variable);
}
unsigned int HLSLVariableRegisterCount(const Uniform &variable)
{
return HLSLRegisterCount(variable);
}
}
......@@ -12,6 +12,9 @@
namespace sh
{
struct Varying;
struct Uniform;
// Block layout packed according to the default D3D11 register packing rules
// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
......@@ -27,6 +30,11 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
};
// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
// class to count the number of used registers in a struct (which are individually packed according to the same rules).
unsigned int HLSLVariableRegisterCount(const Varying &variable);
unsigned int HLSLVariableRegisterCount(const Uniform &variable);
}
#endif // TRANSLATOR_HLSL_HLSLLAYOUTENCODER_H_
\ No newline at end of file
#endif // TRANSLATOR_HLSL_HLSLLAYOUTENCODER_H_
......@@ -66,6 +66,18 @@ TString OutputHLSL::TextureFunction::name() const
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
{
if (sampler < rhs.sampler) return true;
......@@ -530,25 +542,30 @@ void OutputHLSL::header()
TString attributes;
TString flaggedStructs;
for (ReferencedSymbols::const_iterator uniform = mReferencedUniforms.begin(); uniform != mReferencedUniforms.end(); uniform++)
for (ReferencedSymbols::const_iterator uniformIt = mReferencedUniforms.begin(); uniformIt != mReferencedUniforms.end(); uniformIt++)
{
const TType &type = uniform->second->getType();
const TString &name = uniform->second->getSymbol();
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
{
int index = samplerRegister(mReferencedUniforms[name]);
uniforms += "uniform " + samplerString(type) + " sampler_" + decorateUniform(name, type) + arrayString(type) +
" : register(s" + str(index) + ");\n";
" : register(s" + str(registerIndex) + ");\n";
uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
" : register(t" + str(index) + ");\n";
" : register(t" + str(registerIndex) + ");\n";
}
else
{
uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) +
" : register(" + registerString(mReferencedUniforms[name]) + ");\n";
const TStructure *structure = type.getStruct();
const TString &typeName = (structure ? structureTypeName(*structure, false, false) : typeString(type));
const TString &registerString = TString("register(") + RegisterPrefix(type) + str(registerIndex) + ")";
uniforms += "uniform " + typeName + " " + decorateUniform(name, type) + arrayString(type) + " : " + registerString + ";\n";
}
}
......@@ -3539,44 +3556,6 @@ TString OutputHLSL::decorateField(const TString &string, const TStructure &struc
return string;
}
TString OutputHLSL::registerString(TIntermSymbol *operand)
{
ASSERT(operand->getQualifier() == EvqUniform);
if (IsSampler(operand->getBasicType()))
{
return "s" + str(samplerRegister(operand));
}
return "c" + str(uniformRegister(operand));
}
int OutputHLSL::samplerRegister(TIntermSymbol *sampler)
{
const TType &type = sampler->getType();
ASSERT(IsSampler(type.getBasicType()));
int index = mSamplerRegister;
mSamplerRegister += sampler->totalRegisterCount();
declareUniform(type, sampler->getSymbol(), index);
return index;
}
int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
{
const TType &type = uniform->getType();
ASSERT(!IsSampler(type.getBasicType()));
int index = mUniformRegister;
mUniformRegister += uniform->totalRegisterCount();
declareUniform(type, uniform->getSymbol(), index);
return index;
}
void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output)
{
const TStructure *structure = type.getStruct();
......@@ -3609,7 +3588,7 @@ void OutputHLSL::declareInterfaceBlockField(const TType &type, const TString &na
}
}
void OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output)
Uniform OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output)
{
const TStructure *structure = type.getStruct();
......@@ -3619,6 +3598,8 @@ void OutputHLSL::declareUniformToList(const TType &type, const TString &name, in
Uniform uniform(glVariableType(type), glVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), (unsigned int)registerIndex);
output.push_back(uniform);
return uniform;
}
else
{
......@@ -3632,14 +3613,13 @@ void OutputHLSL::declareUniformToList(const TType &type, const TString &name, in
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
// make sure to copy matrix packing information
fieldType->setLayoutQualifier(type.getLayoutQualifier());
declareUniformToList(*fieldType, field->name(), fieldRegister, structUniform.fields);
fieldRegister += fieldType->totalRegisterCount();
const Uniform &fieldVariable = declareUniformToList(*fieldType, field->name(), fieldRegister, structUniform.fields);
fieldRegister += HLSLVariableRegisterCount(fieldVariable);
}
output.push_back(structUniform);
return structUniform;
}
}
......@@ -3691,9 +3671,22 @@ void OutputHLSL::declareVaryingToList(const TType &type, const TString &name, st
}
}
void OutputHLSL::declareUniform(const TType &type, const TString &name, int index)
int OutputHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name)
{
declareUniformToList(type, name, index, mActiveUniforms);
int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
const Uniform &uniform = declareUniformToList(type, name, registerIndex, mActiveUniforms);
if (IsSampler(type.getBasicType()))
{
mSamplerRegister += HLSLVariableRegisterCount(uniform);
}
else
{
mUniformRegister += HLSLVariableRegisterCount(uniform);
}
return registerIndex;
}
GLenum OutputHLSL::glVariableType(const TType &type)
......
......@@ -178,10 +178,13 @@ class OutputHLSL : public TIntermTraverser
int samplerRegister(TIntermSymbol *sampler);
int uniformRegister(TIntermSymbol *uniform);
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output);
void declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output);
Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output);
void declareUniform(const TType &type, const TString &name, int index);
void declareVaryingToList(const TType &type, const TString &name, std::vector<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 decoratePrivate(const TString &privateText);
TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType);
......
......@@ -179,42 +179,6 @@ public:
// Full size of single instance of type
size_t getObjectSize() const;
int elementRegisterCount() const
{
if (structure)
{
const TFieldList& fields = structure->fields();
int registerCount = 0;
for (size_t i = 0; i < fields.size(); i++)
{
registerCount += fields[i]->type()->totalRegisterCount();
}
return registerCount;
}
else if (isMatrix())
{
return getRows();
}
else
{
return 1;
}
}
int totalRegisterCount() const
{
if (array)
{
return arraySize * elementRegisterCount();
}
else
{
return elementRegisterCount();
}
}
bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
bool isArray() const { return array ? true : false; }
int getArraySize() const { return arraySize; }
......
......@@ -281,8 +281,6 @@ public:
const char* getQualifierString() const { return type.getQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); }
int totalRegisterCount() const { return type.totalRegisterCount(); }
int elementRegisterCount() const { return type.elementRegisterCount(); }
int getArraySize() const { return type.getArraySize(); }
protected:
......
......@@ -24,6 +24,8 @@
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
#include "compiler/HLSLLayoutEncoder.h"
#undef near
#undef far
......@@ -2375,7 +2377,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In
{
return false;
}
fieldRegisterIndex += totalRegisterCount(field);
fieldRegisterIndex += sh::HLSLVariableRegisterCount(field);
}
}
......
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