}
-static void
-detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
+static ALWAYS_INLINE void
+detach_shader(struct gl_context *ctx, GLuint program, GLuint shader,
+ bool no_error)
{
struct gl_shader_program *shProg;
GLuint n;
GLuint i, j;
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
- if (!shProg)
- return;
+ if (!no_error) {
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
+ if (!shProg)
+ return;
+ } else {
+ shProg = _mesa_lookup_shader_program(ctx, program);
+ }
n = shProg->NumShaders;
}
/* not found */
- {
+ if (!no_error) {
GLenum err;
if (is_shader(ctx, shader) || is_program(ctx, shader))
err = GL_INVALID_OPERATION;
}
+static void
+detach_shader_error(struct gl_context *ctx, GLuint program, GLuint shader)
+{
+ detach_shader(ctx, program, shader, false);
+}
+
+
+static void
+detach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader)
+{
+ detach_shader(ctx, program, shader, true);
+}
+
+
/**
* Return list of shaders attached to shader program.
*/
* glShaderSource[ARB].
*/
static void
-shader_source(struct gl_shader *sh, const GLchar *source)
+set_shader_source(struct gl_shader *sh, const GLchar *source)
{
assert(sh);
/**
* Link a program's shaders.
*/
-void
-_mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
+static ALWAYS_INLINE void
+link_program(struct gl_context *ctx, struct gl_shader_program *shProg,
+ bool no_error)
{
if (!shProg)
return;
- /* From the ARB_transform_feedback2 specification:
- * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
- * the name of a program being used by one or more transform feedback
- * objects, even if the objects are not currently bound or are paused."
- */
- if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLinkProgram(transform feedback is using the program)");
- return;
+ if (!no_error) {
+ /* From the ARB_transform_feedback2 specification:
+ * "The error INVALID_OPERATION is generated by LinkProgram if <program>
+ * is the name of a program being used by one or more transform feedback
+ * objects, even if the objects are not currently bound or are paused."
+ */
+ if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glLinkProgram(transform feedback is using the program)");
+ return;
+ }
}
unsigned programs_in_use = 0;
}
+static void
+link_program_error(struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ link_program(ctx, shProg, false);
+}
+
+
+static void
+link_program_no_error(struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ link_program(ctx, shProg, true);
+}
+
+
+void
+_mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ link_program_error(ctx, shProg);
+}
+
+
/**
* Print basic shader info (for debug).
*/
}
+void GLAPIENTRY
+_mesa_DetachObjectARB_no_error(GLhandleARB program, GLhandleARB shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ detach_shader_no_error(ctx, program, shader);
+}
+
+
void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
- detach_shader(ctx, program, shader);
+ detach_shader_error(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_DetachShader_no_error(GLuint program, GLuint shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ detach_shader_no_error(ctx, program, shader);
}
_mesa_DetachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
- detach_shader(ctx, program, shader);
+ detach_shader_error(ctx, program, shader);
}
}
+void GLAPIENTRY
+_mesa_LinkProgram_no_error(GLuint programObj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program(ctx, programObj);
+ link_program_no_error(ctx, shProg);
+}
+
+
void GLAPIENTRY
_mesa_LinkProgram(GLuint programObj)
{
GET_CURRENT_CONTEXT(ctx);
+
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glLinkProgram %u\n", programObj);
- _mesa_link_program(ctx, _mesa_lookup_shader_program_err(ctx, programObj,
- "glLinkProgram"));
+
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, programObj, "glLinkProgram");
+ link_program_error(ctx, shProg);
}
#ifdef ENABLE_SHADER_CACHE
* Basically, concatenate the source code strings into one long string
* and pass it to _mesa_shader_source().
*/
-void GLAPIENTRY
-_mesa_ShaderSource(GLuint shaderObj, GLsizei count,
- const GLchar * const * string, const GLint * length)
+static ALWAYS_INLINE void
+shader_source(struct gl_context *ctx, GLuint shaderObj, GLsizei count,
+ const GLchar *const *string, const GLint *length, bool no_error)
{
- GET_CURRENT_CONTEXT(ctx);
GLint *offsets;
GLsizei i, totalLength;
GLcharARB *source;
struct gl_shader *sh;
- sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
- if (!sh)
- return;
+ if (!no_error) {
+ sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
+ if (!sh)
+ return;
- if (string == NULL) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
- return;
+ if (string == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
+ return;
+ }
+ } else {
+ sh = _mesa_lookup_shader(ctx, shaderObj);
}
/*
}
for (i = 0; i < count; i++) {
- if (string[i] == NULL) {
+ if (!no_error && string[i] == NULL) {
free((GLvoid *) offsets);
_mesa_error(ctx, GL_INVALID_OPERATION,
"glShaderSourceARB(null string)");
}
#endif /* ENABLE_SHADER_CACHE */
- shader_source(sh, source);
+ set_shader_source(sh, source);
free(offsets);
}
+void GLAPIENTRY
+_mesa_ShaderSource_no_error(GLuint shaderObj, GLsizei count,
+ const GLchar *const *string, const GLint *length)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ shader_source(ctx, shaderObj, count, string, length, true);
+}
+
+
+void GLAPIENTRY
+_mesa_ShaderSource(GLuint shaderObj, GLsizei count,
+ const GLchar *const *string, const GLint *length)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ shader_source(ctx, shaderObj, count, string, length, false);
+}
+
+
static ALWAYS_INLINE void
use_program(GLuint program, bool no_error)
{
}
-void GLAPIENTRY
-_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
+static ALWAYS_INLINE void
+program_parameteri(struct gl_context *ctx, struct gl_shader_program *shProg,
+ GLuint pname, GLint value, bool no_error)
{
- struct gl_shader_program *shProg;
- GET_CURRENT_CONTEXT(ctx);
-
- shProg = _mesa_lookup_shader_program_err(ctx, program,
- "glProgramParameteri");
- if (!shProg)
- return;
-
switch (pname) {
case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
/* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
* "An INVALID_VALUE error is generated if the <value> argument to
* ProgramParameteri is not TRUE or FALSE."
*/
- if (value != GL_TRUE && value != GL_FALSE) {
+ if (!no_error && value != GL_TRUE && value != GL_FALSE) {
goto invalid_value;
}
/* Spec imply that the behavior is the same as ARB_get_program_binary
* Chapter 7.3 Program Objects
*/
- if (value != GL_TRUE && value != GL_FALSE) {
+ if (!no_error && value != GL_TRUE && value != GL_FALSE) {
goto invalid_value;
}
shProg->SeparateShader = value;
return;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
- _mesa_enum_to_string(pname));
+ if (!no_error) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
+ _mesa_enum_to_string(pname));
+ }
return;
}
}
+void GLAPIENTRY
+_mesa_ProgramParameteri_no_error(GLuint program, GLenum pname, GLint value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program);
+ program_parameteri(ctx, shProg, pname, value, true);
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ struct gl_shader_program *shProg;
+ GET_CURRENT_CONTEXT(ctx);
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramParameteri");
+ if (!shProg)
+ return;
+
+ program_parameteri(ctx, shProg, pname, value, false);
+}
+
+
void
_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
struct gl_shader_program *shProg, struct gl_program *prog,
if (compiled) {
attach_shader_err(ctx, program, shader, "glCreateShaderProgramv");
_mesa_link_program(ctx, shProg);
- detach_shader(ctx, program, shader);
+ detach_shader_error(ctx, program, shader);
#if 0
/* Possibly... */
/**
* For GL_ARB_tessellation_shader
*/
+void GLAPIENTRY
+_mesa_PatchParameteri_no_error(GLenum pname, GLint value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->TessCtrlProgram.patch_vertices = value;
+}
+
+
extern void GLAPIENTRY
_mesa_PatchParameteri(GLenum pname, GLint value)
{