Implemented glGetActiveUniform
TRAC #11929
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@181 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 109b356..a36a856 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -124,10 +124,10 @@
}
}
- out << "uniform float4 gl_Window;\n"
- "uniform float2 gl_Depth;\n"
- "uniform bool gl_PointsOrLines;\n"
- "uniform bool gl_FrontCCW;\n"
+ out << "uniform float4 dx_Window;\n"
+ "uniform float2 dx_Depth;\n"
+ "uniform bool dx_PointsOrLines;\n"
+ "uniform bool dx_FrontCCW;\n"
"\n";
out << uniforms;
out << "\n"
@@ -275,7 +275,7 @@
}
}
- out << "uniform float2 gl_HalfPixelSize;\n"
+ out << "uniform float2 dx_HalfPixelSize;\n"
"\n";
out << uniforms;
out << "\n"
@@ -617,11 +617,11 @@
out << "PS_OUTPUT main(PS_INPUT input)\n"
"{\n"
" float rhw = 1.0 / input.gl_FragCoord.w;\n"
- " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * gl_Window.x + gl_Window.z;\n"
- " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * gl_Window.y + gl_Window.w;\n"
- " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * gl_Depth.x + gl_Depth.y;\n"
+ " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Window.x + dx_Window.z;\n"
+ " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Window.y + dx_Window.w;\n"
+ " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n"
- " gl_FrontFacing = gl_PointsOrLines || (gl_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
+ " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
for (TSymbolTableLevel::const_iterator namedSymbol = symbols->begin(); namedSymbol != symbols->end(); namedSymbol++)
{
@@ -680,8 +680,8 @@
" gl_main();\n"
"\n"
" VS_OUTPUT output;\n"
- " output.gl_Position.x = gl_Position.x - gl_HalfPixelSize.x * gl_Position.w;\n"
- " output.gl_Position.y = -(gl_Position.y - gl_HalfPixelSize.y * gl_Position.w);\n"
+ " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
+ " output.gl_Position.y = -(gl_Position.y - dx_HalfPixelSize.y * gl_Position.w);\n"
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n"
" output.gl_PointSize = gl_PointSize;\n"
@@ -1979,7 +1979,7 @@
TString OutputHLSL::decorate(const TString &string)
{
- if (string.substr(0, 3) != "gl_")
+ if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_")
{
return "_" + string;
}
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index d6df598..c700b4c 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1230,15 +1230,15 @@
renderTarget->GetDesc(&description);
Program *programObject = getCurrentProgram();
- GLint halfPixelSize = programObject->getUniformLocation("gl_HalfPixelSize");
+ GLint halfPixelSize = programObject->getUniformLocation("dx_HalfPixelSize");
GLfloat xy[2] = {1.0f / description.Width, 1.0f / description.Height};
programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
- GLint window = programObject->getUniformLocation("gl_Window");
+ GLint window = programObject->getUniformLocation("dx_Window");
GLfloat whxy[4] = {viewportWidth / 2.0f, viewportHeight / 2.0f, (float)viewportX + viewportWidth / 2.0f, (float)viewportY + viewportHeight / 2.0f};
programObject->setUniform4fv(window, 1, (GLfloat*)&whxy);
- GLint depth = programObject->getUniformLocation("gl_Depth");
+ GLint depth = programObject->getUniformLocation("dx_Depth");
GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
programObject->setUniform2fv(depth, 1, (GLfloat*)&dz);
@@ -1262,11 +1262,11 @@
IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram();
- GLint frontCCW = programObject->getUniformLocation("gl_FrontCCW");
+ GLint frontCCW = programObject->getUniformLocation("dx_FrontCCW");
GLint ccw = (frontFace == GL_CCW);
programObject->setUniform1iv(frontCCW, 1, &ccw);
- GLint pointsOrLines = programObject->getUniformLocation("gl_PointsOrLines");
+ GLint pointsOrLines = programObject->getUniformLocation("dx_PointsOrLines");
GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index 3dff097..1e2f944 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -1274,7 +1274,7 @@
// This methods needs to match OutputHLSL::decorate
std::string Program::decorate(const std::string &string)
{
- if (string.substr(0, 3) != "gl_")
+ if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_")
{
return "_" + string;
}
@@ -1749,41 +1749,6 @@
return true;
}
-GLenum Program::parseAttributeType(const std::string &type)
-{
- if (type == "float")
- {
- return GL_FLOAT;
- }
- else if (type == "float2")
- {
- return GL_FLOAT_VEC2;
- }
- else if (type == "float3")
- {
- return GL_FLOAT_VEC3;
- }
- else if (type == "float4")
- {
- return GL_FLOAT_VEC4;
- }
- else if (type == "float2x2")
- {
- return GL_FLOAT_MAT2;
- }
- else if (type == "float3x3")
- {
- return GL_FLOAT_MAT3;
- }
- else if (type == "float4x4")
- {
- return GL_FLOAT_MAT4;
- }
- else UNREACHABLE();
-
- return GL_NONE;
-}
-
void Program::appendToInfoLog(const char *format, ...)
{
if (!format)
@@ -1862,7 +1827,6 @@
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mLinkedAttribute[index].name.clear();
- mLinkedAttribute[index].type.clear();
mSemanticIndex[index] = -1;
}
@@ -1962,7 +1926,7 @@
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- int attribute = 0;
+ unsigned int attribute = 0;
for (unsigned int i = 0; i < index; i++)
{
do
@@ -1989,7 +1953,7 @@
*size = 1;
- *type = parseAttributeType(mLinkedAttribute[attribute].type);
+ *type = mLinkedAttribute[attribute].type;
}
GLint Program::getActiveAttributeCount()
@@ -2022,6 +1986,73 @@
return maxLength;
}
+void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+ unsigned int uniform = 0;
+ for (unsigned int i = 0; i < index; i++)
+ {
+ do
+ {
+ uniform++;
+
+ ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+ }
+ while (mUniforms[uniform]->name.substr(0, 3) == "dx_");
+ }
+
+ if (bufsize > 0)
+ {
+ const char *string = mUniforms[uniform]->name.c_str();
+
+ if(string[0] == '_') // Undecorate
+ {
+ string++;
+ }
+
+ strncpy(name, string, bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(name);
+ }
+ }
+
+ *size = 1;
+
+ *type = mUniforms[uniform]->type;
+}
+
+GLint Program::getActiveUniformCount()
+{
+ int count = 0;
+
+ for (unsigned int uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ if (mUniforms[uniformIndex]->name.substr(0, 3) != "dx_")
+ {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+GLint Program::getActiveUniformMaxLength()
+{
+ int maxLength = 0;
+
+ for (unsigned int uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.substr(0, 3) != "dx_")
+ {
+ maxLength = std::max((int)(mUniforms[uniformIndex]->name.length() + 1), maxLength);
+ }
+ }
+
+ return maxLength;
+}
+
void Program::flagForDeletion()
{
mDeleteStatus = true;
diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h
index 9992a5c..91d04ef 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -85,6 +85,10 @@
GLint getActiveAttributeCount();
GLint getActiveAttributeMaxLength();
+ void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+ GLint getActiveUniformCount();
+ GLint getActiveUniformMaxLength();
+
void flagForDeletion();
bool isFlaggedForDeletion() const;
@@ -135,7 +139,6 @@
bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
- GLenum parseAttributeType(const std::string &type);
void appendToInfoLog(const char *info, ...);
FragmentShader *mFragmentShader;
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index 61c8e48..2abbd61 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -216,6 +216,41 @@
mVertexCompiler = NULL;
}
+GLenum Shader::parseAttributeType(const std::string &type)
+{
+ if (type == "float")
+ {
+ return GL_FLOAT;
+ }
+ else if (type == "float2")
+ {
+ return GL_FLOAT_VEC2;
+ }
+ else if (type == "float3")
+ {
+ return GL_FLOAT_VEC3;
+ }
+ else if (type == "float4")
+ {
+ return GL_FLOAT_VEC4;
+ }
+ else if (type == "float2x2")
+ {
+ return GL_FLOAT_MAT2;
+ }
+ else if (type == "float3x3")
+ {
+ return GL_FLOAT_MAT3;
+ }
+ else if (type == "float4x4")
+ {
+ return GL_FLOAT_MAT4;
+ }
+ else UNREACHABLE();
+
+ return GL_NONE;
+}
+
void Shader::compileToHLSL(void *compiler)
{
if (isCompiled() || !mSource)
@@ -319,7 +354,7 @@
{
if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
{
- mAttribute[semanticIndex].type = attributeType;
+ mAttribute[semanticIndex].type = parseAttributeType(attributeType);
mAttribute[semanticIndex].name = attributeName;
}
else
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index 7872d24..86ead44 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -49,6 +49,7 @@
void flagForDeletion();
static void releaseCompiler();
+ static GLenum parseAttributeType(const std::string &type);
protected:
DISALLOW_COPY_AND_ASSIGN(Shader);
@@ -69,7 +70,7 @@
struct Attribute
{
- std::string type;
+ GLenum type;
std::string name;
};
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 9f70ace..516ec8c 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1899,7 +1899,7 @@
}
}
- if (index >= programObject->getActiveAttributeCount())
+ if (index >= (GLuint)programObject->getActiveAttributeCount())
{
return error(GL_INVALID_VALUE);
}
@@ -1926,7 +1926,31 @@
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED(); // FIXME
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ }
+
+ if (index >= (GLuint)programObject->getActiveUniformCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ programObject->getActiveUniform(index, bufsize, length, size, type, name);
+ }
}
catch(std::bad_alloc&)
{
@@ -2330,12 +2354,10 @@
*params = programObject->getActiveAttributeMaxLength();
return;
case GL_ACTIVE_UNIFORMS:
- UNIMPLEMENTED(); // FIXME
- *params = 0;
+ *params = programObject->getActiveUniformCount();
return;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- UNIMPLEMENTED(); // FIXME
- *params = 0;
+ *params = programObject->getActiveUniformMaxLength();
return;
default:
return error(GL_INVALID_ENUM);