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.
This commit is contained in:
@@ -1205,7 +1205,7 @@ i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GLboolean
|
||||||
i915ProgramStringNotify(GLcontext * ctx,
|
i915ProgramStringNotify(GLcontext * ctx,
|
||||||
GLenum target, struct gl_program *prog)
|
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
|
void
|
||||||
|
@@ -111,9 +111,10 @@ static GLboolean brwIsProgramNative( GLcontext *ctx,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void brwProgramStringNotify( GLcontext *ctx,
|
|
||||||
GLenum target,
|
static GLboolean brwProgramStringNotify( GLcontext *ctx,
|
||||||
struct gl_program *prog )
|
GLenum target,
|
||||||
|
struct gl_program *prog )
|
||||||
{
|
{
|
||||||
struct brw_context *brw = brw_context(ctx);
|
struct brw_context *brw = brw_context(ctx);
|
||||||
|
|
||||||
@@ -150,6 +151,9 @@ static void brwProgramStringNotify( GLcontext *ctx,
|
|||||||
*/
|
*/
|
||||||
_tnl_program_string(ctx, target, prog);
|
_tnl_program_string(ctx, target, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX check if program is legal, within limits */
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void brwInitFragProgFuncs( struct dd_function_table *functions )
|
void brwInitFragProgFuncs( struct dd_function_table *functions )
|
||||||
|
@@ -1218,7 +1218,7 @@ r200DeleteProgram(GLcontext *ctx, struct gl_program *prog)
|
|||||||
_mesa_delete_program(ctx, prog);
|
_mesa_delete_program(ctx, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GLboolean
|
||||||
r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
|
r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
|
||||||
{
|
{
|
||||||
struct r200_vertex_program *vp = (void *)prog;
|
struct r200_vertex_program *vp = (void *)prog;
|
||||||
@@ -1237,7 +1237,10 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* need this for tcl fallbacks */
|
/* 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
|
static GLboolean
|
||||||
|
@@ -98,7 +98,7 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog)
|
|||||||
_mesa_delete_program(ctx, prog);
|
_mesa_delete_program(ctx, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GLboolean
|
||||||
r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
||||||
{
|
{
|
||||||
struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)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 */
|
/* 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
|
static GLboolean
|
||||||
|
@@ -132,7 +132,7 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
|
|||||||
_mesa_delete_program(ctx, prog);
|
_mesa_delete_program(ctx, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GLboolean
|
||||||
r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
||||||
{
|
{
|
||||||
struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX check if program is legal, within limits */
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
||||||
|
@@ -581,9 +581,13 @@ struct dd_function_table {
|
|||||||
struct gl_program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id);
|
struct gl_program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id);
|
||||||
/** Delete a program */
|
/** Delete a program */
|
||||||
void (*DeleteProgram)(GLcontext *ctx, struct gl_program *prog);
|
void (*DeleteProgram)(GLcontext *ctx, struct gl_program *prog);
|
||||||
/** Notify driver that a program string has been specified. */
|
/**
|
||||||
void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
|
* Notify driver that a program string (and GPU code) has been specified
|
||||||
struct gl_program *prog);
|
* 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 */
|
/** Query if program can be loaded onto hardware */
|
||||||
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
|
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
|
||||||
|
@@ -1535,8 +1535,15 @@ create_new_program(GLcontext *ctx, struct state_key *key,
|
|||||||
/* Notify driver the fragment program has (actually) changed.
|
/* Notify driver the fragment program has (actually) changed.
|
||||||
*/
|
*/
|
||||||
if (ctx->Driver.ProgramStringNotify) {
|
if (ctx->Driver.ProgramStringNotify) {
|
||||||
ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB,
|
GLboolean ok = ctx->Driver.ProgramStringNotify(ctx,
|
||||||
&p.program->Base );
|
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) {
|
if (DISASSEM) {
|
||||||
|
@@ -489,8 +489,13 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
|
if (ctx->Program.ErrorPos == -1) {
|
||||||
ctx->Driver.ProgramStringNotify( ctx, target, base );
|
/* 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -378,8 +378,11 @@ _mesa_EndFragmentShaderATI(void)
|
|||||||
}
|
}
|
||||||
if (ctx->ATIFragmentShader.Current->cur_pass > 1)
|
if (ctx->ATIFragmentShader.Current->cur_pass > 1)
|
||||||
ctx->ATIFragmentShader.Current->NumPasses = 2;
|
ctx->ATIFragmentShader.Current->NumPasses = 2;
|
||||||
else ctx->ATIFragmentShader.Current->NumPasses = 1;
|
else
|
||||||
ctx->ATIFragmentShader.Current->cur_pass=0;
|
ctx->ATIFragmentShader.Current->NumPasses = 1;
|
||||||
|
|
||||||
|
ctx->ATIFragmentShader.Current->cur_pass = 0;
|
||||||
|
|
||||||
#if MESA_DEBUG_ATI_FS
|
#if MESA_DEBUG_ATI_FS
|
||||||
for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
|
for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
|
||||||
for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
|
for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
|
||||||
@@ -402,8 +405,13 @@ _mesa_EndFragmentShaderATI(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
void GLAPIENTRY
|
||||||
|
@@ -1715,7 +1715,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
|
|||||||
*/
|
*/
|
||||||
FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
|
FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
|
||||||
_mesa_update_shader_textures_used(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 {
|
else {
|
||||||
|
@@ -719,6 +719,7 @@ _slang_link(GLcontext *ctx,
|
|||||||
{
|
{
|
||||||
const struct gl_vertex_program *vertProg = NULL;
|
const struct gl_vertex_program *vertProg = NULL;
|
||||||
const struct gl_fragment_program *fragProg = NULL;
|
const struct gl_fragment_program *fragProg = NULL;
|
||||||
|
GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
|
||||||
GLuint numSamplers = 0;
|
GLuint numSamplers = 0;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
@@ -871,8 +872,8 @@ _slang_link(GLcontext *ctx,
|
|||||||
_mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
|
_mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
|
||||||
|
|
||||||
/* notify driver that a new fragment program has been compiled/linked */
|
/* notify driver that a new fragment program has been compiled/linked */
|
||||||
ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
|
vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
|
||||||
&shProg->FragmentProgram->Base);
|
&shProg->FragmentProgram->Base);
|
||||||
if (ctx->Shader.Flags & GLSL_DUMP) {
|
if (ctx->Shader.Flags & GLSL_DUMP) {
|
||||||
_mesa_printf("Mesa pre-link fragment program:\n");
|
_mesa_printf("Mesa pre-link fragment program:\n");
|
||||||
_mesa_print_program(&fragProg->Base);
|
_mesa_print_program(&fragProg->Base);
|
||||||
@@ -889,8 +890,8 @@ _slang_link(GLcontext *ctx,
|
|||||||
_mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
|
_mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
|
||||||
|
|
||||||
/* notify driver that a new vertex program has been compiled/linked */
|
/* notify driver that a new vertex program has been compiled/linked */
|
||||||
ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
|
fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
|
||||||
&shProg->VertexProgram->Base);
|
&shProg->VertexProgram->Base);
|
||||||
if (ctx->Shader.Flags & GLSL_DUMP) {
|
if (ctx->Shader.Flags & GLSL_DUMP) {
|
||||||
_mesa_printf("Mesa pre-link vertex program:\n");
|
_mesa_printf("Mesa pre-link vertex program:\n");
|
||||||
_mesa_print_program(&vertProg->Base);
|
_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -177,9 +177,9 @@ static GLboolean st_is_program_native( GLcontext *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void st_program_string_notify( GLcontext *ctx,
|
static GLboolean st_program_string_notify( GLcontext *ctx,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
struct gl_program *prog )
|
struct gl_program *prog )
|
||||||
{
|
{
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
|
|
||||||
@@ -211,6 +211,9 @@ static void st_program_string_notify( GLcontext *ctx,
|
|||||||
if (st->vp == stvp)
|
if (st->vp == stvp)
|
||||||
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
|
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX check if program is legal, within limits */
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
* Called via ctx->Driver.ProgramStringNotify() after a new vertex program
|
||||||
* string has been parsed.
|
* string has been parsed.
|
||||||
*/
|
*/
|
||||||
void
|
GLboolean
|
||||||
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
|
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
|
||||||
{
|
{
|
||||||
/* No-op.
|
/* No-op.
|
||||||
* If we had derived anything from the program that was private to this
|
* If we had derived anything from the program that was private to this
|
||||||
* stage we'd recompute/validate it here.
|
* stage we'd recompute/validate it here.
|
||||||
*/
|
*/
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -66,7 +66,7 @@ _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value );
|
|||||||
extern void
|
extern void
|
||||||
_tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value );
|
_tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value );
|
||||||
|
|
||||||
extern void
|
extern GLboolean
|
||||||
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program);
|
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program);
|
||||||
|
|
||||||
struct _mesa_prim;
|
struct _mesa_prim;
|
||||||
|
Reference in New Issue
Block a user