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_BindBufferOffsetEXT(disp, _mesa_BindBufferOffsetEXT); 295b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_TransformFeedbackVaryingsEXT(disp, _mesa_TransformFeedbackVaryings); 296b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_GetTransformFeedbackVaryingEXT(disp, _mesa_GetTransformFeedbackVarying); 29748dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák /* ARB_transform_feedback2 */ 29848dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_BindTransformFeedback(disp, _mesa_BindTransformFeedback); 29948dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_DeleteTransformFeedbacks(disp, _mesa_DeleteTransformFeedbacks); 30048dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_GenTransformFeedbacks(disp, _mesa_GenTransformFeedbacks); 30148dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback); 30248dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback); 30348dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback); 304b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu} 305b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu 306fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 307fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 308fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ** Begin API functions 309fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul **/ 310fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 311fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 312de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 313de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BeginTransformFeedback(GLenum mode) 314de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 315fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 316ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry struct gl_transform_feedback_info *info; 317ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry int i; 318de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 319de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 320fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 32186bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 32286bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (ctx->Shader.CurrentVertexProgram == NULL) { 32386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 32486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBeginTransformFeedback(no program active)"); 32586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 32686bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 32786bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 328ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry info = &ctx->Shader.CurrentVertexProgram->LinkedTransformFeedback; 329fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 33086bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (info->NumOutputs == 0) { 33186bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 33286bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBeginTransformFeedback(no varyings to record)"); 33386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 33486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 33586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 336de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (mode) { 337de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_POINTS: 338de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINES: 339de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_TRIANGLES: 340de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* legal */ 341de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 342de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 343de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBeginTransformFeedback(mode)"); 344de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 345de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 346de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 347fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 348de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 349de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBeginTransformFeedback(already active)"); 350de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 351de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 352de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 353ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry for (i = 0; i < info->NumBuffers; ++i) { 354ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry if (obj->BufferNames[i] == 0) { 355ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry _mesa_error(ctx, GL_INVALID_OPERATION, 356ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry "glBeginTransformFeedback(binding point %d does not have " 357ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry "a buffer object bound)", i); 358ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry return; 359ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry } 360ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry } 361ebfad9f6a125738b9bfc5d5f7d09a8b57856674aPaul Berry 362a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 363fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Active = GL_TRUE; 364de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul ctx->TransformFeedback.Mode = mode; 365fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 366fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.BeginTransformFeedback); 367fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.BeginTransformFeedback(ctx, mode, obj); 368de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 369de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 370de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 371de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 372de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_EndTransformFeedback(void) 373de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 374fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 375de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 376de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 377fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 378fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 379fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active) { 380de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 381de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glEndTransformFeedback(not active)"); 382de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 383de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 384de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 385a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 386fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; 38708ce48733d9441e1daa779027dbea1ce9964cc77Paul Berry ctx->TransformFeedback.CurrentObject->Paused = GL_FALSE; 38814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE; 389fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 390fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.EndTransformFeedback); 391fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.EndTransformFeedback(ctx, obj); 392de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 393de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 394de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 395de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 396de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Helper used by BindBufferRange() and BindBufferBase(). 397de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 398de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulstatic void 399f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergbind_buffer_range(struct gl_context *ctx, GLuint index, 400de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj, 401de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset, GLsizeiptr size) 402de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 403fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 404fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject; 405291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry 406291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry /* Note: no need to FLUSH_VERTICES or flag _NEW_TRANSFORM_FEEDBACK, because 407291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry * transform feedback buffers can't be changed while transform feedback is 408291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry * active. 409291ae4e6396872679fef72ed4fdd46fb7f945c3dPaul Berry */ 410fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 411de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The general binding point */ 412de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 413de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 414de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 415de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 416de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The per-attribute binding point */ 417de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 418fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul &obj->Buffers[index], 419de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 420de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 421fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->BufferNames[index] = bufObj->Name; 422de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 423fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Offset[index] = offset; 424fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Size[index] = size; 425de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 426de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 427de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 428de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 429de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. Plus, 430de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * specify the starting offset to place the results, and max size. 431d988ea5e810868244eb1a1e7ede32295c9ed9ad4Brian Paul * Called from the glBindBufferRange() function. 432de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 433b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholtvoid 434b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx, 435b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt GLuint index, 436b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt struct gl_buffer_object *bufObj, 437b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt GLintptr offset, 438b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt GLsizeiptr size) 439de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 440fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 441de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 442fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 443fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 444fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 445de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 446de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferRange(transform feedback active)"); 447de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 448de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 449de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 45015ac66e331abdab12e882d80a6b4f647bc905298Marek Olšák if (index >= ctx->Const.MaxTransformFeedbackBuffers) { 451de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); 452de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 453de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 454de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 455b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt if (size & 0x3) { 456b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt /* must a multiple of four */ 4571979e22e13dd28553bcc67cc51e56684e6ee4768Paul Berry _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size); 458de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 459de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 460de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 461de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (offset & 0x3) { 462de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* must be multiple of four */ 463de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 4649eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul "glBindBufferRange(offset=%d)", (int) offset); 465de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 466de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 467de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 468de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 469de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 470de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 471de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 472de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 473de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. 474de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * As above, but start at offset = 0. 475d988ea5e810868244eb1a1e7ede32295c9ed9ad4Brian Paul * Called from the glBindBufferBase() function. 476de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 477b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholtvoid 478b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, 479b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt GLuint index, 480b82c47215689d1243d1aa810bff7f06d8288d686Eric Anholt struct gl_buffer_object *bufObj) 481de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 482fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 483de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 484de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 485fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 486fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 487fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 488de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 4892be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferBase(transform feedback active)"); 490de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 491de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 492de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 49315ac66e331abdab12e882d80a6b4f647bc905298Marek Olšák if (index >= ctx->Const.MaxTransformFeedbackBuffers) { 494de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); 495de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 496de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 497de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 498de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 499de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 500de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 501de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = bufObj->Size & ~0x3; 502de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 503de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, 0, size); 504de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 505de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 506de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 507de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 508de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results, plus the 509de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * offset in the buffer to start placing results. 510de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function is part of GL_EXT_transform_feedback, but not GL3. 511de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 512de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 513de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, 514de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset) 515de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 516fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 517de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 518de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 519de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 520de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 521de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 522de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferOffsetEXT(target)"); 523de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 524de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 525de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 526fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 527fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 528fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 529de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 5302be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferOffsetEXT(transform feedback active)"); 531de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 532de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 533de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 53415ac66e331abdab12e882d80a6b4f647bc905298Marek Olšák if (index >= ctx->Const.MaxTransformFeedbackBuffers) { 535de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 536de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(index=%d)", index); 537de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 538de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 539de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 54086bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry if (offset & 0x3) { 54186bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry /* must be multiple of four */ 54286bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry _mesa_error(ctx, GL_INVALID_VALUE, 54386bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry "glBindBufferOffsetEXT(offset=%d)", (int) offset); 54486bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry return; 54586bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry } 54686bb45ffc36280263ba99fdca0c341489ad99e7fPaul Berry 54705b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke if (buffer == 0) { 54805b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = ctx->Shared->NullBufferObj; 54905b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } else { 55005b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke bufObj = _mesa_lookup_bufferobj(ctx, buffer); 55105b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke } 55205b086ce934fa2967da736db8db429d0886735a9Kenneth Graunke 553de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 554de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 555de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(invalid buffer=%u)", buffer); 556de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 557de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 558de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 559de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 560de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 561de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 562de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = (bufObj->Size - offset) & ~0x3; 563de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 564de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 565de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 566de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 567de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 568de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 569de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function specifies the vertex shader outputs to be written 570de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s), and in what order. 571de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 572de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 573de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_TransformFeedbackVaryings(GLuint program, GLsizei count, 574de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const GLchar **varyings, GLenum bufferMode) 575de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 576de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_shader_program *shProg; 577de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLuint i; 578de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 579de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 580de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (bufferMode) { 581de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_INTERLEAVED_ATTRIBS: 582de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 583de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_SEPARATE_ATTRIBS: 584de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 585de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 586de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, 587de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(bufferMode)"); 588de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 589de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 590de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 591f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák if (count < 0 || 592f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák (bufferMode == GL_SEPARATE_ATTRIBS && 59315ac66e331abdab12e882d80a6b4f647bc905298Marek Olšák (GLuint) count > ctx->Const.MaxTransformFeedbackBuffers)) { 594de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 595de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(count=%d)", count); 596de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 597de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 598de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 599de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 600de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 601de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 602de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(program=%u)", program); 603de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 604de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 605de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 606375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák if (ctx->Extensions.ARB_transform_feedback3) { 607375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák if (bufferMode == GL_INTERLEAVED_ATTRIBS) { 608375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák unsigned buffers = 1; 609375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák 610375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák for (i = 0; i < count; i++) { 611375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák if (strcmp(varyings[i], "gl_NextBuffer") == 0) 612375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák buffers++; 613375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 614375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák 615375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák if (buffers > ctx->Const.MaxTransformFeedbackBuffers) { 616375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák _mesa_error(ctx, GL_INVALID_OPERATION, 617375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák "glTransformFeedbackVaryings(too many gl_NextBuffer " 618375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák "occurences)"); 619375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák return; 620375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 621375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } else { 622375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák for (i = 0; i < count; i++) { 623375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák if (strcmp(varyings[i], "gl_NextBuffer") == 0 || 624375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák strcmp(varyings[i], "gl_SkipComponents1") == 0 || 625375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák strcmp(varyings[i], "gl_SkipComponents2") == 0 || 626375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák strcmp(varyings[i], "gl_SkipComponents3") == 0 || 627375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák strcmp(varyings[i], "gl_SkipComponents4") == 0) { 628375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák _mesa_error(ctx, GL_INVALID_OPERATION, 629375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák "glTransformFeedbackVaryings(SEPARATE_ATTRIBS," 630375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák "varying=%s)", 631375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák varyings[i]); 632375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák return; 633375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 634375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 635375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 636375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák } 637375e73d85948b43aa509e25f0a210ebd10238b6fMarek Olšák 638de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* free existing varyings, if any */ 639de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 640de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames[i]); 641de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 642de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames); 643de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 644de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* allocate new memory for varying names */ 645de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames = 646de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul (GLchar **) malloc(count * sizeof(GLchar *)); 647de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 648de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg->TransformFeedback.VaryingNames) { 649de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTransformFeedbackVaryings()"); 650de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 651de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 652de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 653de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* Save the new names and the count */ 654de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < (GLuint) count; i++) { 655de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames[i] = _mesa_strdup(varyings[i]); 656de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 657de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.NumVarying = count; 658de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 659de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.BufferMode = bufferMode; 660de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 661a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry /* No need to set _NEW_TRANSFORM_FEEDBACK (or invoke FLUSH_VERTICES) since 662a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry * the varyings won't be used until shader link time. 663a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry */ 664de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 665de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 666de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 667de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 668de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Get info about the vertex shader's outputs which are to be written 669de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s). 670de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 671de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 672de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, 673de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei bufSize, GLsizei *length, 674de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei *size, GLenum *type, GLchar *name) 675de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 676de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const struct gl_shader_program *shProg; 6779d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt const struct gl_transform_feedback_info *linked_xfb_info; 678de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 679de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 680de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 681de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 682de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 683de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(program=%u)", program); 684de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 685de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 686de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 6879d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt linked_xfb_info = &shProg->LinkedTransformFeedback; 6889d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (index >= linked_xfb_info->NumVarying) { 689de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 690de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(index=%u)", index); 691de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 692de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 693de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 6949d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt /* return the varying's name and length */ 6959d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt _mesa_copy_string(name, bufSize, length, 6969d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt linked_xfb_info->Varyings[index].Name); 697de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 6989d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt /* return the datatype and value's size (in datatype units) */ 6999d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (type) 7009d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt *type = linked_xfb_info->Varyings[index].Type; 7019d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt if (size) 7029d36c96d6ec9f2c05c8e0b9ef18c5462cddee8c1Eric Anholt *size = linked_xfb_info->Varyings[index].Size; 703de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 704de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 705fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 706fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 70714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstruct gl_transform_feedback_object * 70814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) 709fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 710fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (name == 0) { 711fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return ctx->TransformFeedback.DefaultObject; 712fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 713fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 714fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return (struct gl_transform_feedback_object *) 715fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashLookup(ctx->TransformFeedback.Objects, name); 716fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 717fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 718fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 719fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 720fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Create new transform feedback objects. Transform feedback objects 721fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * encapsulate the state related to transform feedback to allow quickly 722fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * switching state (and drawing the results, below). 723fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 724fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 725fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 726fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) 727fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 728fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLuint first; 729fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 730fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 731fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 732fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 733fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 734fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)"); 735fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 736fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 737fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 738fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 739fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 740fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 741fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* we don't need contiguous IDs, but this might be faster */ 742fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul first = _mesa_HashFindFreeKeyBlock(ctx->TransformFeedback.Objects, n); 743fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (first) { 744fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLsizei i; 745fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 746fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 747fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul = ctx->Driver.NewTransformFeedback(ctx, first + i); 748fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 749fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 750fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 751fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 752fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i] = first + i; 753fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj); 754fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 755fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 756fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else { 757fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 758fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 759fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 760fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 761fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 762fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 763fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Is the given ID a transform feedback object? 764fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 765fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 766fef6e36e0736a68e24d7844bae65a01de8359214Brian PaulGLboolean GLAPIENTRY 767fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_IsTransformFeedback(GLuint name) 768fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 769fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 770fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 771fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 772fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 77314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák if (name && _mesa_lookup_transform_feedback_object(ctx, name)) 774fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_TRUE; 775fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 776fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_FALSE; 777fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 778fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 779fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 780fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 781fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Bind the given transform feedback object. 782fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 783fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 784fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 785d74f525060f779cfe449c20853b11ba2bbcdea6dVinson Lee_mesa_BindTransformFeedback(GLenum target, GLuint name) 786fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 787fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 788fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 789fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 790fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (target != GL_TRANSFORM_FEEDBACK) { 791fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindTransformFeedback(target)"); 792fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 793fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 794fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 795fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (ctx->TransformFeedback.CurrentObject->Active && 796fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul !ctx->TransformFeedback.CurrentObject->Paused) { 797fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 79839c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul "glBindTransformFeedback(transform is active, or not paused)"); 799fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 800fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 801fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 80214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák obj = _mesa_lookup_transform_feedback_object(ctx, name); 803fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 804fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 805fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glBindTransformFeedback(name=%u)", name); 806fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 807fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 808fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 809fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject, 810fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj); 811fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 812fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 813fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 814fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 815fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Delete the given transform feedback objects. 816fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 817fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 818fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 819fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names) 820fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 821fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLint i; 822fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 823fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 824fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 825fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 826fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 827fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTransformFeedbacks(n < 0)"); 828fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 829fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 830fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 831fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 832fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 833fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 834fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 835fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (names[i] > 0) { 836fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 83714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák = _mesa_lookup_transform_feedback_object(ctx, names[i]); 838fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 839fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 840fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 841fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glDeleteTransformFeedbacks(object %u is active)", 842fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i]); 843fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 844fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 845fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]); 846fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* unref, but object may not be deleted until later */ 847fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&obj, NULL); 848fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 849fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 850fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 851fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 852fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 853fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 854fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 855fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Pause transform feedback. 856fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 857fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 858fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 859fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_PauseTransformFeedback(void) 860fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 861fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 862fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 863fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 864fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 865fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 866fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || obj->Paused) { 867fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 868fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glPauseTransformFeedback(feedback not active or already paused)"); 869fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 870fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 871fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 872a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 873fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_TRUE; 874fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 875fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.PauseTransformFeedback); 876fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.PauseTransformFeedback(ctx, obj); 877fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 878fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 879fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 880fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 881fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Resume transform feedback. 882fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 883fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 884fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 885fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_ResumeTransformFeedback(void) 886fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 887fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 888fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 889fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 890fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 891fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 892fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || !obj->Paused) { 893fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 894076bd11112742ca615880f2c6dc6ed235ab37eb5Brian Paul "glResumeTransformFeedback(feedback not active or not paused)"); 895fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 896fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 897fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 898a98ceee0ee3692783047c6f8f9f6bf6afbf4dd3bPaul Berry FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); 899fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_FALSE; 900fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 901fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.ResumeTransformFeedback); 902fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.ResumeTransformFeedback(ctx, obj); 903fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 904fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 905b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu#endif /* FEATURE_EXT_transform_feedback */ 906