transformfeedback.c revision c67d9cfd9d5d04b5b32170616f75b34e0192304b
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 if the given primitive mode (as in glBegin(mode)) is compatible 93de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * with the current transform feedback mode (if it's enabled). 94de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This is to be called from glBegin(), glDrawArrays(), glDrawElements(), etc. 95de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * 96de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * \return GL_TRUE if the mode is OK, GL_FALSE otherwise. 97de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 98de8530e1546733bf21b2e0518d6c5bda560770b9Brian PaulGLboolean 99f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode) 100de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 101fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (ctx->TransformFeedback.CurrentObject->Active) { 102de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (mode) { 103de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_POINTS: 104de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return ctx->TransformFeedback.Mode == GL_POINTS; 105de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINES: 106de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINE_STRIP: 107de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINE_LOOP: 108de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return ctx->TransformFeedback.Mode == GL_LINES; 109de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 110de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return ctx->TransformFeedback.Mode == GL_TRIANGLES; 111de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 112de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 113de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return GL_TRUE; 114de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 115de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 116de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 117de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 118de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Check that all the buffer objects currently bound for transform 119de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * feedback actually exist. Raise a GL_INVALID_OPERATION error if 120de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * any buffers are missing. 121de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * \return GL_TRUE for success, GL_FALSE if error 122de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 123de8530e1546733bf21b2e0518d6c5bda560770b9Brian PaulGLboolean 124f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_validate_transform_feedback_buffers(struct gl_context *ctx) 125de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 126fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* XXX to do */ 127de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return GL_TRUE; 128de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 129de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 130de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 131de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 132de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 133de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Per-context init for transform feedback. 134de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 135de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid 136f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_init_transform_feedback(struct gl_context *ctx) 137de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 13832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu /* core mesa expects this, even a dummy one, to be available */ 13932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ASSERT(ctx->Driver.NewTransformFeedback); 140fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 141fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.DefaultObject = 142fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.NewTransformFeedback(ctx, 0); 143fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 144fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->TransformFeedback.DefaultObject->RefCount == 1); 145fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 146fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject, 147fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.DefaultObject); 148fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 149fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->TransformFeedback.DefaultObject->RefCount == 2); 150fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 151fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.Objects = _mesa_NewHashTable(); 152fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 153de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 154de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 155de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul ctx->Shared->NullBufferObj); 156de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 157de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 158de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 159fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 160fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 161fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Callback for _mesa_HashDeleteAll(). 162fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 163fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 164fef6e36e0736a68e24d7844bae65a01de8359214Brian Pauldelete_cb(GLuint key, void *data, void *userData) 165fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 166f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 167fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 168fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul (struct gl_transform_feedback_object *) data; 169fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 170fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.DeleteTransformFeedback(ctx, obj); 171fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 172fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 173fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 174de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 175de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Per-context free/clean-up for transform feedback. 176de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 177de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid 178f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_free_transform_feedback(struct gl_context *ctx) 179de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 18032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu /* core mesa expects this, even a dummy one, to be available */ 18132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ASSERT(ctx->Driver.NewTransformFeedback); 182fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 183de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 184de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 185de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul NULL); 186fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 187fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* Delete all feedback objects */ 188fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashDeleteAll(ctx->TransformFeedback.Objects, delete_cb, ctx); 1895b90f83aee89d051983485cdec5b5db2f3659256Brian Paul _mesa_DeleteHashTable(ctx->TransformFeedback.Objects); 190fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 191fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* Delete the default feedback object */ 192fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.DeleteTransformFeedback); 19339c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul ctx->Driver.DeleteTransformFeedback(ctx, 19439c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul ctx->TransformFeedback.DefaultObject); 195fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 196fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject = NULL; 197de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 198de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 199de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 20032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#else /* FEATURE_EXT_transform_feedback */ 20132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 20232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu/* forward declarations */ 20332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wustatic struct gl_transform_feedback_object * 204f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnew_transform_feedback(struct gl_context *ctx, GLuint name); 20532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 20632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wustatic void 207f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdelete_transform_feedback(struct gl_context *ctx, 20832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu struct gl_transform_feedback_object *obj); 20932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 21032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu/* dummy per-context init/clean-up for transform feedback */ 21132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wuvoid 212f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_init_transform_feedback(struct gl_context *ctx) 21332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu{ 21432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.DefaultObject = new_transform_feedback(ctx, 0); 21532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.CurrentObject = ctx->TransformFeedback.DefaultObject; 21632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu _mesa_reference_buffer_object(ctx, 21732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu &ctx->TransformFeedback.CurrentBuffer, 21832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->Shared->NullBufferObj); 21932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu} 22032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 22132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wuvoid 222f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_free_transform_feedback(struct gl_context *ctx) 22332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu{ 22432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu _mesa_reference_buffer_object(ctx, 22532a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu &ctx->TransformFeedback.CurrentBuffer, 22632a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu NULL); 22732a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu ctx->TransformFeedback.CurrentObject = NULL; 22832a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu delete_transform_feedback(ctx, ctx->TransformFeedback.DefaultObject); 22932a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu} 23032a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 23132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#endif /* FEATURE_EXT_transform_feedback */ 23232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 23332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 234fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.NewTransformFeedback() */ 235fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic struct gl_transform_feedback_object * 236f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnew_transform_feedback(struct gl_context *ctx, GLuint name) 237fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 238fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 239fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = CALLOC_STRUCT(gl_transform_feedback_object); 240fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 241fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Name = name; 242fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->RefCount = 1; 243fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 244fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return obj; 245fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 246fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 247fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.DeleteTransformFeedback() */ 248fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 249f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdelete_transform_feedback(struct gl_context *ctx, 250fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 251fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 252fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLuint i; 253fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 254fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < Elements(obj->Buffers); i++) { 255fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL); 256fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 257fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 258fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul free(obj); 259fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 260fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 26132a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 26232a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu#if FEATURE_EXT_transform_feedback 26332a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 26432a9b2799e5e1254fdf84af8248ea86e234d6dd4Chia-I Wu 265fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.BeginTransformFeedback() */ 266fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 267f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergbegin_transform_feedback(struct gl_context *ctx, GLenum mode, 268fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 269fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 270fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 271fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 272fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 273fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.EndTransformFeedback() */ 274fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 275f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergend_transform_feedback(struct gl_context *ctx, 276fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 277fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 278fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 279fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 280fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 281fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.PauseTransformFeedback() */ 282fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 283f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergpause_transform_feedback(struct gl_context *ctx, 284fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 285fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 286fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 287fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 288fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 289fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.ResumeTransformFeedback() */ 290fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 291f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergresume_transform_feedback(struct gl_context *ctx, 292fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 293fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 294fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* nop */ 295fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 296fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 297fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** Default fallback for ctx->Driver.DrawTransformFeedback() */ 298fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic void 299f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdraw_transform_feedback(struct gl_context *ctx, GLenum mode, 300fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj) 301fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 302fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* XXX to do */ 303fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* 304fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Get number of vertices in obj's feedback buffer. 305fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Call ctx->Exec.DrawArrays(mode, 0, count); 306fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 307fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 308fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 309fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 310fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 311fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Plug in default device driver functions for transform feedback. 312fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Most drivers will override some/all of these. 313fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 314fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid 315fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_init_transform_feedback_functions(struct dd_function_table *driver) 316fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 317fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->NewTransformFeedback = new_transform_feedback; 318fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->DeleteTransformFeedback = delete_transform_feedback; 319fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->BeginTransformFeedback = begin_transform_feedback; 320fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->EndTransformFeedback = end_transform_feedback; 321fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->PauseTransformFeedback = pause_transform_feedback; 322fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->ResumeTransformFeedback = resume_transform_feedback; 323fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul driver->DrawTransformFeedback = draw_transform_feedback; 324fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 325fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 326fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 327b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wuvoid 328b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu_mesa_init_transform_feedback_dispatch(struct _glapi_table *disp) 329b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu{ 33048dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák /* EXT_transform_feedback */ 331b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BeginTransformFeedbackEXT(disp, _mesa_BeginTransformFeedback); 332b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_EndTransformFeedbackEXT(disp, _mesa_EndTransformFeedback); 333b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferRangeEXT(disp, _mesa_BindBufferRange); 334b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferBaseEXT(disp, _mesa_BindBufferBase); 335b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_BindBufferOffsetEXT(disp, _mesa_BindBufferOffsetEXT); 336b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_TransformFeedbackVaryingsEXT(disp, _mesa_TransformFeedbackVaryings); 337b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu SET_GetTransformFeedbackVaryingEXT(disp, _mesa_GetTransformFeedbackVarying); 33848dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák /* ARB_transform_feedback2 */ 33948dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_BindTransformFeedback(disp, _mesa_BindTransformFeedback); 34048dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_DeleteTransformFeedbacks(disp, _mesa_DeleteTransformFeedbacks); 34148dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_GenTransformFeedbacks(disp, _mesa_GenTransformFeedbacks); 34248dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback); 34348dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback); 34448dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback); 34548dcdcffd61c6c3755d818493bc3b7bdc1260ea5Marek Olšák SET_DrawTransformFeedback(disp, _mesa_DrawTransformFeedback); 346b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu} 347b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu 348fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 349fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 350fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ** Begin API functions 351fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul **/ 352fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 353fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 354de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 355de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BeginTransformFeedback(GLenum mode) 356de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 357fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 358de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 359de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 360fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 361fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 362de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (mode) { 363de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_POINTS: 364de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_LINES: 365de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_TRIANGLES: 366de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* legal */ 367de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 368de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 369de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBeginTransformFeedback(mode)"); 370de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 371de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 372de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 373fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 374de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 375de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBeginTransformFeedback(already active)"); 376de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 377de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 378de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 379fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Active = GL_TRUE; 380de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul ctx->TransformFeedback.Mode = mode; 381fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 382fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.BeginTransformFeedback); 383fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.BeginTransformFeedback(ctx, mode, obj); 384de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 385de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 386de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 387de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 388de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_EndTransformFeedback(void) 389de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 390fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 391de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 392de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 393fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 394fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 395fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active) { 396de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 397de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glEndTransformFeedback(not active)"); 398de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 399de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 400de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 401fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; 402fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 403fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.EndTransformFeedback); 404fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.EndTransformFeedback(ctx, obj); 405de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 406de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 407de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 408de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 409de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Helper used by BindBufferRange() and BindBufferBase(). 410de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 411de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulstatic void 412f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergbind_buffer_range(struct gl_context *ctx, GLuint index, 413de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj, 414de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset, GLsizeiptr size) 415de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 416fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 417fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->TransformFeedback.CurrentObject; 418fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 419de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The general binding point */ 420de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 421de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul &ctx->TransformFeedback.CurrentBuffer, 422de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 423de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 424de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The per-attribute binding point */ 425de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_reference_buffer_object(ctx, 426fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul &obj->Buffers[index], 427de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj); 428de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 429fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->BufferNames[index] = bufObj->Name; 430de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 431fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Offset[index] = offset; 432fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Size[index] = size; 433de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 434de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 435de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 436de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 437de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. Plus, 438de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * specify the starting offset to place the results, and max size. 439de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 440de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 441de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferRange(GLenum target, GLuint index, 442de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLuint buffer, GLintptr offset, GLsizeiptr size) 443de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 444fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 445de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 446de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 447de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 448de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 449de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)"); 450de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 451de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 452de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 453fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 454fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 455fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 456de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 457de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferRange(transform feedback active)"); 458de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 459de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 460de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 461de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 462de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); 463de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 464de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 465de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 466de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if ((size <= 0) || (size & 0x3)) { 467de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* must be positive and multiple of four */ 4689eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size%d)", (int) size); 469de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 470de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 471de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 472de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (offset & 0x3) { 473de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* must be multiple of four */ 474de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 4759eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul "glBindBufferRange(offset=%d)", (int) offset); 476de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 477de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 478de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 479de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj = _mesa_lookup_bufferobj(ctx, buffer); 480de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 481de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 482de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferRange(invalid buffer=%u)", buffer); 483de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 484de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 485de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 486de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (offset + size >= bufObj->Size) { 487de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 48886af037e6a1643284f87c5e01c3fcb09dd07bf35Eric Anholt "glBindBufferRange(offset + size %d > buffer size %d)", 4899eca0e2c3e9409b5da49d9a5052d3665e7d45bb1Brian Paul (int) (offset + size), (int) (bufObj->Size)); 490de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 491de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 492de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 493de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 494de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 495de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 496de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 497de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 498de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results. 499de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * As above, but start at offset = 0. 500de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 501de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 502de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) 503de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 504fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 505de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 506de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 507fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 508de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 509de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 510de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)"); 511de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 512de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 513de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 514fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 515fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 516fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 517de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 5182be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferBase(transform feedback active)"); 519de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 520de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 521de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 522de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 523de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); 524de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 525de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 526de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 527de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj = _mesa_lookup_bufferobj(ctx, buffer); 528de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 529de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 530de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferBase(invalid buffer=%u)", buffer); 531de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 532de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 533de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 534de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 535de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 536de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 537de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = bufObj->Size & ~0x3; 538de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 539de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, 0, size); 540de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 541de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 542de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 543de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 544de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Specify a buffer object to receive vertex shader results, plus the 545de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * offset in the buffer to start placing results. 546de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function is part of GL_EXT_transform_feedback, but not GL3. 547de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 548de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 549de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, 550de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLintptr offset) 551de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 552fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 553de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_buffer_object *bufObj; 554de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 555de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizeiptr size; 556de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 557de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { 558de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferOffsetEXT(target)"); 559de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 560de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 561de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 562fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 563fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 564fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 565de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 5662be2e1d3ada2d9cb5c1c42e955629d8fbbafcd0bBrian Paul "glBindBufferOffsetEXT(transform feedback active)"); 567de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 568de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 569de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 570de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs) { 571de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 572de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(index=%d)", index); 573de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 574de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 575de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 576de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bufObj = _mesa_lookup_bufferobj(ctx, buffer); 577de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!bufObj) { 578de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 579de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glBindBufferOffsetEXT(invalid buffer=%u)", buffer); 580de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 581de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 582de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 583de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* default size is the buffer size rounded down to nearest 584de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * multiple of four. 585de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 586de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul size = (bufObj->Size - offset) & ~0x3; 587de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 588de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul bind_buffer_range(ctx, index, bufObj, offset, size); 589de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 590de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 591de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 592de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 593de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * This function specifies the vertex shader outputs to be written 594de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s), and in what order. 595de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 596de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 597de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_TransformFeedbackVaryings(GLuint program, GLsizei count, 598de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const GLchar **varyings, GLenum bufferMode) 599de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 600de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_shader_program *shProg; 601de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLuint i; 602de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 603de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 604de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul switch (bufferMode) { 605de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_INTERLEAVED_ATTRIBS: 606de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 607de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul case GL_SEPARATE_ATTRIBS: 608de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul break; 609de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul default: 610de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, 611de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(bufferMode)"); 612de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 613de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 614de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 615f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák if (count < 0 || 616f77aa278d354bebdbda940b31c9cccf12a5d146fMarek Olšák (bufferMode == GL_SEPARATE_ATTRIBS && 617c67d9cfd9d5d04b5b32170616f75b34e0192304bBrian Paul (GLuint) count > ctx->Const.MaxTransformFeedbackSeparateAttribs)) { 618de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 619de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(count=%d)", count); 620de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 621de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 622de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 623de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 624de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 625de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 626de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glTransformFeedbackVaryings(program=%u)", program); 627de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 628de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 629de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 630de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* free existing varyings, if any */ 631de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { 632de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames[i]); 633de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 634de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul free(shProg->TransformFeedback.VaryingNames); 635de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 636de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* allocate new memory for varying names */ 637de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames = 638de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul (GLchar **) malloc(count * sizeof(GLchar *)); 639de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 640de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg->TransformFeedback.VaryingNames) { 641de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTransformFeedbackVaryings()"); 642de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 643de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 644de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 645de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* Save the new names and the count */ 646de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul for (i = 0; i < (GLuint) count; i++) { 647de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.VaryingNames[i] = _mesa_strdup(varyings[i]); 648de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 649de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.NumVarying = count; 650de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 651de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg->TransformFeedback.BufferMode = bufferMode; 652de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 653de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* The varyings won't be used until shader link time */ 654de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 655de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 656de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 657de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul/** 658de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * Get info about the vertex shader's outputs which are to be written 659de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul * to the feedback buffer(s). 660de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul */ 661de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paulvoid GLAPIENTRY 662de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul_mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, 663de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei bufSize, GLsizei *length, 664de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLsizei *size, GLenum *type, GLchar *name) 665de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul{ 666de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const struct gl_shader_program *shProg; 667de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul const GLchar *varyingName; 668de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GLint v; 669de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul GET_CURRENT_CONTEXT(ctx); 670de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 671de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul shProg = _mesa_lookup_shader_program(ctx, program); 672de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (!shProg) { 673de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 674de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(program=%u)", program); 675de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 676de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 677de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 678de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (index >= shProg->TransformFeedback.NumVarying) { 679de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 680de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul "glGetTransformFeedbackVaryings(index=%u)", index); 681de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul return; 682de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 683de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 684de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul varyingName = shProg->TransformFeedback.VaryingNames[index]; 685de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 686de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul v = _mesa_lookup_parameter_index(shProg->Varying, -1, varyingName); 687de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (v >= 0) { 688de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul struct gl_program_parameter *param = &shProg->Varying->Parameters[v]; 689de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 690de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* return the varying's name and length */ 691de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul _mesa_copy_string(name, bufSize, length, varyingName); 692de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 693de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul /* return the datatype and value's size (in datatype units) */ 694de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (type) 6953100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul *type = param->DataType; 696de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul if (size) 697de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul *size = param->Size; 698de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul } 6993100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul else { 7003100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul name[0] = 0; 7013100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul if (length) 7023100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul *length = 0; 7033100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul if (type) 7043100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul *type = 0; 7053100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul if (size) 7063100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul *size = 0; 7073100f31b747a3294e1e7043ed9a61d8b90bf423aBrian Paul } 708de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul} 709de8530e1546733bf21b2e0518d6c5bda560770b9Brian Paul 710fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 711fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 712fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulstatic struct gl_transform_feedback_object * 713f9995b30756140724f41daf963fa06167912be7fKristian Høgsberglookup_transform_feedback_object(struct gl_context *ctx, GLuint name) 714fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 715fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (name == 0) { 716fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return ctx->TransformFeedback.DefaultObject; 717fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 718fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 719fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return (struct gl_transform_feedback_object *) 720fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashLookup(ctx->TransformFeedback.Objects, name); 721fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 722fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 723fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 724fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 725fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Create new transform feedback objects. Transform feedback objects 726fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * encapsulate the state related to transform feedback to allow quickly 727fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * switching state (and drawing the results, below). 728fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 729fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 730fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 731fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) 732fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 733fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLuint first; 734fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 735fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 736fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 737fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 738fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 739fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)"); 740fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 741fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 742fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 743fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 744fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 745fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 746fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* we don't need contiguous IDs, but this might be faster */ 747fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul first = _mesa_HashFindFreeKeyBlock(ctx->TransformFeedback.Objects, n); 748fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (first) { 749fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLsizei i; 750fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 751fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 752fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul = ctx->Driver.NewTransformFeedback(ctx, first + i); 753fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 754fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 755fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 756fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 757fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i] = first + i; 758fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj); 759fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 760fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 761fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else { 762fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); 763fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 764fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 765fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 766fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 767fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 768fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Is the given ID a transform feedback object? 769fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 770fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 771fef6e36e0736a68e24d7844bae65a01de8359214Brian PaulGLboolean GLAPIENTRY 772fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_IsTransformFeedback(GLuint name) 773fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 774fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 775fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 776fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 777fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 778fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (name && lookup_transform_feedback_object(ctx, name)) 779fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_TRUE; 780fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul else 781fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return GL_FALSE; 782fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 783fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 784fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 785fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 786fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Bind the given transform feedback object. 787fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 788fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 789fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 790d74f525060f779cfe449c20853b11ba2bbcdea6dVinson Lee_mesa_BindTransformFeedback(GLenum target, GLuint name) 791fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 792fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 793fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 794fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 795fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (target != GL_TRANSFORM_FEEDBACK) { 796fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glBindTransformFeedback(target)"); 797fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 798fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 799fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 800fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (ctx->TransformFeedback.CurrentObject->Active && 801fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul !ctx->TransformFeedback.CurrentObject->Paused) { 802fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 80339c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul "glBindTransformFeedback(transform is active, or not paused)"); 804fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 805fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 806fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 807fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = lookup_transform_feedback_object(ctx, name); 808fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 809fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 810fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glBindTransformFeedback(name=%u)", name); 811fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 812fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 813fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 814fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject, 815fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj); 816fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 817fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 818fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 819fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 820fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Delete the given transform feedback objects. 821fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 822fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 823fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 824fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names) 825fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 826fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GLint i; 827fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 828fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 829fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ASSERT_OUTSIDE_BEGIN_END(ctx); 830fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 831fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (n < 0) { 832fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTransformFeedbacks(n < 0)"); 833fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 834fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 835fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 836fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!names) 837fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 838fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 839fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul for (i = 0; i < n; i++) { 840fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (names[i] > 0) { 841fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj 842fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul = lookup_transform_feedback_object(ctx, names[i]); 843fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj) { 844fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (obj->Active) { 845fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 846fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glDeleteTransformFeedbacks(object %u is active)", 847fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul names[i]); 848fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 849fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 850fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]); 851fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* unref, but object may not be deleted until later */ 852fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul reference_transform_feedback_object(&obj, NULL); 853fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 854fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 855fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 856fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 857fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 858fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 859fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 860fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Pause transform feedback. 861fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 862fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 863fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 864fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_PauseTransformFeedback(void) 865fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 866fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 867fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 868fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 869fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 870fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 871fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || obj->Paused) { 872fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 873fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glPauseTransformFeedback(feedback not active or already paused)"); 874fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 875fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 876fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 877fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_TRUE; 878fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 879fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.PauseTransformFeedback); 880fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.PauseTransformFeedback(ctx, obj); 881fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 882fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 883fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 884fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 885fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Resume transform feedback. 886fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 887fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 888fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 889fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_ResumeTransformFeedback(void) 890fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 891fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj; 892fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 893fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 894fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj = ctx->TransformFeedback.CurrentObject; 895fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 896fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj->Active || !obj->Paused) { 897fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 898076bd11112742ca615880f2c6dc6ed235ab37eb5Brian Paul "glResumeTransformFeedback(feedback not active or not paused)"); 899fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 900fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 901fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 902fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul obj->Paused = GL_FALSE; 903fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 904fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.ResumeTransformFeedback); 905fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.ResumeTransformFeedback(ctx, obj); 906fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 907fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 908fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 909fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul/** 910fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Draw the vertex data in a transform feedback object. 911fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 912fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * \param name the transform feedback object 913fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * The number of vertices comes from the transform feedback object. 914fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * User still has to setup of the vertex attribute info with 915fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * glVertexPointer, glColorPointer, etc. 916fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * Part of GL_ARB_transform_feedback2. 917fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 918fef6e36e0736a68e24d7844bae65a01de8359214Brian Paulvoid GLAPIENTRY 919fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul_mesa_DrawTransformFeedback(GLenum mode, GLuint name) 920fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul{ 921fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul GET_CURRENT_CONTEXT(ctx); 922fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul struct gl_transform_feedback_object *obj = 923fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul lookup_transform_feedback_object(ctx, name); 924fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 92539c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul if (mode > GL_POLYGON) { 92639c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, 92739c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul "glDrawTransformFeedback(mode=0x%x)", mode); 92839c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul return; 92939c13a115eb45fb6c711cd86cda3a0c178975b52Brian Paul } 930fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul if (!obj) { 931fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, 932fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul "glDrawTransformFeedback(name = %u)", name); 933fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul return; 934fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul } 935fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 936fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul /* XXX check if EndTransformFeedback has never been called while 937fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul * the object was bound 938fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul */ 939fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 940fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul assert(ctx->Driver.DrawTransformFeedback); 941fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul ctx->Driver.DrawTransformFeedback(ctx, mode, obj); 942fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul} 943fef6e36e0736a68e24d7844bae65a01de8359214Brian Paul 944b093016bd0660cc4ac6142aa8d4d6add5b6bfce8Chia-I Wu#endif /* FEATURE_EXT_transform_feedback */ 945