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()
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()
{
EShLanguage language = mContext.language;
......@@ -255,7 +263,7 @@ void OutputHLSL::header()
attributeInput += " " + typeString(type) + " " + decorate(name) + arrayString(type) + " : TEXCOORD" + str(semanticIndex) + ";\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)
......@@ -690,7 +698,9 @@ void OutputHLSL::footer()
{
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
bool handleExcessiveLoop(TIntermLoop *node);
void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString);
TString argumentString(const TIntermSymbol *symbol);
int vectorSize(const TType &type) const;
TParseContext &mContext;
UnfoldSelect *mUnfoldSelect;
......
......@@ -1075,6 +1075,8 @@ void Program::link()
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
bool Program::linkAttributes()
{
unsigned int usedLocations = 0;
// Link attributes that have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
......@@ -1089,6 +1091,20 @@ bool Program::linkAttributes()
}
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()
const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
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;
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].name.empty())
{
availableIndex++;
}
int size = AttributeVectorCount(attribute.type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, size, MAX_VERTEX_ATTRIBS);
if (availableIndex == MAX_VERTEX_ATTRIBS)
if (availableIndex == -1 || availableIndex + size > MAX_VERTEX_ATTRIBS)
{
appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str());
......@@ -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;
......
......@@ -8,6 +8,8 @@
#include "libGLESv2/utilities.h"
#include <limits>
#include "common/debug.h"
#include "libGLESv2/mathutil.h"
......@@ -89,6 +91,59 @@ size_t UniformTypeSize(GLenum 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
......
......@@ -21,6 +21,9 @@ struct Color;
int UniformComponentCount(GLenum type);
GLenum UniformComponentType(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