st/mesa/glsl/nir/i965: make use of new gl_shader_program_data in gl_shader_program
[mesa.git] / src / mesa / main / transformfeedback.c
index 0900d411b91b8dc53c5036f7e04fd956c606576e..738d63eee37ab894fa64edf08bd2710a824b4005 100644 (file)
@@ -347,23 +347,25 @@ compute_transform_feedback_buffer_sizes(
  * enabled transform feedback buffers without overflowing any of them.
  */
 unsigned
-_mesa_compute_max_transform_feedback_vertices(
+_mesa_compute_max_transform_feedback_vertices(struct gl_context *ctx,
       const struct gl_transform_feedback_object *obj,
       const struct gl_transform_feedback_info *info)
 {
    unsigned max_index = 0xffffffff;
    unsigned i;
 
-   for (i = 0; i < info->NumBuffers; ++i) {
-      unsigned stride = info->BufferStride[i];
-      unsigned max_for_this_buffer;
+   for (i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
+      if ((info->ActiveBuffers >> i) & 1) {
+         unsigned stride = info->Buffers[i].Stride;
+         unsigned max_for_this_buffer;
 
-      /* Skip any inactive buffers, which have a stride of 0. */
-      if (stride == 0)
-        continue;
+         /* Skip any inactive buffers, which have a stride of 0. */
+         if (stride == 0)
+           continue;
 
-      max_for_this_buffer = obj->Size[i] / (4 * stride);
-      max_index = MIN2(max_index, max_for_this_buffer);
+         max_for_this_buffer = obj->Size[i] / (4 * stride);
+         max_index = MIN2(max_index, max_for_this_buffer);
+      }
    }
 
    return max_index;
@@ -445,12 +447,14 @@ _mesa_BeginTransformFeedback(GLenum mode)
       return;
    }
 
-   for (i = 0; i < info->NumBuffers; ++i) {
-      if (obj->BufferNames[i] == 0) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBeginTransformFeedback(binding point %d does not have "
-                     "a buffer object bound)", i);
-         return;
+   for (i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
+      if ((info->ActiveBuffers >> i) & 1) {
+         if (obj->BufferNames[i] == 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glBeginTransformFeedback(binding point %d does not "
+                        "have a buffer object bound)", i);
+            return;
+         }
       }
    }
 
@@ -470,7 +474,7 @@ _mesa_BeginTransformFeedback(GLenum mode)
        * feedback.
        */
       unsigned max_vertices
-         = _mesa_compute_max_transform_feedback_vertices(obj, info);
+         = _mesa_compute_max_transform_feedback_vertices(ctx, obj, info);
       obj->GlesRemainingPrims = max_vertices / vertices_per_prim;
    }
 
@@ -501,12 +505,12 @@ _mesa_EndTransformFeedback(void)
    FLUSH_VERTICES(ctx, 0);
    ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback;
 
+   assert(ctx->Driver.EndTransformFeedback);
+   ctx->Driver.EndTransformFeedback(ctx, obj);
+
    ctx->TransformFeedback.CurrentObject->Active = GL_FALSE;
    ctx->TransformFeedback.CurrentObject->Paused = GL_FALSE;
    ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;
-
-   assert(ctx->Driver.EndTransformFeedback);
-   ctx->Driver.EndTransformFeedback(ctx, obj);
 }
 
 
@@ -842,12 +846,10 @@ _mesa_TransformFeedbackVaryings(GLuint program, GLsizei count,
       return;
    }
 
-   shProg = _mesa_lookup_shader_program(ctx, program);
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glTransformFeedbackVaryings(program=%u)", program);
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glTransformFeedbackVaryings");
+   if (!shProg)
       return;
-   }
 
    if (ctx->Extensions.ARB_transform_feedback3) {
       if (bufferMode == GL_INTERLEAVED_ATTRIBS) {
@@ -861,7 +863,7 @@ _mesa_TransformFeedbackVaryings(GLuint program, GLsizei count,
          if (buffers > ctx->Const.MaxTransformFeedbackBuffers) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "glTransformFeedbackVaryings(too many gl_NextBuffer "
-                        "occurences)");
+                        "occurrences)");
             return;
          }
       } else {
@@ -920,32 +922,35 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
                                   GLsizei *size, GLenum *type, GLchar *name)
 {
    const struct gl_shader_program *shProg;
-   const struct gl_transform_feedback_info *linked_xfb_info;
+   struct gl_program_resource *res;
    GET_CURRENT_CONTEXT(ctx);
 
-   shProg = _mesa_lookup_shader_program(ctx, program);
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glGetTransformFeedbackVarying(program=%u)", program);
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glGetTransformFeedbackVarying");
+   if (!shProg)
       return;
-   }
 
-   linked_xfb_info = &shProg->LinkedTransformFeedback;
-   if (index >= (GLuint) linked_xfb_info->NumVarying) {
+   res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
+                                           GL_TRANSFORM_FEEDBACK_VARYING,
+                                           index);
+   if (!res) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glGetTransformFeedbackVarying(index=%u)", index);
       return;
    }
 
    /* return the varying's name and length */
-   _mesa_copy_string(name, bufSize, length,
-                    linked_xfb_info->Varyings[index].Name);
+   _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
 
    /* return the datatype and value's size (in datatype units) */
    if (type)
-      *type = linked_xfb_info->Varyings[index].Type;
+      _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+                                  res, index, GL_TYPE, (GLint*) type,
+                                  "glGetTransformFeedbackVarying");
    if (size)
-      *size = linked_xfb_info->Varyings[index].Size;
+      _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+                                  res, index, GL_ARRAY_SIZE, (GLint*) size,
+                                  "glGetTransformFeedbackVarying");
 }
 
 
@@ -1131,6 +1136,11 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)
             }
             _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]);
             /* unref, but object may not be deleted until later */
+            if (obj == ctx->TransformFeedback.CurrentObject) {
+               reference_transform_feedback_object(
+                     &ctx->TransformFeedback.CurrentObject,
+                     ctx->TransformFeedback.DefaultObject);
+            }
             reference_transform_feedback_object(&obj, NULL);
          }
       }
@@ -1159,10 +1169,10 @@ _mesa_PauseTransformFeedback(void)
    FLUSH_VERTICES(ctx, 0);
    ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback;
 
-   obj->Paused = GL_TRUE;
-
    assert(ctx->Driver.PauseTransformFeedback);
    ctx->Driver.PauseTransformFeedback(ctx, obj);
+
+   obj->Paused = GL_TRUE;
 }
 
 
@@ -1228,3 +1238,65 @@ _mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
                    "glGetTransformFeedbackiv(pname=%i)", pname);
     }
 }
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index,
+                              GLint *param)
+{
+   struct gl_transform_feedback_object *obj;
+   GET_CURRENT_CONTEXT(ctx);
+
+   obj = lookup_transform_feedback_object_err(ctx, xfb,
+                                              "glGetTransformFeedbacki_v");
+   if(!obj) {
+      return;
+   }
+
+   if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetTransformFeedbacki_v(index=%i)", index);
+      return;
+   }
+
+   switch(pname) {
+   case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+      *param = obj->BufferNames[index];
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetTransformFeedbacki_v(pname=%i)", pname);
+   }
+}
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index,
+                                GLint64 *param)
+{
+   struct gl_transform_feedback_object *obj;
+   GET_CURRENT_CONTEXT(ctx);
+
+   obj = lookup_transform_feedback_object_err(ctx, xfb,
+                                              "glGetTransformFeedbacki64_v");
+   if(!obj) {
+      return;
+   }
+
+   if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetTransformFeedbacki64_v(index=%i)", index);
+      return;
+   }
+
+   compute_transform_feedback_buffer_sizes(obj);
+   switch(pname) {
+   case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+      *param = obj->Offset[index];
+      break;
+   case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+      *param = obj->Size[index];
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetTransformFeedbacki64_v(pname=%i)", pname);
+   }
+}