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)
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)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].enabled)
{
attributes[i].programAttribute = getCurrentProgram()->getInputMapping(i);
attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
}
}
}
......
......@@ -37,11 +37,6 @@ Program::Program()
mConstantTablePS = NULL;
mConstantTableVS = NULL;
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mAttributeName[index] = NULL;
}
mPixelHLSL = NULL;
mVertexHLSL = NULL;
mInfoLog = NULL;
......@@ -131,40 +126,36 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
{
if (index < MAX_VERTEX_ATTRIBS)
{
delete[] mAttributeName[index];
mAttributeName[index] = new char[strlen(name) + 1];
strcpy(mAttributeName[index], name);
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mAttributeBinding[i].erase(name);
}
mAttributeBinding[index].insert(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;
}
bool Program::isActiveAttribute(int attributeIndex)
int Program::getSemanticIndex(int attributeIndex)
{
if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS)
{
return mInputMapping[attributeIndex] != -1;
}
return false;
}
int Program::getInputMapping(int attributeIndex)
{
if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS)
{
return mInputMapping[attributeIndex];
return mSemanticIndex[attributeIndex];
}
return -1;
......@@ -951,6 +942,8 @@ bool Program::linkVaryings()
{
if (pixelVaryings[in].link < 0)
{
appendToInfoLog("Pixel varying (%s) does not match any vertex varying", pixelVaryings[in].name);
return false;
}
}
......@@ -1043,43 +1036,70 @@ void Program::link()
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
bool Program::linkAttributes()
{
// Link attributes that have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
if (name)
if (location != -1) // Set by glBindAttribLocation
{
GLuint location = getAttributeLocation(name);
if (location == -1) // Not set by glBindAttribLocation
if (!mLinkedAttribute[location].empty())
{
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]))
{
availableIndex++;
}
mLinkedAttribute[location] = name;
}
}
if (availableIndex == MAX_VERTEX_ATTRIBS)
{
return false; // Fail to link
}
// Link attributes that don't have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS + 1; attributeIndex++)
{
const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
if (location == -1) // Not set by glBindAttribLocation
{
int availableIndex = 0;
delete[] mAttributeName[availableIndex];
mAttributeName[availableIndex] = new char[strlen(name) + 1]; // FIXME: Check allocation
strcpy(mAttributeName[availableIndex], name);
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].empty())
{
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++)
{
mInputMapping[attributeIndex] = mVertexShader->getInputMapping(mAttributeName[attributeIndex]);
mSemanticIndex[attributeIndex] = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].c_str());
}
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)
{
D3DXCONSTANTTABLE_DESC constantTableDescription;
......@@ -1729,13 +1749,20 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
return true;
}
void Program::appendToInfoLog(const char *info)
void Program::appendToInfoLog(const char *format, ...)
{
if (!info)
if (!format)
{
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);
if (!mInfoLog)
......@@ -1771,12 +1798,6 @@ void Program::unlink(bool destroy)
mVertexShader->detach();
mVertexShader = NULL;
}
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
delete[] mAttributeName[index];
mAttributeName[index] = NULL;
}
}
if (mPixelExecutable)
......@@ -1805,7 +1826,8 @@ void Program::unlink(bool destroy)
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++)
......
......@@ -13,6 +13,7 @@
#include <d3dx9.h>
#include <string>
#include <vector>
#include <set>
#include "libGLESv2/Context.h"
......@@ -50,8 +51,7 @@ class Program
void bindAttributeLocation(GLuint index, const char *name);
GLuint getAttributeLocation(const char *name);
bool isActiveAttribute(int attributeIndex);
int getInputMapping(int attributeIndex);
int getSemanticIndex(int attributeIndex);
GLint getSamplerMapping(unsigned int samplerIndex);
SamplerType getSamplerType(unsigned int samplerIndex);
......@@ -107,6 +107,7 @@ class Program
bool linkVaryings();
bool linkAttributes();
int getAttributeBinding(const char *name);
bool linkUniforms(ID3DXConstantTable *constantTable);
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
......@@ -129,7 +130,7 @@ class Program
bool applyUniform3iv(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;
VertexShader *mVertexShader;
......@@ -142,8 +143,9 @@ class Program
ID3DXConstantTable *mConstantTablePS;
ID3DXConstantTable *mConstantTableVS;
char *mAttributeName[MAX_VERTEX_ATTRIBS];
int mInputMapping[MAX_VERTEX_ATTRIBS];
std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
std::string mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler
{
......
......@@ -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)
{
}
......@@ -307,30 +278,25 @@ void VertexShader::compile()
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;
}
bool VertexShader::isActiveAttribute(const char *attributeName)
{
return getInputMapping(attributeName) != -1;
}
int VertexShader::getInputMapping(const char *attributeName)
int VertexShader::getSemanticIndex(const std::string &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()
if (matches == 2)
{
ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
mInputMapping[attributeIndex] = InputMapping(attributeName, semanticIndex);
attributeIndex++;
if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
{
mAttributeName[semanticIndex] = attributeName;
}
else
{
break;
}
input = strstr(input, ";");
}
......
......@@ -67,20 +67,6 @@ class Shader
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
{
public:
......@@ -91,15 +77,14 @@ class VertexShader : public Shader
GLenum getType();
void compile();
const char *getAttributeName(unsigned int attributeIndex);
bool isActiveAttribute(const char *attributeName);
int getInputMapping(const char *attributeName);
int getSemanticIndex(const std::string &attributeName);
private:
DISALLOW_COPY_AND_ASSIGN(VertexShader);
void parseAttributes();
InputMapping mInputMapping[MAX_VERTEX_ATTRIBS];
std::string mAttributeName[MAX_VERTEX_ATTRIBS + 1]; // One extra to report link error
};
class FragmentShader : public Shader
......
......@@ -70,12 +70,11 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
{
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[i] = true;
active[attributeIndex] = (program->getSemanticIndex(attributeIndex) != -1);
}
return active;
......@@ -83,7 +82,6 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
TranslatedAttribute *outAttribs)
{
ArrayTranslationHelper translationHelper(start, count);
......@@ -92,7 +90,6 @@ GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
GLenum VertexDataManager::preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute *outAttribs)
{
IndexedTranslationHelper translationHelper(indexInfo.indices, indexInfo.minIndex, indexInfo.count);
......
......@@ -43,7 +43,7 @@ struct TranslatedAttribute
std::size_t stride; // 0 means not to advance the read pointer at all
std::size_t programAttribute;
std::size_t semanticIndex;
TranslatedVertexBuffer *buffer;
};
......
......@@ -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->Method = D3DDECLMETHOD_DEFAULT;
nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
nextElement->UsageIndex = attributes[i].programAttribute;
nextElement->UsageIndex = attributes[i].semanticIndex;
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