flags |= GLSL_DUMP;
if (strstr(env, "log"))
flags |= GLSL_LOG;
+ if (strstr(env, "cache_fb"))
+ flags |= GLSL_CACHE_FALLBACK;
if (strstr(env, "cache_info"))
flags |= GLSL_CACHE_INFO;
if (strstr(env, "nopvert"))
* Attach shader to a shader program.
*/
static void
-attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
+attach_shader(struct gl_context *ctx, struct gl_shader_program *shProg,
+ struct gl_shader *sh)
+{
+ GLuint n = shProg->NumShaders;
+
+ shProg->Shaders = realloc(shProg->Shaders,
+ (n + 1) * sizeof(struct gl_shader *));
+ if (!shProg->Shaders) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
+ return;
+ }
+
+ /* append */
+ shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
+ _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
+ shProg->NumShaders++;
+}
+
+static void
+attach_shader_err(struct gl_context *ctx, GLuint program, GLuint shader,
+ const char *caller)
{
struct gl_shader_program *shProg;
struct gl_shader *sh;
const bool same_type_disallowed = _mesa_is_gles(ctx);
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
+ shProg = _mesa_lookup_shader_program_err(ctx, program, caller);
if (!shProg)
return;
- sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
+ sh = _mesa_lookup_shader_err(ctx, shader, caller);
if (!sh) {
return;
}
* "The error INVALID_OPERATION is generated by AttachObjectARB
* if <obj> is already attached to <containerObj>."
*/
- _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
+ _mesa_error(ctx, GL_INVALID_OPERATION, caller);
return;
} else if (same_type_disallowed &&
shProg->Shaders[i]->Stage == sh->Stage) {
* is generated if [...] another shader object of the same type
* as shader is already attached to program."
*/
- _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
+ _mesa_error(ctx, GL_INVALID_OPERATION, caller);
return;
}
}
- /* grow list */
- shProg->Shaders = realloc(shProg->Shaders,
- (n + 1) * sizeof(struct gl_shader *));
- if (!shProg->Shaders) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
- return;
- }
-
- /* append */
- shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
- _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
- shProg->NumShaders++;
+ attach_shader(ctx, shProg, sh);
}
+static void
+attach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader)
+{
+ struct gl_shader_program *shProg;
+ struct gl_shader *sh;
+
+ shProg = _mesa_lookup_shader_program(ctx, program);
+ sh = _mesa_lookup_shader(ctx, shader);
+
+ attach_shader(ctx, shProg, sh);
+}
static GLuint
create_shader(struct gl_context *ctx, GLenum type)
struct gl_shader *sh;
GLuint name;
- if (!_mesa_validate_shader_target(ctx, type)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(%s)",
- _mesa_enum_to_string(type));
- return 0;
- }
-
_mesa_HashLockMutex(ctx->Shared->ShaderObjects);
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type));
}
+static GLuint
+create_shader_err(struct gl_context *ctx, GLenum type, const char *caller)
+{
+ if (!_mesa_validate_shader_target(ctx, type)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s)",
+ caller, _mesa_enum_to_string(type));
+ return 0;
+ }
+
+ return create_shader(ctx, type);
+}
+
+
static GLuint
create_shader_program(struct gl_context *ctx)
{
}
+void GLAPIENTRY
+_mesa_AttachObjectARB_no_error(GLhandleARB program, GLhandleARB shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ attach_shader_no_error(ctx, program, shader);
+}
+
void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
- attach_shader(ctx, program, shader);
+ attach_shader_err(ctx, program, shader, "glAttachObjectARB");
+}
+
+
+void GLAPIENTRY
+_mesa_AttachShader_no_error(GLuint program, GLuint shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ attach_shader_no_error(ctx, program, shader);
}
_mesa_AttachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
- attach_shader(ctx, program, shader);
+ attach_shader_err(ctx, program, shader, "glAttachShader");
}
}
+GLuint GLAPIENTRY
+_mesa_CreateShader_no_error(GLenum type)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return create_shader(ctx, type);
+}
+
+
GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
+
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
+
+ return create_shader_err(ctx, type, "glCreateShader");
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB_no_error(GLenum type)
+{
+ GET_CURRENT_CONTEXT(ctx);
return create_shader(ctx, type);
}
_mesa_CreateShaderObjectARB(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
- return create_shader(ctx, type);
+ return create_shader_err(ctx, type, "glCreateShaderObjectARB");
}
}
-void GLAPIENTRY
-_mesa_UseProgram(GLuint program)
+static ALWAYS_INLINE void
+use_program(GLuint program, bool no_error)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg = NULL;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glUseProgram %u\n", program);
- if (_mesa_is_xfb_active_and_unpaused(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseProgram(transform feedback active)");
- return;
- }
-
- if (program) {
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
- if (!shProg) {
- return;
+ if (no_error) {
+ if (program) {
+ shProg = _mesa_lookup_shader_program(ctx, program);
}
- if (!shProg->data->LinkStatus) {
+ } else {
+ if (_mesa_is_xfb_active_and_unpaused(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseProgram(program %u not linked)", program);
+ "glUseProgram(transform feedback active)");
return;
}
- /* debug code */
- if (ctx->_Shader->Flags & GLSL_USE_PROG) {
- print_shader_info(shProg);
+ if (program) {
+ shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+ if (!shProg)
+ return;
+
+ if (!shProg->data->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUseProgram(program %u not linked)", program);
+ return;
+ }
+
+ /* debug code */
+ if (ctx->_Shader->Flags & GLSL_USE_PROG) {
+ print_shader_info(shProg);
+ }
}
}
* object (section 2.14.PPO), the program bound to the appropriate
* stage of the pipeline object is considered current."
*/
- if (program) {
+ if (shProg) {
/* Attach shader state to the binding point */
_mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
/* Update the program */
/* Must be done first: detach the progam */
_mesa_use_shader_program(ctx, shProg);
/* Unattach shader_state binding point */
- _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
+ _mesa_reference_pipeline_object(ctx, &ctx->_Shader,
+ ctx->Pipeline.Default);
/* If a pipeline was bound, rebind it */
if (ctx->Pipeline.Current) {
- _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
+ if (no_error)
+ _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name);
+ else
+ _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
}
}
}
+void GLAPIENTRY
+_mesa_UseProgram_no_error(GLuint program)
+{
+ use_program(program, true);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgram(GLuint program)
+{
+ use_program(program, false);
+}
+
+
void GLAPIENTRY
_mesa_ValidateProgram(GLuint program)
{
{
GET_CURRENT_CONTEXT(ctx);
- const GLuint shader = create_shader(ctx, type);
+ const GLuint shader = create_shader_err(ctx, type, "glCreateShaderProgramv");
GLuint program = 0;
/*
get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
if (compiled) {
- attach_shader(ctx, program, shader);
+ attach_shader_err(ctx, program, shader, "glCreateShaderProgramv");
_mesa_link_program(ctx, shProg);
detach_shader(ctx, program, shader);
GLenum resource_type;
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return -1;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return -1;
GLenum resource_type;
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return -1;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return -1;
GLenum resource_type;
int count, i, j;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;
GLenum resource_type;
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;
GLenum resource_type;
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;
gl_shader_stage stage;
int i;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;
}
i = 0;
+ bool flushed = false;
do {
struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
if (uni == NULL) {
continue;
}
+ if (!flushed) {
+ _mesa_flush_vertices_for_uniforms(ctx, uni);
+ flushed = true;
+ }
+
int uni_count = uni->array_elements ? uni->array_elements : 1;
int j, k, f;
}
i += uni_count;
} while(i < count);
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
}
const char *api_name = "glGetUniformSubroutineuiv";
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;
struct gl_linked_shader *sh;
gl_shader_stage stage;
- if (!_mesa_has_ARB_shader_subroutine(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
- return;
- }
-
if (!_mesa_validate_shader_target(ctx, shadertype)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return;