Mesa (master): mesa: change ctx->Driver.ProgramStringNotify() to return GLboolean

Brian Paul brianp at kemper.freedesktop.org
Thu Feb 4 23:58:14 UTC 2010


Module: Mesa
Branch: master
Commit: 4ac9c80e5beea26e13ccf12ce6bd9ee051c229f5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4ac9c80e5beea26e13ccf12ce6bd9ee051c229f5

Author: Brian Paul <brianp at vmware.com>
Date:   Thu Feb  4 16:49:35 2010 -0700

mesa: change ctx->Driver.ProgramStringNotify() to return GLboolean

GL_TRUE indicates that the driver accepts the program.
GL_FALSE indicates the program can't be compiled/translated by the
driver for some reason (too many resources used, etc).

Propogate this result up to the GL API: set GL_INVALID_OPERATION
error if glProgramString() was called.  Set shader program link
status to GL_FALSE if glLinkProgram() was called.

At this point, drivers still don't do any program checking and
always return GL_TRUE.

---

 src/mesa/drivers/dri/i915/i915_fragprog.c |    7 +++++--
 src/mesa/drivers/dri/i965/brw_program.c   |   10 +++++++---
 src/mesa/drivers/dri/r200/r200_vertprog.c |    7 +++++--
 src/mesa/drivers/dri/r300/r300_shader.c   |    7 +++++--
 src/mesa/drivers/dri/r600/r700_oglprog.c  |    4 +++-
 src/mesa/main/dd.h                        |   10 +++++++---
 src/mesa/main/texenvprogram.c             |   11 +++++++++--
 src/mesa/shader/arbprogram.c              |    9 +++++++--
 src/mesa/shader/atifragshader.c           |   16 ++++++++++++----
 src/mesa/shader/shader_api.c              |    6 +++++-
 src/mesa/shader/slang/slang_link.c        |   17 ++++++++++++-----
 src/mesa/state_tracker/st_cb_program.c    |    9 ++++++---
 src/mesa/tnl/t_vb_program.c               |    3 ++-
 src/mesa/tnl/tnl.h                        |    2 +-
 14 files changed, 86 insertions(+), 32 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index a273bd2..15e3b87 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -1205,7 +1205,7 @@ i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
       return GL_TRUE;
 }
 
-static void
+static GLboolean
 i915ProgramStringNotify(GLcontext * ctx,
                         GLenum target, struct gl_program *prog)
 {
@@ -1223,7 +1223,10 @@ i915ProgramStringNotify(GLcontext * ctx,
       }
    }
 
-   _tnl_program_string(ctx, target, prog);
+   (void) _tnl_program_string(ctx, target, prog);
+
+   /* XXX check if program is legal, within limits */
+   return GL_TRUE;
 }
 
 void
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index e3b6fcc..c78f7b3 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -111,9 +111,10 @@ static GLboolean brwIsProgramNative( GLcontext *ctx,
    return GL_TRUE;
 }
 
-static void brwProgramStringNotify( GLcontext *ctx,
-				    GLenum target,
-				    struct gl_program *prog )
+
+static GLboolean brwProgramStringNotify( GLcontext *ctx,
+                                         GLenum target,
+                                         struct gl_program *prog )
 {
    struct brw_context *brw = brw_context(ctx);
 
@@ -150,6 +151,9 @@ static void brwProgramStringNotify( GLcontext *ctx,
        */
       _tnl_program_string(ctx, target, prog);
    }
+
+   /* XXX check if program is legal, within limits */
+   return GL_TRUE;
 }
 
 void brwInitFragProgFuncs( struct dd_function_table *functions )
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 4f225a2..12f869d 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -1218,7 +1218,7 @@ r200DeleteProgram(GLcontext *ctx, struct gl_program *prog)
    _mesa_delete_program(ctx, prog);
 }
 
-static void
+static GLboolean
 r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
 {
    struct r200_vertex_program *vp = (void *)prog;
@@ -1237,7 +1237,10 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
       break;
    }
    /* need this for tcl fallbacks */
-   _tnl_program_string(ctx, target, prog);
+   (void) _tnl_program_string(ctx, target, prog);
+
+   /* XXX check if program is legal, within limits */
+   return GL_TRUE;
 }
 
 static GLboolean
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index a4f9db1..3638010 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -98,7 +98,7 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog)
 	_mesa_delete_program(ctx, prog);
 }
 
-static void
+static GLboolean
 r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
 {
 	struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog;
@@ -116,7 +116,10 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
 	}
 
 	/* need this for tcl fallbacks */
-	_tnl_program_string(ctx, target, prog);
+	(void) _tnl_program_string(ctx, target, prog);
+
+	/* XXX check if program is legal, within limits */
+	return GL_TRUE;
 }
 
 static GLboolean
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 0d476fc..2a50361 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -132,7 +132,7 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
 	_mesa_delete_program(ctx, prog);
 }
 
-static void
+static GLboolean
 r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
 {
 	struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
@@ -153,6 +153,8 @@ r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
 		break;
 	}
 		
+	/* XXX check if program is legal, within limits */
+	return GL_TRUE;
 }
 
 static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 6705c90..d98a14e 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -581,9 +581,13 @@ struct dd_function_table {
    struct gl_program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id);
    /** Delete a program */
    void (*DeleteProgram)(GLcontext *ctx, struct gl_program *prog);   
-   /** Notify driver that a program string has been specified. */
-   void (*ProgramStringNotify)(GLcontext *ctx, GLenum target, 
-			       struct gl_program *prog);
+   /**
+    * Notify driver that a program string (and GPU code) has been specified
+    * or modified.  Return GL_TRUE or GL_FALSE to indicate if the program is
+    * supported by the driver.
+    */
+   GLboolean (*ProgramStringNotify)(GLcontext *ctx, GLenum target, 
+                                    struct gl_program *prog);
 
    /** Query if program can be loaded onto hardware */
    GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target, 
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 499b733..414607e 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1535,8 +1535,15 @@ create_new_program(GLcontext *ctx, struct state_key *key,
    /* Notify driver the fragment program has (actually) changed.
     */
    if (ctx->Driver.ProgramStringNotify) {
-      ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, 
-                                       &p.program->Base );
+      GLboolean ok = ctx->Driver.ProgramStringNotify(ctx,
+                                                     GL_FRAGMENT_PROGRAM_ARB, 
+                                                     &p.program->Base);
+      /* Driver should be able to handle any texenv programs as long as
+       * the driver correctly reported max number of texture units correctly,
+       * etc.
+       */
+      ASSERT(ok);
+      (void) ok; /* silence unused var warning */
    }
 
    if (DISASSEM) {
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 7461380..7e3040a 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -489,8 +489,13 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
       return;
    }
 
-   if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
-      ctx->Driver.ProgramStringNotify( ctx, target, base );
+   if (ctx->Program.ErrorPos == -1) {
+      /* finally, give the program to the driver for translation/checking */
+      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glProgramStringARB(rejected by driver");
+      }
+   }
 }
 
 
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index e04a05b..ab7b203 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -378,8 +378,11 @@ _mesa_EndFragmentShaderATI(void)
    }
    if (ctx->ATIFragmentShader.Current->cur_pass > 1)
       ctx->ATIFragmentShader.Current->NumPasses = 2;
-   else ctx->ATIFragmentShader.Current->NumPasses = 1;
-   ctx->ATIFragmentShader.Current->cur_pass=0;
+   else
+      ctx->ATIFragmentShader.Current->NumPasses = 1;
+
+   ctx->ATIFragmentShader.Current->cur_pass = 0;
+
 #if MESA_DEBUG_ATI_FS
    for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
       for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
@@ -402,8 +405,13 @@ _mesa_EndFragmentShaderATI(void)
       }
    }
 #endif
-   if (ctx->Driver.ProgramStringNotify)
-      ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL );
+
+   if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
+      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+      /* XXX is this the right error? */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glEndFragmentShaderATI(driver rejected shader)");
+   }
 }
 
 void GLAPIENTRY
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index d53580f..e8eaa9c 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1715,7 +1715,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
           */
          FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
          _mesa_update_shader_textures_used(program);
-         ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+         /* Do we need to care about the return value here?
+          * This should not be the first time the driver was notified of
+          * this program.
+          */
+         (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
       }
    }
    else {
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 21497b3..df524ce 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -719,6 +719,7 @@ _slang_link(GLcontext *ctx,
 {
    const struct gl_vertex_program *vertProg = NULL;
    const struct gl_fragment_program *fragProg = NULL;
+   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
    GLuint numSamplers = 0;
    GLuint i;
 
@@ -871,8 +872,8 @@ _slang_link(GLcontext *ctx,
       _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
 
       /* notify driver that a new fragment program has been compiled/linked */
-      ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                                      &shProg->FragmentProgram->Base);
+      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+                                                 &shProg->FragmentProgram->Base);
       if (ctx->Shader.Flags & GLSL_DUMP) {
          _mesa_printf("Mesa pre-link fragment program:\n");
          _mesa_print_program(&fragProg->Base);
@@ -889,8 +890,8 @@ _slang_link(GLcontext *ctx,
       _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
 
       /* notify driver that a new vertex program has been compiled/linked */
-      ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-                                      &shProg->VertexProgram->Base);
+      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+                                                   &shProg->VertexProgram->Base);
       if (ctx->Shader.Flags & GLSL_DUMP) {
          _mesa_printf("Mesa pre-link vertex program:\n");
          _mesa_print_program(&vertProg->Base);
@@ -918,6 +919,12 @@ _slang_link(GLcontext *ctx,
       }
    }
 
-   shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+   if (!vertNotify || !fragNotify) {
+      /* driver rejected one/both of the vertex/fragment programs */
+      link_error(shProg, "Vertex and/or fragment program rejected by driver\n");
+   }
+   else {
+      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+   }
 }
 
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 86c53b4..82ef557 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -177,9 +177,9 @@ static GLboolean st_is_program_native( GLcontext *ctx,
 }
 
 
-static void st_program_string_notify( GLcontext *ctx,
-				      GLenum target,
-				      struct gl_program *prog )
+static GLboolean st_program_string_notify( GLcontext *ctx,
+                                           GLenum target,
+                                           struct gl_program *prog )
 {
    struct st_context *st = st_context(ctx);
 
@@ -211,6 +211,9 @@ static void st_program_string_notify( GLcontext *ctx,
       if (st->vp == stvp)
 	 st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
    }
+
+   /* XXX check if program is legal, within limits */
+   return GL_TRUE;
 }
 
 
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 5396548..44b64b1 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -203,13 +203,14 @@ vp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
  * Called via ctx->Driver.ProgramStringNotify() after a new vertex program
  * string has been parsed.
  */
-void
+GLboolean
 _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
 {
    /* No-op.
     * If we had derived anything from the program that was private to this
     * stage we'd recompute/validate it here.
     */
+   return GL_TRUE;
 }
 
 
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
index 9c66d3b..2c0d1fe 100644
--- a/src/mesa/tnl/tnl.h
+++ b/src/mesa/tnl/tnl.h
@@ -66,7 +66,7 @@ _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value );
 extern void
 _tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value );
 
-extern void
+extern GLboolean
 _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program);
 
 struct _mesa_prim;




More information about the mesa-commit mailing list