From 7944edcdb28d6924f782fb04464526165447c1e6 Mon Sep 17 00:00:00 2001 From: Guy Zadickario Date: Wed, 10 Aug 2011 08:39:53 +0300 Subject: [PATCH] opengles emulator: fix the uniform location WAR for intel platforms Fixed the location shift WAR to work for arrays that starts at location 0. Fixed conformance regressions made by this workaround. The conversion should be smarter than just shifting 16-bits back and forth, it should take into account if array element is being accessed. Change-Id: Icb746c67e16edfacb8264a1e687fd24ac6e868e7 --- .../OpenglCodecCommon/GLSharedGroup.cpp | 71 ++++++++++++++----- .../shared/OpenglCodecCommon/GLSharedGroup.h | 10 ++- .../opengl/system/GLESv2_enc/GL2Encoder.cpp | 23 +++++- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp index f46889b3d..ff48c9d6a 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp @@ -45,19 +45,30 @@ void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type m_Indexes[index].base = base; m_Indexes[index].size = size; 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 i=0; - for (i=0;i= low && location < high) - break; + GLint dist = location - m_Indexes[i].base; + if (dist >= 0 && + (minDist < 0 || dist < minDist)) { + index = i; + minDist = dist; + } } - return i; + return index; } GLenum ProgramData::getTypeForLocation(GLint location) @@ -72,24 +83,44 @@ GLenum ProgramData::getTypeForLocation(GLint location) void ProgramData::setupLocationShiftWAR() { m_locShiftWAR = false; - for (int i=0; i 1) { + m_locShiftWAR = true; + } } -GLint ProgramData::locationWARHostToApp(GLint hostLoc) +GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex) { - if (m_locShiftWAR && hostLoc>0) return hostLoc>>16; - else return hostLoc; + if (!m_locShiftWAR) return hostLoc; + + GLuint index = getIndexForLocation(hostLoc); + if (index 0) { + m_Indexes[index].hostLocsPerElement = + (hostLoc - m_Indexes[index].base) / arrIndex; + } + return m_Indexes[index].appBase + arrIndex; + } + return -1; } GLint ProgramData::locationWARAppToHost(GLint appLoc) { - if (m_locShiftWAR && appLoc>0) return appLoc<<16; - else return appLoc; + if (!m_locShiftWAR) return appLoc; + + for(GLuint i=0; i= 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(); } -GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc) +GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex) { android::AutoMutex _lock(m_lock); ProgramData* pData = m_programs.valueFor(program); - if (pData) return pData->locationWARHostToApp(hostLoc); + if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex); else return hostLoc; } @@ -238,6 +269,14 @@ GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint 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) { diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h index 2443562bc..7104550d1 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h @@ -49,7 +49,9 @@ private: GLint base; GLint size; GLenum type; - }IndexInfo; + GLint appBase; + GLint hostLocsPerElement; + } IndexInfo; GLuint m_numIndexes; IndexInfo* m_Indexes; @@ -64,8 +66,9 @@ public: GLuint getIndexForLocation(GLint location); GLenum getTypeForLocation(GLint location); + bool needUniformLocationWAR() const { return m_locShiftWAR; } void setupLocationShiftWAR(); - GLint locationWARHostToApp(GLint hostLoc); + GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex); GLint locationWARAppToHost(GLint appLoc); }; @@ -93,8 +96,9 @@ public: void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type); GLenum getProgramUniformType(GLuint program, GLint location); void setupLocationShiftWAR(GLuint program); - GLint locationWARHostToApp(GLuint program, GLint hostLoc); + GLint locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex); GLint locationWARAppToHost(GLuint program, GLint appLoc); + bool needUniformLocationWAR(GLuint program); void addShaderData(GLuint shader); bool isShader(GLuint shader); diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index 5781dd4fe..61b19c1f6 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -534,9 +534,30 @@ void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name) { + if (!name) return -1; + 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); - 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)