am d2c5f503: Merge "opengles emulator: fix the uniform location WAR for intel platforms"

* commit 'd2c5f50354052223348aa9acbdaeea407b28d8f9':
  opengles emulator: fix the uniform location WAR for intel platforms
This commit is contained in:
David Turner
2011-08-13 16:10:53 -07:00
committed by Android Git Automerger
3 changed files with 84 additions and 20 deletions

View File

@@ -45,19 +45,30 @@ void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type
m_Indexes[index].base = base; m_Indexes[index].base = base;
m_Indexes[index].size = size; m_Indexes[index].size = size;
m_Indexes[index].type = type; m_Indexes[index].type = type;
if (index > 0) {
m_Indexes[index].appBase = m_Indexes[index-1].appBase +
m_Indexes[index-1].size;
}
else {
m_Indexes[index].appBase = 0;
}
m_Indexes[index].hostLocsPerElement = 1;
} }
GLuint ProgramData::getIndexForLocation(GLint location) GLuint ProgramData::getIndexForLocation(GLint location)
{ {
GLuint i=0; GLuint index = m_numIndexes;
for (i=0;i<m_numIndexes;++i) GLint minDist = -1;
for (GLuint i=0;i<m_numIndexes;++i)
{ {
GLint low = m_Indexes[i].base;; GLint dist = location - m_Indexes[i].base;
GLint high = low + m_Indexes[i].size; if (dist >= 0 &&
if (location >= low && location < high) (minDist < 0 || dist < minDist)) {
break; index = i;
minDist = dist;
}
} }
return i; return index;
} }
GLenum ProgramData::getTypeForLocation(GLint location) GLenum ProgramData::getTypeForLocation(GLint location)
@@ -72,24 +83,44 @@ GLenum ProgramData::getTypeForLocation(GLint location)
void ProgramData::setupLocationShiftWAR() void ProgramData::setupLocationShiftWAR()
{ {
m_locShiftWAR = false; m_locShiftWAR = false;
for (int i=0; i<m_numIndexes; i++) { for (GLuint i=0; i<m_numIndexes; i++) {
if (0 != (m_Indexes[i].base & 0xffff)) { if (0 != (m_Indexes[i].base & 0xffff)) {
return; return;
} }
} }
m_locShiftWAR = true; // if we have one uniform at location 0, we do not need the WAR.
if (m_numIndexes > 1) {
m_locShiftWAR = true;
}
} }
GLint ProgramData::locationWARHostToApp(GLint hostLoc) GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
{ {
if (m_locShiftWAR && hostLoc>0) return hostLoc>>16; if (!m_locShiftWAR) return hostLoc;
else return hostLoc;
GLuint index = getIndexForLocation(hostLoc);
if (index<m_numIndexes) {
if (arrIndex > 0) {
m_Indexes[index].hostLocsPerElement =
(hostLoc - m_Indexes[index].base) / arrIndex;
}
return m_Indexes[index].appBase + arrIndex;
}
return -1;
} }
GLint ProgramData::locationWARAppToHost(GLint appLoc) GLint ProgramData::locationWARAppToHost(GLint appLoc)
{ {
if (m_locShiftWAR && appLoc>0) return appLoc<<16; if (!m_locShiftWAR) return appLoc;
else return appLoc;
for(GLuint i=0; i<m_numIndexes; i++) {
GLint elemIndex = appLoc - m_Indexes[i].appBase;
if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
return m_Indexes[i].base +
elemIndex * m_Indexes[i].hostLocsPerElement;
}
}
return -1;
} }
@@ -222,11 +253,11 @@ void GLSharedGroup::setupLocationShiftWAR(GLuint program)
if (pData) pData->setupLocationShiftWAR(); if (pData) pData->setupLocationShiftWAR();
} }
GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc) GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
{ {
android::AutoMutex _lock(m_lock); android::AutoMutex _lock(m_lock);
ProgramData* pData = m_programs.valueFor(program); ProgramData* pData = m_programs.valueFor(program);
if (pData) return pData->locationWARHostToApp(hostLoc); if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
else return hostLoc; else return hostLoc;
} }
@@ -238,6 +269,14 @@ GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
else return appLoc; else return appLoc;
} }
bool GLSharedGroup::needUniformLocationWAR(GLuint program)
{
android::AutoMutex _lock(m_lock);
ProgramData* pData = m_programs.valueFor(program);
if (pData) return pData->needUniformLocationWAR();
return false;
}
void GLSharedGroup::addShaderData(GLuint shader) void GLSharedGroup::addShaderData(GLuint shader)
{ {

View File

@@ -49,7 +49,9 @@ private:
GLint base; GLint base;
GLint size; GLint size;
GLenum type; GLenum type;
}IndexInfo; GLint appBase;
GLint hostLocsPerElement;
} IndexInfo;
GLuint m_numIndexes; GLuint m_numIndexes;
IndexInfo* m_Indexes; IndexInfo* m_Indexes;
@@ -64,8 +66,9 @@ public:
GLuint getIndexForLocation(GLint location); GLuint getIndexForLocation(GLint location);
GLenum getTypeForLocation(GLint location); GLenum getTypeForLocation(GLint location);
bool needUniformLocationWAR() const { return m_locShiftWAR; }
void setupLocationShiftWAR(); void setupLocationShiftWAR();
GLint locationWARHostToApp(GLint hostLoc); GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex);
GLint locationWARAppToHost(GLint appLoc); GLint locationWARAppToHost(GLint appLoc);
}; };
@@ -93,8 +96,9 @@ public:
void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type); void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type);
GLenum getProgramUniformType(GLuint program, GLint location); GLenum getProgramUniformType(GLuint program, GLint location);
void setupLocationShiftWAR(GLuint program); void setupLocationShiftWAR(GLuint program);
GLint locationWARHostToApp(GLuint program, GLint hostLoc); GLint locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex);
GLint locationWARAppToHost(GLuint program, GLint appLoc); GLint locationWARAppToHost(GLuint program, GLint appLoc);
bool needUniformLocationWAR(GLuint program);
void addShaderData(GLuint shader); void addShaderData(GLuint shader);
bool isShader(GLuint shader); bool isShader(GLuint shader);

View File

@@ -534,9 +534,30 @@ void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name) int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
{ {
if (!name) return -1;
GL2Encoder *ctx = (GL2Encoder*)self; GL2Encoder *ctx = (GL2Encoder*)self;
// if we need the uniform location WAR
// parse array index from the end of the name string
int arrIndex = 0;
bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
if (needLocationWAR) {
int namelen = strlen(name);
if (name[namelen-1] == ']') {
char *brace = strrchr(name,'[');
if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
return -1;
}
}
}
int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name); int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
return ctx->m_shared->locationWARHostToApp(program, hostLoc); if (hostLoc >= 0 && needLocationWAR) {
return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
}
return hostLoc;
} }
void GL2Encoder::s_glUseProgram(void *self, GLuint program) void GL2Encoder::s_glUseProgram(void *self, GLuint program)