Implemented aliased attributes support

TRAC #11092 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@177 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent f9ef107f
...@@ -1390,14 +1390,14 @@ void Context::applyState(GLenum drawMode) ...@@ -1390,14 +1390,14 @@ void Context::applyState(GLenum drawMode)
device->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE); device->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE);
} }
// Fill in the programAttribute field of the array of TranslatedAttributes based on the active GLSL program. // Fill in the semanticIndex field of the array of TranslatedAttributes based on the active GLSL program.
void Context::lookupAttributeMapping(TranslatedAttribute *attributes) void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
{ {
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
if (attributes[i].enabled) if (attributes[i].enabled)
{ {
attributes[i].programAttribute = getCurrentProgram()->getInputMapping(i); attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
} }
} }
} }
......
...@@ -37,11 +37,6 @@ Program::Program() ...@@ -37,11 +37,6 @@ Program::Program()
mConstantTablePS = NULL; mConstantTablePS = NULL;
mConstantTableVS = NULL; mConstantTableVS = NULL;
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mAttributeName[index] = NULL;
}
mPixelHLSL = NULL; mPixelHLSL = NULL;
mVertexHLSL = NULL; mVertexHLSL = NULL;
mInfoLog = NULL; mInfoLog = NULL;
...@@ -131,40 +126,36 @@ void Program::bindAttributeLocation(GLuint index, const char *name) ...@@ -131,40 +126,36 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
{ {
if (index < MAX_VERTEX_ATTRIBS) if (index < MAX_VERTEX_ATTRIBS)
{ {
delete[] mAttributeName[index]; for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
mAttributeName[index] = new char[strlen(name) + 1]; {
strcpy(mAttributeName[index], name); mAttributeBinding[i].erase(name);
}
mAttributeBinding[index].insert(name);
} }
} }
GLuint Program::getAttributeLocation(const char *name) GLuint Program::getAttributeLocation(const char *name)
{ {
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) if (name)
{ {
if (mAttributeName[index] && strcmp(mAttributeName[index], name) == 0) for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{ {
return index; if (mLinkedAttribute[index] == std::string(name))
{
return index;
}
} }
} }
return -1; return -1;
} }
bool Program::isActiveAttribute(int attributeIndex) int Program::getSemanticIndex(int attributeIndex)
{ {
if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS) if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS)
{ {
return mInputMapping[attributeIndex] != -1; return mSemanticIndex[attributeIndex];
}
return false;
}
int Program::getInputMapping(int attributeIndex)
{
if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS)
{
return mInputMapping[attributeIndex];
} }
return -1; return -1;
...@@ -951,6 +942,8 @@ bool Program::linkVaryings() ...@@ -951,6 +942,8 @@ bool Program::linkVaryings()
{ {
if (pixelVaryings[in].link < 0) if (pixelVaryings[in].link < 0)
{ {
appendToInfoLog("Pixel varying (%s) does not match any vertex varying", pixelVaryings[in].name);
return false; return false;
} }
} }
...@@ -1043,43 +1036,70 @@ void Program::link() ...@@ -1043,43 +1036,70 @@ 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()
{ {
// 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++)
{ {
const char *name = mVertexShader->getAttributeName(attributeIndex); const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
if (name) if (location != -1) // Set by glBindAttribLocation
{ {
GLuint location = getAttributeLocation(name); if (!mLinkedAttribute[location].empty())
if (location == -1) // Not set by glBindAttribLocation
{ {
int availableIndex = 0; // Multiple active attributes bound to the same location; not an error
}
while (availableIndex < MAX_VERTEX_ATTRIBS && mAttributeName[availableIndex] && mVertexShader->isActiveAttribute(mAttributeName[availableIndex])) mLinkedAttribute[location] = name;
{ }
availableIndex++; }
}
if (availableIndex == MAX_VERTEX_ATTRIBS) // Link attributes that don't have a binding location
{ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS + 1; attributeIndex++)
return false; // Fail to link {
} const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
if (location == -1) // Not set by glBindAttribLocation
{
int availableIndex = 0;
delete[] mAttributeName[availableIndex]; while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].empty())
mAttributeName[availableIndex] = new char[strlen(name) + 1]; // FIXME: Check allocation {
strcpy(mAttributeName[availableIndex], name); availableIndex++;
} }
if (availableIndex == MAX_VERTEX_ATTRIBS)
{
appendToInfoLog("Too many active attributes (%s)", name);
return false; // Fail to link
}
mLinkedAttribute[availableIndex] = name;
} }
} }
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
mInputMapping[attributeIndex] = mVertexShader->getInputMapping(mAttributeName[attributeIndex]); mSemanticIndex[attributeIndex] = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].c_str());
} }
return true; return true;
} }
int Program::getAttributeBinding(const char *name)
{
for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
{
if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end())
{
return location;
}
}
return -1;
}
bool Program::linkUniforms(ID3DXConstantTable *constantTable) bool Program::linkUniforms(ID3DXConstantTable *constantTable)
{ {
D3DXCONSTANTTABLE_DESC constantTableDescription; D3DXCONSTANTTABLE_DESC constantTableDescription;
...@@ -1729,13 +1749,20 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v) ...@@ -1729,13 +1749,20 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
void Program::appendToInfoLog(const char *info) void Program::appendToInfoLog(const char *format, ...)
{ {
if (!info) if (!format)
{ {
return; return;
} }
char info[1024];
va_list vararg;
va_start(vararg, format);
vsnprintf(info, sizeof(info), format, vararg);
va_end(vararg);
size_t infoLength = strlen(info); size_t infoLength = strlen(info);
if (!mInfoLog) if (!mInfoLog)
...@@ -1771,12 +1798,6 @@ void Program::unlink(bool destroy) ...@@ -1771,12 +1798,6 @@ void Program::unlink(bool destroy)
mVertexShader->detach(); mVertexShader->detach();
mVertexShader = NULL; mVertexShader = NULL;
} }
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
delete[] mAttributeName[index];
mAttributeName[index] = NULL;
}
} }
if (mPixelExecutable) if (mPixelExecutable)
...@@ -1805,7 +1826,8 @@ void Program::unlink(bool destroy) ...@@ -1805,7 +1826,8 @@ void Program::unlink(bool destroy)
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{ {
mInputMapping[index] = 0; mLinkedAttribute[index].clear();
mSemanticIndex[index] = -1;
} }
for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <d3dx9.h> #include <d3dx9.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <set>
#include "libGLESv2/Context.h" #include "libGLESv2/Context.h"
...@@ -50,8 +51,7 @@ class Program ...@@ -50,8 +51,7 @@ class Program
void bindAttributeLocation(GLuint index, const char *name); void bindAttributeLocation(GLuint index, const char *name);
GLuint getAttributeLocation(const char *name); GLuint getAttributeLocation(const char *name);
bool isActiveAttribute(int attributeIndex); int getSemanticIndex(int attributeIndex);
int getInputMapping(int attributeIndex);
GLint getSamplerMapping(unsigned int samplerIndex); GLint getSamplerMapping(unsigned int samplerIndex);
SamplerType getSamplerType(unsigned int samplerIndex); SamplerType getSamplerType(unsigned int samplerIndex);
...@@ -107,6 +107,7 @@ class Program ...@@ -107,6 +107,7 @@ class Program
bool linkVaryings(); bool linkVaryings();
bool linkAttributes(); bool linkAttributes();
int getAttributeBinding(const char *name);
bool linkUniforms(ID3DXConstantTable *constantTable); bool linkUniforms(ID3DXConstantTable *constantTable);
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
...@@ -129,7 +130,7 @@ class Program ...@@ -129,7 +130,7 @@ class Program
bool applyUniform3iv(GLint location, GLsizei count, const GLint *v); bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
void appendToInfoLog(const char *info); void appendToInfoLog(const char *info, ...);
FragmentShader *mFragmentShader; FragmentShader *mFragmentShader;
VertexShader *mVertexShader; VertexShader *mVertexShader;
...@@ -142,8 +143,9 @@ class Program ...@@ -142,8 +143,9 @@ class Program
ID3DXConstantTable *mConstantTablePS; ID3DXConstantTable *mConstantTablePS;
ID3DXConstantTable *mConstantTableVS; ID3DXConstantTable *mConstantTableVS;
char *mAttributeName[MAX_VERTEX_ATTRIBS]; std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
int mInputMapping[MAX_VERTEX_ATTRIBS]; std::string mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler struct Sampler
{ {
......
...@@ -259,35 +259,6 @@ void Shader::compileToHLSL(void *compiler) ...@@ -259,35 +259,6 @@ void Shader::compileToHLSL(void *compiler)
} }
} }
InputMapping::InputMapping()
{
mAttribute = NULL;
mSemanticIndex = -1;
}
InputMapping::InputMapping(const char *attribute, int semanticIndex)
{
mAttribute = new char[strlen(attribute) + 1];
strcpy(mAttribute, attribute);
mSemanticIndex = semanticIndex;
}
InputMapping &InputMapping::operator=(const InputMapping &inputMapping)
{
delete[] mAttribute;
mAttribute = new char[strlen(inputMapping.mAttribute) + 1];
strcpy(mAttribute, inputMapping.mAttribute);
mSemanticIndex = inputMapping.mSemanticIndex;
return *this;
}
InputMapping::~InputMapping()
{
delete[] mAttribute;
}
VertexShader::VertexShader(GLuint handle) : Shader(handle) VertexShader::VertexShader(GLuint handle) : Shader(handle)
{ {
} }
...@@ -307,30 +278,25 @@ void VertexShader::compile() ...@@ -307,30 +278,25 @@ void VertexShader::compile()
parseAttributes(); parseAttributes();
} }
const char *VertexShader::getAttributeName(unsigned int attributeIndex) const char *VertexShader::getAttributeName(unsigned int semanticIndex)
{ {
if (attributeIndex < MAX_VERTEX_ATTRIBS) if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
{ {
return mInputMapping[attributeIndex].mAttribute; return mAttributeName[semanticIndex].c_str();
} }
return 0; return 0;
} }
bool VertexShader::isActiveAttribute(const char *attributeName) int VertexShader::getSemanticIndex(const std::string &attributeName)
{
return getInputMapping(attributeName) != -1;
}
int VertexShader::getInputMapping(const char *attributeName)
{ {
if (attributeName) if (!attributeName.empty())
{ {
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) for (int semanticIndex = 0; semanticIndex < MAX_VERTEX_ATTRIBS; semanticIndex++)
{ {
if (mInputMapping[index].mAttribute && strcmp(mInputMapping[index].mAttribute, attributeName) == 0) if (mAttributeName[semanticIndex] == attributeName)
{ {
return mInputMapping[index].mSemanticIndex; return semanticIndex;
} }
} }
} }
...@@ -353,9 +319,14 @@ void VertexShader::parseAttributes() ...@@ -353,9 +319,14 @@ void VertexShader::parseAttributes()
if (matches == 2) if (matches == 2)
{ {
ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS); if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
mInputMapping[attributeIndex] = InputMapping(attributeName, semanticIndex); {
attributeIndex++; mAttributeName[semanticIndex] = attributeName;
}
else
{
break;
}
input = strstr(input, ";"); input = strstr(input, ";");
} }
......
...@@ -67,20 +67,6 @@ class Shader ...@@ -67,20 +67,6 @@ class Shader
static void *mVertexCompiler; static void *mVertexCompiler;
}; };
class InputMapping
{
public:
InputMapping();
InputMapping(const char *attribute, int semanticIndex);
~InputMapping();
InputMapping &operator=(const InputMapping &inputMapping);
char *mAttribute;
int mSemanticIndex; // TEXCOORDi
};
class VertexShader : public Shader class VertexShader : public Shader
{ {
public: public:
...@@ -91,15 +77,14 @@ class VertexShader : public Shader ...@@ -91,15 +77,14 @@ class VertexShader : public Shader
GLenum getType(); GLenum getType();
void compile(); void compile();
const char *getAttributeName(unsigned int attributeIndex); const char *getAttributeName(unsigned int attributeIndex);
bool isActiveAttribute(const char *attributeName); int getSemanticIndex(const std::string &attributeName);
int getInputMapping(const char *attributeName);
private: private:
DISALLOW_COPY_AND_ASSIGN(VertexShader); DISALLOW_COPY_AND_ASSIGN(VertexShader);
void parseAttributes(); void parseAttributes();
InputMapping mInputMapping[MAX_VERTEX_ATTRIBS]; std::string mAttributeName[MAX_VERTEX_ATTRIBS + 1]; // One extra to report link error
}; };
class FragmentShader : public Shader class FragmentShader : public Shader
......
...@@ -70,12 +70,11 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs() ...@@ -70,12 +70,11 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
{ {
std::bitset<MAX_VERTEX_ATTRIBS> active; std::bitset<MAX_VERTEX_ATTRIBS> active;
Program *p = mContext->getCurrentProgram(); Program *program = mContext->getCurrentProgram();
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
if (p->isActiveAttribute(i)) active[attributeIndex] = (program->getSemanticIndex(attributeIndex) != -1);
active[i] = true;
} }
return active; return active;
...@@ -83,7 +82,6 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs() ...@@ -83,7 +82,6 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count, GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
TranslatedAttribute *outAttribs) TranslatedAttribute *outAttribs)
{ {
ArrayTranslationHelper translationHelper(start, count); ArrayTranslationHelper translationHelper(start, count);
...@@ -92,7 +90,6 @@ GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count, ...@@ -92,7 +90,6 @@ GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
GLenum VertexDataManager::preRenderValidate(const TranslatedIndexData &indexInfo, GLenum VertexDataManager::preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute *outAttribs) TranslatedAttribute *outAttribs)
{ {
IndexedTranslationHelper translationHelper(indexInfo.indices, indexInfo.minIndex, indexInfo.count); IndexedTranslationHelper translationHelper(indexInfo.indices, indexInfo.minIndex, indexInfo.count);
......
...@@ -43,7 +43,7 @@ struct TranslatedAttribute ...@@ -43,7 +43,7 @@ struct TranslatedAttribute
std::size_t stride; // 0 means not to advance the read pointer at all std::size_t stride; // 0 means not to advance the read pointer at all
std::size_t programAttribute; std::size_t semanticIndex;
TranslatedVertexBuffer *buffer; TranslatedVertexBuffer *buffer;
}; };
......
...@@ -213,7 +213,7 @@ GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes) ...@@ -213,7 +213,7 @@ GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes)
nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized)); nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized));
nextElement->Method = D3DDECLMETHOD_DEFAULT; nextElement->Method = D3DDECLMETHOD_DEFAULT;
nextElement->Usage = D3DDECLUSAGE_TEXCOORD; nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
nextElement->UsageIndex = attributes[i].programAttribute; nextElement->UsageIndex = attributes[i].semanticIndex;
nextElement++; nextElement++;
} }
} }
......
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