* 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;
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;
+ }
}
}
* 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;
}
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);
}
if (buffers > ctx->Const.MaxTransformFeedbackBuffers) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTransformFeedbackVaryings(too many gl_NextBuffer "
- "occurences)");
+ "occurrences)");
return;
}
} else {
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);
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");
}
}
_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);
}
}
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;
}
assert(ctx->Driver.ResumeTransformFeedback);
ctx->Driver.ResumeTransformFeedback(ctx, obj);
}
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
+{
+ struct gl_transform_feedback_object *obj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glGetTransformFeedbackiv");
+ if(!obj) {
+ return;
+ }
+
+ switch(pname) {
+ case GL_TRANSFORM_FEEDBACK_PAUSED:
+ *param = obj->Paused;
+ break;
+ case GL_TRANSFORM_FEEDBACK_ACTIVE:
+ *param = obj->Active;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "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);
+ }
+}