_mesa_delete_pipeline_object(struct gl_context *ctx,
struct gl_pipeline_object *obj)
{
- unsinged i;
+ unsigned i;
_mesa_reference_shader_program(ctx, &obj->_CurrentFragmentProgram, NULL);
_mesa_reference_shader_program(ctx, &obj->CurrentProgram[i], NULL);
_mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
- _glthread_DESTROY_MUTEX(obj->Mutex);
+ mtx_destroy(&obj->Mutex);
ralloc_free(obj);
}
struct gl_pipeline_object *obj = rzalloc(NULL, struct gl_pipeline_object);
if (obj) {
obj->Name = name;
- _glthread_INIT_MUTEX(obj->Mutex);
+ mtx_init(&obj->Mutex, mtx_plain);
obj->RefCount = 1;
obj->Flags = _mesa_get_shader_flags();
}
GLboolean deleteFlag = GL_FALSE;
struct gl_pipeline_object *oldObj = *ptr;
- _glthread_LOCK_MUTEX(oldObj->Mutex);
+ mtx_lock(&oldObj->Mutex);
ASSERT(oldObj->RefCount > 0);
oldObj->RefCount--;
deleteFlag = (oldObj->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldObj->Mutex);
+ mtx_unlock(&oldObj->Mutex);
if (deleteFlag) {
_mesa_delete_pipeline_object(ctx, oldObj);
if (obj) {
/* reference new pipeline object */
- _glthread_LOCK_MUTEX(obj->Mutex);
+ mtx_lock(&obj->Mutex);
if (obj->RefCount == 0) {
/* this pipeline's being deleted (look just above) */
/* Not sure this can ever really happen. Warn if it does. */
obj->RefCount++;
*ptr = obj;
}
- _glthread_UNLOCK_MUTEX(obj->Mutex);
+ mtx_unlock(&obj->Mutex);
}
}
void GLAPIENTRY
_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg = NULL;
+ struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+ if (program != 0) {
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glActiveShaderProgram(program)");
+ if (shProg == NULL)
+ return;
+ }
+
+ if (!pipe) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveShaderProgram(pipeline)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ pipe->EverBound = GL_TRUE;
+
+ if ((shProg != NULL) && !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glActiveShaderProgram(program %u not linked)", shProg->Name);
+ return;
+ }
+
+ _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
}
/**
GLboolean GLAPIENTRY
_mesa_IsProgramPipeline(GLuint pipeline)
{
- return GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_pipeline_object *obj = lookup_pipeline_object(ctx, pipeline);
+ if (obj == NULL)
+ return GL_FALSE;
+
+ return obj->EverBound;
}
/**
void GLAPIENTRY
_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+ /* Are geometry shaders available in this context?
+ */
+ const bool has_gs = _mesa_has_geometry_shaders(ctx);
+
+ if (!pipe) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramPipelineiv(pipeline)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ pipe->EverBound = GL_TRUE;
+
+ switch (pname) {
+ case GL_ACTIVE_PROGRAM:
+ *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
+ return;
+ case GL_INFO_LOG_LENGTH:
+ /* FINISHME: Implement the info log.
+ */
+ *params = 0;
+ return;
+ case GL_VALIDATE_STATUS:
+ /* FINISHME: Implement validation status.
+ */
+ *params = 0;
+ return;
+ case GL_VERTEX_SHADER:
+ *params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
+ ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name : 0;
+ return;
+ case GL_TESS_EVALUATION_SHADER:
+ /* NOT YET SUPPORTED */
+ break;
+ case GL_TESS_CONTROL_SHADER:
+ /* NOT YET SUPPORTED */
+ break;
+ case GL_GEOMETRY_SHADER:
+ if (!has_gs)
+ break;
+ *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY]
+ ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name : 0;
+ return;
+ case GL_FRAGMENT_SHADER:
+ *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT]
+ ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name : 0;
+ return;
+ default:
+ break;
+ }
+
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
}
/**