Support matrix attributes

TRAC #11095 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@195 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent fbc09533
...@@ -73,6 +73,14 @@ TInfoSinkBase &OutputHLSL::getBodyStream() ...@@ -73,6 +73,14 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
return mBody; return mBody;
} }
int OutputHLSL::vectorSize(const TType &type) const
{
int elementSize = type.isMatrix() ? type.getNominalSize() : 1;
int arraySize = type.isArray() ? type.getArraySize() : 1;
return elementSize * arraySize;
}
void OutputHLSL::header() void OutputHLSL::header()
{ {
EShLanguage language = mContext.language; EShLanguage language = mContext.language;
...@@ -255,7 +263,7 @@ void OutputHLSL::header() ...@@ -255,7 +263,7 @@ void OutputHLSL::header()
attributeInput += " " + typeString(type) + " " + decorate(name) + arrayString(type) + " : TEXCOORD" + str(semanticIndex) + ";\n"; attributeInput += " " + typeString(type) + " " + decorate(name) + arrayString(type) + " : TEXCOORD" + str(semanticIndex) + ";\n";
attributeGlobals += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n"; attributeGlobals += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
semanticIndex += type.isArray() ? type.getArraySize() : 1; semanticIndex += vectorSize(type);
} }
} }
else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut) else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut)
...@@ -690,7 +698,9 @@ void OutputHLSL::footer() ...@@ -690,7 +698,9 @@ void OutputHLSL::footer()
{ {
if (mReferencedAttributes.find(name.c_str()) != mReferencedAttributes.end()) if (mReferencedAttributes.find(name.c_str()) != mReferencedAttributes.end())
{ {
out << " " + decorate(name) + " = input." + decorate(name) + ";\n"; const char *transpose = type.isMatrix() ? "transpose" : "";
out << " " + decorate(name) + " = " + transpose + "(input." + decorate(name) + ");\n";
} }
} }
} }
......
...@@ -48,6 +48,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -48,6 +48,7 @@ class OutputHLSL : public TIntermTraverser
bool handleExcessiveLoop(TIntermLoop *node); bool handleExcessiveLoop(TIntermLoop *node);
void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString); void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString);
TString argumentString(const TIntermSymbol *symbol); TString argumentString(const TIntermSymbol *symbol);
int vectorSize(const TType &type) const;
TParseContext &mContext; TParseContext &mContext;
UnfoldSelect *mUnfoldSelect; UnfoldSelect *mUnfoldSelect;
......
...@@ -1075,6 +1075,8 @@ void Program::link() ...@@ -1075,6 +1075,8 @@ void Program::link()
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
bool Program::linkAttributes() bool Program::linkAttributes()
{ {
unsigned int usedLocations = 0;
// Link attributes that have a binding location // Link attributes that have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
...@@ -1089,6 +1091,20 @@ bool Program::linkAttributes() ...@@ -1089,6 +1091,20 @@ bool Program::linkAttributes()
} }
mLinkedAttribute[location] = attribute; mLinkedAttribute[location] = attribute;
int size = AttributeVectorCount(attribute.type);
if (size + location > MAX_VERTEX_ATTRIBS)
{
appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
return false;
}
for (int i = 0; i < size; i++)
{
usedLocations |= 1 << (location + i);
}
} }
} }
...@@ -1098,16 +1114,12 @@ bool Program::linkAttributes() ...@@ -1098,16 +1114,12 @@ bool Program::linkAttributes()
const Attribute &attribute = mVertexShader->getAttribute(attributeIndex); const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
int location = getAttributeBinding(attribute.name); int location = getAttributeBinding(attribute.name);
if (location == -1) // Not set by glBindAttribLocation if (!attribute.name.empty() && location == -1) // Not set by glBindAttribLocation
{ {
int availableIndex = 0; int size = AttributeVectorCount(attribute.type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, size, MAX_VERTEX_ATTRIBS);
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].name.empty())
{
availableIndex++;
}
if (availableIndex == MAX_VERTEX_ATTRIBS) if (availableIndex == -1 || availableIndex + size > MAX_VERTEX_ATTRIBS)
{ {
appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str()); appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str());
...@@ -1118,9 +1130,23 @@ bool Program::linkAttributes() ...@@ -1118,9 +1130,23 @@ bool Program::linkAttributes()
} }
} }
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{ {
mSemanticIndex[attributeIndex] = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name.c_str()); int index = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
if (index == -1)
{
mSemanticIndex[attributeIndex++] = -1;
}
else
{
int size = AttributeVectorCount(mVertexShader->getAttribute(index).type);
for (int i = 0; i < size; i++)
{
mSemanticIndex[attributeIndex++] = index++;
}
}
} }
return true; return true;
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "libGLESv2/utilities.h" #include "libGLESv2/utilities.h"
#include <limits>
#include "common/debug.h" #include "common/debug.h"
#include "libGLESv2/mathutil.h" #include "libGLESv2/mathutil.h"
...@@ -89,6 +91,59 @@ size_t UniformTypeSize(GLenum type) ...@@ -89,6 +91,59 @@ size_t UniformTypeSize(GLenum type)
return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type); return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
} }
int AttributeVectorCount(GLenum type)
{
switch (type)
{
case GL_BOOL:
case GL_FLOAT:
case GL_INT:
case GL_BOOL_VEC2:
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_FLOAT_VEC3:
case GL_BOOL_VEC3:
case GL_BOOL_VEC4:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
return 1;
case GL_FLOAT_MAT2:
return 2;
case GL_FLOAT_MAT3:
return 3;
case GL_FLOAT_MAT4:
return 4;
default:
UNREACHABLE();
return 0;
}
}
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
{
ASSERT(allocationSize <= bitsSize);
unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
{
if ((*bits & mask) == 0)
{
*bits |= mask;
return i;
}
mask <<= 1;
}
return -1;
}
} }
namespace es2dx namespace es2dx
......
...@@ -21,6 +21,9 @@ struct Color; ...@@ -21,6 +21,9 @@ struct Color;
int UniformComponentCount(GLenum type); int UniformComponentCount(GLenum type);
GLenum UniformComponentType(GLenum type); GLenum UniformComponentType(GLenum type);
size_t UniformTypeSize(GLenum type); size_t UniformTypeSize(GLenum type);
int AttributeVectorCount(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
} }
......
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