YaGL: Shader precision test removed, it's not needed, we just assume that it always...
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Wed, 22 May 2013 06:58:53 +0000 (10:58 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Wed, 22 May 2013 06:58:53 +0000 (10:58 +0400)
YaGL: Add #version directive to shaders when it's not already present

hw/yagl_apis/gles2/yagl_gles2_context.c
hw/yagl_apis/gles2/yagl_gles2_context.h
hw/yagl_apis/gles2/yagl_gles2_shader.c
hw/yagl_apis/gles2/yagl_gles2_shader.h
hw/yagl_apis/gles2/yagl_host_gles2_calls.c

index 9c3b1dc..f518dbf 100644 (file)
@@ -373,33 +373,6 @@ static void yagl_gles2_context_destroy(struct yagl_client_context *ctx)
     YAGL_LOG_FUNC_EXIT(NULL);
 }
 
-static const char* g_shader_precision_test =
-    "varying lowp vec4 c;\n"
-    "void main(void) { gl_FragColor=c; }\n";
-
-static bool yagl_gles2_shader_precision_supported(struct yagl_gles2_driver *driver)
-{
-    GLuint shader = driver->CreateShader(GL_FRAGMENT_SHADER);
-    GLint status = GL_FALSE;
-
-    YAGL_LOG_FUNC_ENTER(yagl_gles2_shader_precision_supported, NULL);
-
-    driver->ShaderSource(shader, 1, &g_shader_precision_test, 0);
-    driver->CompileShader(shader);
-    driver->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
-    driver->DeleteShader(shader);
-
-    if (status == GL_FALSE) {
-        YAGL_LOG_WARN("Host OpenGL implementation doesn't understand precision keyword");
-    } else {
-        YAGL_LOG_DEBUG("Host OpenGL implementation understands precision keyword");
-    }
-
-    YAGL_LOG_FUNC_EXIT(NULL);
-
-    return (status != GL_FALSE);
-}
-
 static void yagl_gles2_context_prepare(struct yagl_gles2_context *gles2_ctx)
 {
     struct yagl_gles_driver *gles_driver = &gles2_ctx->driver->base;
@@ -435,9 +408,6 @@ static void yagl_gles2_context_prepare(struct yagl_gles2_context *gles2_ctx)
     yagl_gles_context_prepare(&gles2_ctx->base, arrays, num_arrays,
                               num_texture_units);
 
-    gles2_ctx->shader_strip_precision =
-        !yagl_gles2_shader_precision_supported(gles2_ctx->driver);
-
     /*
      * We don't support it for now...
      */
@@ -528,7 +498,6 @@ struct yagl_gles2_context
     gles2_ctx->driver = driver;
     gles2_ctx->prepared = false;
     gles2_ctx->sg = sg;
-    gles2_ctx->shader_strip_precision = true;
 
     gles2_ctx->num_shader_binary_formats = 0;
 
index fa5835b..7261888 100644 (file)
@@ -20,12 +20,6 @@ struct yagl_gles2_context
      */
     struct yagl_sharegroup *sg;
 
-    /*
-     * Strip 'precision' keyword from shaders because
-     * host implementation doesn't support them.
-     */
-    bool shader_strip_precision;
-
     int num_shader_binary_formats;
 
     bool texture_half_float;
index fb5641e..48df920 100644 (file)
@@ -194,33 +194,44 @@ static char *yagl_gles2_shader_patch(const char *source,
 
 void yagl_gles2_shader_source(struct yagl_gles2_shader *shader,
                               GLchar **strings,
-                              int count,
-                              bool strip_precision)
+                              int count)
 {
     GLchar **processed_strings = NULL;
     GLint *lengths = NULL;
     int i;
 
-    if (strip_precision) {
-        processed_strings = g_malloc0(count * sizeof(*processed_strings));
-    }
+    processed_strings = g_malloc0(count * sizeof(*processed_strings));
 
     lengths = g_malloc0(count * sizeof(*lengths));
 
     for (i = 0; i < count; ++i) {
-        if (strip_precision) {
-            processed_strings[i] = yagl_gles2_shader_patch(strings[i],
-                                                           strlen(strings[i]),
-                                                           &lengths[i]);
-
-        } else {
-            lengths[i] = strlen(strings[i]);
+        processed_strings[i] = yagl_gles2_shader_patch(strings[i],
+                                                       strlen(strings[i]),
+                                                       &lengths[i]);
+        if (i == 0) {
+            /*
+             * On some GPUs (like Ivybridge Desktop) it's necessary to add
+             * "#version" directive as the first line of the shader, otherwise
+             * some of the features might not be available to the shader.
+             *
+             * For example, on Ivybridge Desktop, if we don't add the "#version"
+             * line to the fragment shader then "gl_PointCoord"
+             * won't be available.
+             */
+            if (strstr(processed_strings[i], "#version") == NULL) {
+                char *tmp = g_malloc(strlen(processed_strings[i]) + sizeof("#version 120\n\n"));
+                strcpy(tmp, "#version 120\n\n");
+                strcat(tmp, processed_strings[i]);
+                g_free(processed_strings[i]);
+                processed_strings[i] = tmp;
+                lengths[i] = strlen(tmp);
+            }
         }
     }
 
     shader->driver->ShaderSource(shader->global_name,
                                  count,
-                                 (const GLchar**)(strip_precision ? processed_strings : strings),
+                                 (const GLchar**)processed_strings,
                                  lengths);
 
     g_free(lengths);
index 4d13201..6635f11 100644 (file)
@@ -38,8 +38,7 @@ struct yagl_gles2_shader
 
 void yagl_gles2_shader_source(struct yagl_gles2_shader *shader,
                               GLchar **strings,
-                              int count,
-                              bool strip_precision);
+                              int count);
 
 void yagl_gles2_shader_compile(struct yagl_gles2_shader *shader);
 
index 38d2015..79b7184 100644 (file)
@@ -1545,8 +1545,7 @@ bool yagl_host_glShaderSource(GLuint shader,
 
     yagl_gles2_shader_source(shader_obj,
                              strings,
-                             count,
-                             ctx->shader_strip_precision);
+                             count);
 
 out:
     if (strings) {