summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2010-02-04 16:49:35 -0700
committerBrian Paul <[email protected]>2010-02-04 16:53:27 -0700
commit4ac9c80e5beea26e13ccf12ce6bd9ee051c229f5 (patch)
tree80b3ca588ae0befc950beec84fe3fdc89fd2890d
parent0f763c5b000ad87c43da12bec014d5e367ae64fe (diff)
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.
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c7
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c7
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c4
-rw-r--r--src/mesa/main/dd.h10
-rw-r--r--src/mesa/main/texenvprogram.c11
-rw-r--r--src/mesa/shader/arbprogram.c9
-rw-r--r--src/mesa/shader/atifragshader.c16
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/shader/slang/slang_link.c17
-rw-r--r--src/mesa/state_tracker/st_cb_program.c9
-rw-r--r--src/mesa/tnl/t_vb_program.c3
-rw-r--r--src/mesa/tnl/tnl.h2
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 a273bd28ea1..15e3b87097e 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 e3b6fccc49f..c78f7b38aee 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 4f225a233da..12f869d96f8 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 a4f9db13ecf..3638010e486 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 0d476fcd863..2a50361199b 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 6705c901dd5..d98a14e09c4 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 499b7330d0a..414607e2288 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 746138071ed..7e3040a6ef4 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 e04a05b22ff..ab7b2030d19 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 d53580f5f69..e8eaa9c1031 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 21497b34e25..df524ce0787 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 86c53b4e763..82ef5572e1d 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 5396548666f..44b64b17d15 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 9c66d3b0192..2c0d1fef737 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;