mesa: Allow GL_DEPTH_COMPONENT and GL_DEPTH_STENCIL combinations in glTexImage{123}D()
[mesa.git] / src / mesa / main / pipelineobj.c
index 9f1cefc883c14720c8da119b662884e977350742..27012df7273749fcb6dc96ff9006a559f407756b 100644 (file)
@@ -56,7 +56,7 @@ void
 _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);
 
@@ -64,7 +64,7 @@ _mesa_delete_pipeline_object(struct gl_context *ctx,
       _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);
 }
 
@@ -77,7 +77,7 @@ _mesa_new_pipeline_object(struct gl_context *ctx, GLuint name)
    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();
    }
@@ -177,11 +177,11 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx,
       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);
@@ -193,7 +193,7 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx,
 
    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. */
@@ -204,7 +204,7 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx,
          obj->RefCount++;
          *ptr = obj;
       }
-      _glthread_UNLOCK_MUTEX(obj->Mutex);
+      mtx_unlock(&obj->Mutex);
    }
 }
 
@@ -223,6 +223,34 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
 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);
 }
 
 /**
@@ -327,7 +355,13 @@ _mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines)
 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;
 }
 
 /**
@@ -336,6 +370,64 @@ _mesa_IsProgramPipeline(GLuint pipeline)
 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));
 }
 
 /**