Merge "opengles emulator: fix the uniform location WAR for intel platforms"
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if we have one uniform at location 0, we do not need the WAR.
|
||||||
|
if (m_numIndexes > 1) {
|
||||||
m_locShiftWAR = true;
|
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user