transformfeedback.c revision 05b086ce934fa2967da736db8db429d0886735a9
1de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/* 2de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Mesa 3-D graphics library 3de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 4de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Copyright (C) 2010 VMware, Inc. All Rights Reserved. 5de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 6de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 7de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * copy of this software and associated documentation files (the "Software"), 8de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to deal in the Software without restriction, including without limitation 9de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 11de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Software is furnished to do so, subject to the following conditions: 12de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 13de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * The above copyright notice and this permission notice shall be included 14de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * in all copies or substantial portions of the Software. 15de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 16de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 23de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 24de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 25de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/* 26de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Vertex transform feedback support. 27de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 28de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Authors: 29de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Brian Paul 30de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 31de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 32de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 33de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul#include "buffers.h" 34de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul#include "bufferobj.h" 35de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul#include "context.h" 36fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul#include "hash.h" 37db61b9ce39bccc43140357652ceb78baaf2aea44Vinson Lee#include "mfeatures.h" 380117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h" 39de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul#include "transformfeedback.h" 40a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul#include "shaderapi.h" 41a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul#include "shaderobj.h" 42b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu#include "main/dispatch.h" 43de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 44ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h" 45de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 46de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 47b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu#if FEATURE_EXT_transform_feedback 48b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu 49b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu 50de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 51fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Do reference counting of transform feedback buffers. 52fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 53fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 54fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulreference_transform_feedback_object(struct gl_transform_feedback_object **ptr, 55fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 56fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 57fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (*ptr == obj) 58fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 59fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 60fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (*ptr) { 61fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* Unreference the old object */ 62fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *oldObj = *ptr; 63fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 64fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT(oldObj->RefCount > 0); 65fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul oldObj->RefCount--; 66fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 67fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (oldObj->RefCount == 0) { 68fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 69fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (ctx) 70fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.DeleteTransformFeedback(ctx, oldObj); 71fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 72fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 73fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul *ptr = NULL; 74fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 75fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT(!*ptr); 76fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 77fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 78fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* reference new object */ 79fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->RefCount == 0) { 80fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_problem(NULL, "referencing deleted transform feedback object"); 81fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul *ptr = NULL; 82fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 83fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else { 84fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->RefCount++; 85fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul *ptr = obj; 86fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 87fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 88fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 89fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 90fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 91fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 92de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Check that all the buffer objects currently bound for transform 93de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * feedback actually exist. Raise a GL_INVALID_OPERATION error if 94de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * any buffers are missing. 95de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * \return GL_TRUE for success, GL_FALSE if error 96de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 97de8530e1546733bf21b2e0518d6c5bda560770b9Brian PaulGLboolean 98f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_validate_transform_feedback_buffers(struct gl_context *ctx) 99de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 100fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* XXX to do */ 101de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return GL_TRUE; 102de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 103de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 104de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 105de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 106de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 107de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Per-context init for transform feedback. 108de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 109de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid 110f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_init_transform_feedback(struct gl_context *ctx) 111de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 11232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu /* core mesa expects this, even a dummy one, to be available */ 11332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ASSERT(ctx->Driver.NewTransformFeedback); 114fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 115fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.DefaultObject = 116fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.NewTransformFeedback(ctx, 0); 117fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 118fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->TransformFeedback.DefaultObject->RefCount == 1); 119fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 120fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject, 121fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.DefaultObject); 122fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 123fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->TransformFeedback.DefaultObject->RefCount == 2); 124fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 125fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.Objects = _mesa_NewHashTable(); 126fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 127de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 128de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 129de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul ctx->Shared->NullBufferObj); 130de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 131de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 132de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 133fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 134fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 135fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Callback for _mesa_HashDeleteAll(). 136fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 137fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 138fef6e36e0736a68e24d7844bae65a01de8359214Brian Pauldelete_cb(GLuint key, void *data, void *userData) 139fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 140f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 141fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 142fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul (struct gl_transform_feedback_object *) data; 143fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 144fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.DeleteTransformFeedback(ctx, obj); 145fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 146fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 147fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 148de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 149de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Per-context free/clean-up for transform feedback. 150de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 151de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid 152f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_free_transform_feedback(struct gl_context *ctx) 153de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 15432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu /* core mesa expects this, even a dummy one, to be available */ 15532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ASSERT(ctx->Driver.NewTransformFeedback); 156fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 157de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 158de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 159de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul NULL); 160fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 161fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* Delete all feedback objects */ 162fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashDeleteAll(ctx->TransformFeedback.Objects, delete_cb, ctx); 1635b90f83aee89d051983485cdec5b5db2f3659256Brian Paul _mesa_DeleteHashTable(ctx->TransformFeedback.Objects); 164fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 165fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* Delete the default feedback object */ 166fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.DeleteTransformFeedback); 16739c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul ctx->Driver.DeleteTransformFeedback(ctx, 16839c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul ctx->TransformFeedback.DefaultObject); 169fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 170fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject = NULL; 171de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 172de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 173de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 17432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#else /* FEATURE_EXT_transform_feedback */ 17532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 17632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu/* forward declarations */ 17732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wustatic struct gl_transform_feedback_object * 178f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnew_transform_feedback(struct gl_context *ctx, GLuint name); 17932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 18032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wustatic void 181f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdelete_transform_feedback(struct gl_context *ctx, 18232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu struct gl_transform_feedback_object *obj); 18332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 18432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu/* dummy per-context init/clean-up for transform feedback */ 18532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wuvoid 186f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_init_transform_feedback(struct gl_context *ctx) 18732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu{ 18832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.DefaultObject = new_transform_feedback(ctx, 0); 18932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.CurrentObject = ctx->TransformFeedback.DefaultObject; 19032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu _mesa_reference_buffer_object(ctx, 19132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu &ctx->TransformFeedback.CurrentBuffer, 19232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->Shared->NullBufferObj); 19332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu} 19432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 19532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wuvoid 196f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_free_transform_feedback(struct gl_context *ctx) 19732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu{ 19832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu _mesa_reference_buffer_object(ctx, 19932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu &ctx->TransformFeedback.CurrentBuffer, 20032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu NULL); 20132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.CurrentObject = NULL; 20232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu delete_transform_feedback(ctx, ctx->TransformFeedback.DefaultObject); 20332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu} 20432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 20532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#endif /* FEATURE_EXT_transform_feedback */ 20632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 20732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 208fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.NewTransformFeedback() */ 209fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic struct gl_transform_feedback_object * 210f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnew_transform_feedback(struct gl_context *ctx, GLuint name) 211fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 212fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 213fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = CALLOC_STRUCT(gl_transform_feedback_object); 214fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 215fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Name = name; 216fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->RefCount = 1; 217fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 218fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return obj; 219fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 220fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 221fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.DeleteTransformFeedback() */ 222fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 223f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdelete_transform_feedback(struct gl_context *ctx, 224fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 225fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 226fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLuint i; 227fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 228fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < Elements(obj->Buffers); i++) { 229fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL); 230fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 231fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 232fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul free(obj); 233fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 234fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 23532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 23632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#if FEATURE_EXT_transform_feedback 23732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 23832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 239fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.BeginTransformFeedback() */ 240fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 241f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergbegin_transform_feedback(struct gl_context *ctx, GLenum mode, 242fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 243fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 244fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 245fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 246fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 247fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.EndTransformFeedback() */ 248fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 249f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergend_transform_feedback(struct gl_context *ctx, 250fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 251fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 252fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 253fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 254fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 255fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.PauseTransformFeedback() */ 256fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 257f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergpause_transform_feedback(struct gl_context *ctx, 258fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 259fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 260fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 261fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 262fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 263fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.ResumeTransformFeedback() */ 264fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 265f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergresume_transform_feedback(struct gl_context *ctx, 266fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 267fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 268fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 269fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 270fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 271fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 272fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 273fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Plug in default device driver functions for transform feedback. 274fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Most drivers will override some/all of these. 275fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 276fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid 277fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_init_transform_feedback_functions(struct dd_function_table *driver) 278fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 279fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->NewTransformFeedback = new_transform_feedback; 280fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->DeleteTransformFeedback = delete_transform_feedback; 281fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->BeginTransformFeedback = begin_transform_feedback; 282fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->EndTransformFeedback = end_transform_feedback; 283fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->PauseTransformFeedback = pause_transform_feedback; 284fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->ResumeTransformFeedback = resume_transform_feedback; 285fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 286fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 287fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 288b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wuvoid 289b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu_mesa_init_transform_feedback_dispatch(struct _glapi_table *disp) 290b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu{ 29148dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák /* EXT_transform_feedback */ 292b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BeginTransformFeedbackEXT(disp, _mesa_BeginTransformFeedback); 293b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_EndTransformFeedbackEXT(disp, _mesa_EndTransformFeedback); 294b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferRangeEXT(disp, _mesa_BindBufferRange); 295b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferBaseEXT(disp, _mesa_BindBufferBase); 296b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferOffsetEXT(disp, _mesa_BindBufferOffsetEXT); 297b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_TransformFeedbackVaryingsEXT(disp, _mesa_TransformFeedbackVaryings); 298b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_GetTransformFeedbackVaryingEXT(disp, _mesa_GetTransformFeedbackVarying); 29948dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák /* ARB_transform_feedback2 */ 30048dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_BindTransformFeedback(disp, _mesa_BindTransformFeedback); 30148dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_DeleteTransformFeedbacks(disp, _mesa_DeleteTransformFeedbacks); 30248dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_GenTransformFeedbacks(disp, _mesa_GenTransformFeedbacks); 30348dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback); 30448dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback); 30548dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback); 306b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu} 307b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu 308fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 309fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 310fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ** Begin API functions 311fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul **/ 312fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 313fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 314de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 315de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BeginTransformFeedback(GLenum mode) 316de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 317fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 318ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry struct gl_transform_feedback_info *info; 319ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry int i; 320de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 321de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 322fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 32386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 32486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (ctx->Shader.CurrentVertexProgram == NULL) { 32586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 32686bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBeginTransformFeedback(no program active)"); 32786bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 32886bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 32986bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 330ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry info = &ctx->Shader.CurrentVertexProgram->LinkedTransformFeedback; 331fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 33286bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (info->NumOutputs == 0) { 33386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 33486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBeginTransformFeedback(no varyings to record)"); 33586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 33686bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 33786bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 338de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (mode) { 339de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_POINTS: 340de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINES: 341de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_TRIANGLES: 342de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* legal */ 343de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 344de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 345de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBeginTransformFeedback(mode)"); 346de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 347de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 348de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 349fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 350de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 351de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBeginTransformFeedback(already active)"); 352de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 353de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 354de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 355ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry for (i = 0; i < info->NumBuffers; ++i) { 356ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry if (obj->BufferNames[i] == 0) { 357ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 358ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry "glBeginTransformFeedback(binding point %d does not have " 359ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry "a buffer object bound)", i); 360ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry return; 361ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry } 362ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry } 363ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry 364a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 365fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Active = GL_TRUE; 366de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul ctx->TransformFeedback.Mode = mode; 367fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 368fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.BeginTransformFeedback); 369fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.BeginTransformFeedback(ctx, mode, obj); 370de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 371de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 372de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 373de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 374de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_EndTransformFeedback(void) 375de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 376fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 377de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 378de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 379fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 380fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 381fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active) { 382de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 383de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glEndTransformFeedback(not active)"); 384de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 385de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 386de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 387a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 388fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; 38908ce48733d9441e1daa779027dbea1ce9964cc77Paul Berry ctx->TransformFeedback.CurrentObject->Paused = GL_FALSE; 39014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE; 391fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 392fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.EndTransformFeedback); 393fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.EndTransformFeedback(ctx, obj); 394de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 395de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 396de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 397de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 398de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Helper used by BindBufferRange() and BindBufferBase(). 399de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 400de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulstatic void 401f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergbind_buffer_range(struct gl_context *ctx, GLuint index, 402de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj, 403de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset, GLsizeiptr size) 404de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 405fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 406fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject; 407291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry 408291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry /* Note: no need to FLUSH_VERTICES or flag _NEW_TRANSFORM_FEEDBACK, because 409291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry * transform feedback buffers can't be changed while transform feedback is 410291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry * active. 411291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry */ 412fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 413de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The general binding point */ 414de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 415de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 416de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 417de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 418de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The per-attribute binding point */ 419de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 420fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul &obj->Buffers[index], 421de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 422de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 423fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->BufferNames[index] = bufObj->Name; 424de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 425fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Offset[index] = offset; 426fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Size[index] = size; 427de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 428de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 429de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 430de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 431de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. Plus, 432de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * specify the starting offset to place the results, and max size. 433de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 434de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 435de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferRange(GLenum target, GLuint index, 436de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLuint buffer, GLintptr offset, GLsizeiptr size) 437de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 438fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 439de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 440de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 441de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 442de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 443de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)"); 444de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 445de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 446de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 447fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 448fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 449fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 450de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 451de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferRange(transform feedback active)"); 452de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 453de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 454de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 455de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 456de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); 457de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 458de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 459de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 460de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if ((size <= 0) || (size & 0x3)) { 461de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* must be positive and multiple of four */ 4621979e22e13dd28553bcc67cc51e56684e6ee4768Paul Berry _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size); 463de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 464de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 465de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 466de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (offset & 0x3) { 467de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* must be multiple of four */ 468de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 4699eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul "glBindBufferRange(offset=%d)", (int) offset); 470de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 471de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 472de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 47305b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke if (buffer == 0) { 47405b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = ctx->Shared->NullBufferObj; 47505b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } else { 47605b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = _mesa_lookup_bufferobj(ctx, buffer); 47705b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } 47805b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke 479de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 480de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 481de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferRange(invalid buffer=%u)", buffer); 482de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 483de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 484de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 48538b118d49ddbc8bd5d96cc0d23d681887fca045ePaul Berry if (offset + size > bufObj->Size) { 486de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 48786af037e6a1643284f87c5e01c3fcb09dd07bf35Eric Anholt "glBindBufferRange(offset + size %d > buffer size %d)", 4889eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul (int) (offset + size), (int) (bufObj->Size)); 489de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 490de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 491de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 492de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 493de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 494de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 495de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 496de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 497de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. 498de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * As above, but start at offset = 0. 499de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 500de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 501de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) 502de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 503fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 504de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 505de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 506fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 507de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 508de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 509de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)"); 510de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 511de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 512de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 513fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 514fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 515fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 516de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 5172be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferBase(transform feedback active)"); 518de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 519de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 520de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 521de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 522de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); 523de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 524de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 525de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 52605b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke if (buffer == 0) { 52705b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = ctx->Shared->NullBufferObj; 52805b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } else { 52905b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = _mesa_lookup_bufferobj(ctx, buffer); 53005b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } 53105b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke 532de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 533de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 534de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferBase(invalid buffer=%u)", buffer); 535de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 536de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 537de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 538de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 539de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 540de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 541de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = bufObj->Size & ~0x3; 542de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 543de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, 0, size); 544de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 545de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 546de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 547de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 548de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results, plus the 549de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * offset in the buffer to start placing results. 550de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function is part of GL_EXT_transform_feedback, but not GL3. 551de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 552de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 553de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, 554de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset) 555de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 556fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 557de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 558de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 559de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 560de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 561de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 562de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferOffsetEXT(target)"); 563de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 564de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 565de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 566fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 567fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 568fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 569de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 5702be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferOffsetEXT(transform feedback active)"); 571de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 572de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 573de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 574de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 575de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 576de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(index=%d)", index); 577de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 578de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 579de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 58086bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (offset & 0x3) { 58186bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry /* must be multiple of four */ 58286bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_VALUE, 58386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBindBufferOffsetEXT(offset=%d)", (int) offset); 58486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 58586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 58686bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 58705b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke if (buffer == 0) { 58805b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = ctx->Shared->NullBufferObj; 58905b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } else { 59005b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = _mesa_lookup_bufferobj(ctx, buffer); 59105b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } 59205b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke 593de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 594de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 595de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(invalid buffer=%u)", buffer); 596de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 597de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 598de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 599de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 600de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 601de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 602de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = (bufObj->Size - offset) & ~0x3; 603de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 604de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 605de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 606de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 607de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 608de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 609de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function specifies the vertex shader outputs to be written 610de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s), and in what order. 611de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 612de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 613de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_TransformFeedbackVaryings(GLuint program, GLsizei count, 614de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const GLchar **varyings, GLenum bufferMode) 615de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 616de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_shader_program *shProg; 617de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLuint i; 618de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 619de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 620de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (bufferMode) { 621de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_INTERLEAVED_ATTRIBS: 622de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 623de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_SEPARATE_ATTRIBS: 624de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 625de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 626de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, 627de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(bufferMode)"); 628de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 629de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 630de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 631f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák if (count < 0 || 632f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák (bufferMode == GL_SEPARATE_ATTRIBS && 633c67d9cfd9d5d04b5b32170616f75b34e0192304bBrian Paul (GLuint) count > ctx->Const.MaxTransformFeedbackSeparateAttribs)) { 634de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 635de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(count=%d)", count); 636de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 637de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 638de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 639de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 640de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 641de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 642de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(program=%u)", program); 643de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 644de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 645de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 646de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* free existing varyings, if any */ 647de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 648de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames[i]); 649de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 650de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames); 651de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 652de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* allocate new memory for varying names */ 653de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames = 654de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul (GLchar **) malloc(count * sizeof(GLchar *)); 655de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 656de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg->TransformFeedback.VaryingNames) { 657de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTransformFeedbackVaryings()"); 658de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 659de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 660de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 661de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* Save the new names and the count */ 662de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < (GLuint) count; i++) { 663de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames[i] = _mesa_strdup(varyings[i]); 664de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 665de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.NumVarying = count; 666de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 667de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.BufferMode = bufferMode; 668de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 669a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry /* No need to set _NEW_TRANSFORM_FEEDBACK (or invoke FLUSH_VERTICES) since 670a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry * the varyings won't be used until shader link time. 671a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry */ 672de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 673de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 674de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 675de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 676de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Get info about the vertex shader's outputs which are to be written 677de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s). 678de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 679de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 680de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, 681de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei bufSize, GLsizei *length, 682de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei *size, GLenum *type, GLchar *name) 683de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 684de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const struct gl_shader_program *shProg; 6859d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt const struct gl_transform_feedback_info *linked_xfb_info; 686de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 687de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 688de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 689de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 690de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 691de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(program=%u)", program); 692de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 693de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 694de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 6959d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt linked_xfb_info = &shProg->LinkedTransformFeedback; 6969d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (index >= linked_xfb_info->NumVarying) { 697de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 698de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(index=%u)", index); 699de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 700de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 701de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 7029d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt /* return the varying's name and length */ 7039d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt _mesa_copy_string(name, bufSize, length, 7049d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt linked_xfb_info->Varyings[index].Name); 705de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 7069d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt /* return the datatype and value's size (in datatype units) */ 7079d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (type) 7089d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt *type = linked_xfb_info->Varyings[index].Type; 7099d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (size) 7109d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt *size = linked_xfb_info->Varyings[index].Size; 711de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 712de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 713fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 714fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 71514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstruct gl_transform_feedback_object * 71614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) 717fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 718fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (name == 0) { 719fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return ctx->TransformFeedback.DefaultObject; 720fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 721fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 722fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return (struct gl_transform_feedback_object *) 723fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashLookup(ctx->TransformFeedback.Objects, name); 724fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 725fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 726fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 727fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 728fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Create new transform feedback objects. Transform feedback objects 729fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * encapsulate the state related to transform feedback to allow quickly 730fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * switching state (and drawing the results, below). 731fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 732fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 733fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 734fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) 735fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 736fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLuint first; 737fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 738fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 739fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 740fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 741fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 742fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)"); 743fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 744fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 745fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 746fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 747fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 748fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 749fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* we don't need contiguous IDs, but this might be faster */ 750fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul first = _mesa_HashFindFreeKeyBlock(ctx->TransformFeedback.Objects, n); 751fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (first) { 752fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLsizei i; 753fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 754fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 755fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul = ctx->Driver.NewTransformFeedback(ctx, first + i); 756fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 757fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 758fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 759fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 760fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i] = first + i; 761fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj); 762fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 763fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 764fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else { 765fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 766fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 767fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 768fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 769fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 770fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 771fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Is the given ID a transform feedback object? 772fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 773fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 774fef6e36e0736a68e24d7844bae65a01de8359214Brian PaulGLboolean GLAPIENTRY 775fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_IsTransformFeedback(GLuint name) 776fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 777fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 778fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 779fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 780fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 78114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák if (name && _mesa_lookup_transform_feedback_object(ctx, name)) 782fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_TRUE; 783fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 784fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_FALSE; 785fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 786fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 787fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 788fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 789fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Bind the given transform feedback object. 790fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 791fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 792fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 793d74f525060f779cfe449c20853b11ba2bbcdea6dVinson Lee_mesa_BindTransformFeedback(GLenum target, GLuint name) 794fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 795fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 796fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 797fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 798fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (target != GL_TRANSFORM_FEEDBACK) { 799fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindTransformFeedback(target)"); 800fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 801fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 802fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 803fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (ctx->TransformFeedback.CurrentObject->Active && 804fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul !ctx->TransformFeedback.CurrentObject->Paused) { 805fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 80639c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul "glBindTransformFeedback(transform is active, or not paused)"); 807fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 808fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 809fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 81014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák obj = _mesa_lookup_transform_feedback_object(ctx, name); 811fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 812fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 813fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glBindTransformFeedback(name=%u)", name); 814fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 815fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 816fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 817fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject, 818fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj); 819fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 820fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 821fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 822fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 823fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Delete the given transform feedback objects. 824fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 825fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 826fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 827fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names) 828fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 829fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLint i; 830fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 831fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 832fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 833fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 834fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 835fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTransformFeedbacks(n < 0)"); 836fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 837fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 838fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 839fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 840fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 841fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 842fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 843fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (names[i] > 0) { 844fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 84514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák = _mesa_lookup_transform_feedback_object(ctx, names[i]); 846fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 847fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 848fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 849fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glDeleteTransformFeedbacks(object %u is active)", 850fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i]); 851fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 852fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 853fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]); 854fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* unref, but object may not be deleted until later */ 855fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&obj, NULL); 856fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 857fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 858fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 859fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 860fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 861fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 862fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 863fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Pause transform feedback. 864fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 865fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 866fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 867fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_PauseTransformFeedback(void) 868fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 869fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 870fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 871fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 872fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 873fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 874fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || obj->Paused) { 875fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 876fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glPauseTransformFeedback(feedback not active or already paused)"); 877fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 878fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 879fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 880a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 881fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_TRUE; 882fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 883fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.PauseTransformFeedback); 884fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.PauseTransformFeedback(ctx, obj); 885fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 886fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 887fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 888fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 889fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Resume transform feedback. 890fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 891fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 892fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 893fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_ResumeTransformFeedback(void) 894fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 895fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 896fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 897fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 898fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 899fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 900fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || !obj->Paused) { 901fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 902076bd11112742ca615880f2c6dc6ed235ab37eb5Brian Paul "glResumeTransformFeedback(feedback not active or not paused)"); 903fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 904fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 905fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 906a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 907fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_FALSE; 908fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 909fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.ResumeTransformFeedback); 910fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.ResumeTransformFeedback(ctx, obj); 911fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 912fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 913b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu#endif /* FEATURE_EXT_transform_feedback */ 914