Add an extension for querying translated HLSL shader source.
Review URL: http://codereview.appspot.com/5149046

git-svn-id: https://angleproject.googlecode.com/svn/trunk@780 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/extensions/ANGLE_translated_shader_source.txt b/extensions/ANGLE_translated_shader_source.txt
new file mode 100644
index 0000000..5d68b55
--- /dev/null
+++ b/extensions/ANGLE_translated_shader_source.txt
@@ -0,0 +1,113 @@
+Name
+
+    ANGLE_translated_shader_source
+
+Name Strings
+
+    GL_ANGLE_translated_shader_source
+
+Contributors
+
+    Daniel Koch, TransGaming Inc.
+    Gregg Tavares, Google Inc.
+    Kenneth Russell, Google Inc.
+    Zhenyao Mo, Google Inc.
+
+Contact
+
+    Zhenyao Mo, Google Inc. (zmo 'at' google 'dot' com)
+
+Status
+
+    Implemented in ANGLE ES2
+
+Version
+
+    Last Modified Date: Septemper 29, 2011
+    Author Revision: 1
+
+Number
+
+    OpenGL ES Extension #??
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+    The extension is written against the OpenGL ES 2.0 specification.
+
+Overview
+
+    WebGL uses the GLSL ES 2.0 spec on all platforms, and translates these
+    shaders to the host platform's native language (HLSL, GLSL, and even GLSL
+    ES). For debugging purposes, it is useful to be able to examine the shader
+    after translation.
+
+    This extension addes a new function to query the translated shader source,
+    and adds a new enum for GetShaderiv's <pname> parameter to query the
+    translated shader source length. 
+
+IP Status
+
+    No known IP claims.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    void GetTranslatedShaderSourceANGLE(uint shader, sizei bufsize,
+                                        sizei* length, char* source);
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetShaderiv:
+
+    TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE              0x6900
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    Append in the end of the fourth paragraph of section 6.1.8 (Shader and
+    Program Queries):
+
+    " If <pname> is TRANSLATED_SHADER_LENGTH_ANGLE, the length of the translated
+    source string, including a null terminator, is returned. If no source has
+    been defined, CompileShader has not been called, or the translation has
+    failed for <shader>, zero is returned."
+
+    Append after the last paragraph of section 6.1.8 (Shader and Program
+    Queries):
+
+    "The command
+
+      void GetTranslatedShaderSourceANGLE( uint shader, sizei bufSize,
+         sizei *length, char *source );
+
+    returns in <source> the string making up the translated source code for
+    the shader object <shader>. The string <source> will be null terminated.
+    The actual number of characters written into <source>, excluding the null
+    terminator, is returned in <length>. If <length> is NULL, no length is
+    returned. The maximum number of characters that may be written into 
+    <source>, including the null terminator, is specified by <bufSize>. The
+    string <source> is the translated string of a concatenation of the strings
+    passed to the GL using ShaderSource. The length of this translated string
+    is given by TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, which can be queried
+    with GetShaderiv.
+
+    If no source has been defined, CompileShader has not been called, or the
+    translation has failed for <shader>, zero is returned for <length>, and
+    an empty string is returned for <source>.
+
+    If the value of SHADER_COMPILER is not TRUE, then the error INVALID_-
+    OPERATION is generated."
+
+Issues
+
+    1) 0x6900 is temporarily assigned to TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE.
+
+Revision History
+
+    Revision 1, 2011/09/29
+      - first draft
diff --git a/include/GLES2/gl2ext.h b/include/GLES2/gl2ext.h
index 9371ad7..ea8a286 100644
--- a/include/GLES2/gl2ext.h
+++ b/include/GLES2/gl2ext.h
@@ -217,6 +217,11 @@
 #define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE                      0x83F3
 #endif
 
+/* GL_ANGLE_translated_shader_source */
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE                0x6900
+#endif
+
 /*------------------------------------------------------------------------*
  * APPLE extension tokens
  *------------------------------------------------------------------------*/
@@ -810,6 +815,14 @@
 #define GL_ANGLE_texture_compression_dxt5 1
 #endif
 
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+#endif
+
 /*------------------------------------------------------------------------*
  * APPLE extension functions
  *------------------------------------------------------------------------*/
diff --git a/src/common/version.h b/src/common/version.h
index 2827ea2..95f5cfe 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 0
 #define MINOR_VERSION 0
 #define BUILD_VERSION 0
-#define BUILD_REVISION 774
+#define BUILD_REVISION 780
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index e5e05d5..58d6510 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -3434,6 +3434,7 @@
     {
         mExtensionString += "GL_ANGLE_texture_compression_dxt5 ";
     }
+    mExtensionString += "GL_ANGLE_translated_shader_source ";
 
     // Other vendor-specific extensions
     if (supportsEventQueries())
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index f66b2c5..58eed07 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -157,22 +157,34 @@
     }
 }
 
-void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
+int Shader::getTranslatedSourceLength() const
+{
+    if (!mHlsl)
+    {
+        return 0;
+    }
+    else
+    {
+       return strlen(mHlsl) + 1;
+    }
+}
+
+void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
 {
     int index = 0;
 
-    if (mSource)
+    if (source)
     {
-        while (index < bufSize - 1 && index < (int)strlen(mSource))
+        while (index < bufSize - 1 && index < (int)strlen(source))
         {
-            source[index] = mSource[index];
+            buffer[index] = source[index];
             index++;
         }
     }
 
     if (bufSize)
     {
-        source[index] = '\0';
+        buffer[index] = '\0';
     }
 
     if (length)
@@ -181,6 +193,16 @@
     }
 }
 
+void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
+{
+    getSourceImpl(mSource, bufSize, length, buffer);
+}
+
+void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
+{
+    getSourceImpl(mHlsl, bufSize, length, buffer);
+}
+
 bool Shader::isCompiled()
 {
     return mHlsl != NULL;
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index 535b42d..22fc637 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -57,7 +57,9 @@
     int getInfoLogLength() const;
     void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
     int getSourceLength() const;
-    void getSource(GLsizei bufSize, GLsizei *length, char *source);
+    void getSource(GLsizei bufSize, GLsizei *length, char *buffer);
+    int getTranslatedSourceLength() const;
+    void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer);
 
     virtual void compile() = 0;
     bool isCompiled();
@@ -78,6 +80,8 @@
 
     void compileToHLSL(void *compiler);
 
+    void getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer);
+
     static GLenum parseType(const std::string &type);
     static bool compareVarying(const Varying &x, const Varying &y);
 
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 5a816d4..bf6f447 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -3089,6 +3089,9 @@
               case GL_SHADER_SOURCE_LENGTH:
                 *params = shaderObject->getSourceLength();
                 return;
+              case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+                *params = shaderObject->getTranslatedSourceLength();
+                return;
               default:
                 return error(GL_INVALID_ENUM);
             }
@@ -3209,6 +3212,38 @@
     }
 }
 
+void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+    EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
+          shader, bufsize, length, source);
+
+    try
+    {
+        if (bufsize < 0)
+        {
+            return error(GL_INVALID_VALUE);
+        }
+
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Shader *shaderObject = context->getShader(shader);
+
+            if (!shaderObject)
+            {
+                return error(GL_INVALID_OPERATION);
+            }
+
+            shaderObject->getTranslatedSource(bufsize, length, source);
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
 const GLubyte* __stdcall glGetString(GLenum name)
 {
     EVENT("(GLenum name = 0x%X)", name);
@@ -5769,6 +5804,7 @@
         {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
         {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
         {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
+        {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
     };
 
     for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
diff --git a/src/libGLESv2/libGLESv2.def b/src/libGLESv2/libGLESv2.def
index b912171..4793f75 100644
--- a/src/libGLESv2/libGLESv2.def
+++ b/src/libGLESv2/libGLESv2.def
@@ -154,6 +154,7 @@
     glIsFenceNV                     @155
     glSetFenceNV                    @156
     glTestFenceNV                   @157
+    glGetTranslatedShaderSourceANGLE @159
 
     ; EGL dependencies
     glCreateContext                 @144 NONAME