From 5cb24c4a75cd0b45bb332721c3d0e5a1f928b6f4 Mon Sep 17 00:00:00 2001
From: Ian Romanick <ian.d.romanick@intel.com>
Date: Mon, 11 Oct 2010 15:21:17 -0700
Subject: mesa: Refactor validation of shader targets

Actually validate that the implementation supports the particular
shader target as well.  Previously if a driver only supported vertex
shaders, for example, glCreateShaderObjectARB would gladly create a
fragment shader.

NOTE: this is a candidate for the 7.9 branch.
---
 src/mesa/main/shaderapi.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

(limited to 'src')

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 9a2a42e50e..c90e5b74cb 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -47,7 +47,7 @@
 #include "program/prog_parameter.h"
 #include "program/prog_uniform.h"
 #include "talloc.h"
-
+#include <stdbool.h>
 
 /** Define this to enable shader substitution (see below) */
 #define SHADER_SUBST 0
@@ -201,6 +201,35 @@ _mesa_copy_string(GLchar *dst, GLsizei maxLength,
 
 
 
+/**
+ * Confirm that the a shader type is valid and supported by the implementation
+ *
+ * \param ctx   Current GL context
+ * \param type  Shader target
+ *
+ */
+static bool
+validate_shader_target(const struct gl_context *ctx, GLenum type)
+{
+   switch (type) {
+#if FEATURE_ARB_fragment_shader
+   case GL_FRAGMENT_SHADER:
+      return ctx->Extensions.ARB_fragment_shader;
+#endif
+#if FEATURE_ARB_vertex_shader
+   case GL_VERTEX_SHADER:
+      return ctx->Extensions.ARB_vertex_shader;
+#endif
+#if FEATURE_ARB_geometry_shader4
+   case GL_GEOMETRY_SHADER_ARB:
+      return ctx->Extensions.ARB_geometry_shader4;
+#endif
+   default:
+      return false;
+   }
+}
+
+
 /**
  * Find the length of the longest transform feedback varying name
  * which was specified with glTransformFeedbackVaryings().
@@ -376,19 +405,13 @@ create_shader(struct gl_context *ctx, GLenum type)
    struct gl_shader *sh;
    GLuint name;
 
-   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-
-   switch (type) {
-   case GL_FRAGMENT_SHADER:
-   case GL_VERTEX_SHADER:
-   case GL_GEOMETRY_SHADER_ARB:
-      sh = ctx->Driver.NewShader(ctx, name, type);
-      break;
-   default:
+   if (!validate_shader_target(ctx, type)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
       return 0;
    }
 
+   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
+   sh = ctx->Driver.NewShader(ctx, name, type);
    _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
 
    return name;
-- 
cgit v1.2.3