st_cb_bufferobjects.c revision cd1eefee8404ae69ea5b604971b8be78abf588e6
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29#include "main/imports.h" 30#include "main/mtypes.h" 31#include "main/bufferobj.h" 32 33#include "st_context.h" 34#include "st_cb_bufferobjects.h" 35 36#include "pipe/p_context.h" 37#include "pipe/p_defines.h" 38#include "pipe/p_winsys.h" 39 40 41 42/* Pixel buffers and Vertex/index buffers are handled through these 43 * mesa callbacks. Framebuffer/Renderbuffer objects are 44 * created/managed elsewhere. 45 */ 46 47 48 49/** 50 * There is some duplication between mesa's bufferobjects and our 51 * bufmgr buffers. Both have an integer handle and a hashtable to 52 * lookup an opaque structure. It would be nice if the handles and 53 * internal structure where somehow shared. 54 */ 55static struct gl_buffer_object * 56st_bufferobj_alloc(GLcontext *ctx, GLuint name, GLenum target) 57{ 58 struct st_context *st = st_context(ctx); 59 struct st_buffer_object *st_obj = CALLOC_STRUCT(st_buffer_object); 60 61 if (!st_obj) 62 return NULL; 63 64 _mesa_initialize_buffer_object(&st_obj->Base, name, target); 65 66 st_obj->buffer = st->pipe->winsys->buffer_create( st->pipe->winsys, 32, 0, 0 ); 67 68 return &st_obj->Base; 69} 70 71 72 73/** 74 * Deallocate/free a vertex/pixel buffer object. 75 * Called via glDeleteBuffersARB(). 76 */ 77static void 78st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj) 79{ 80 struct pipe_context *pipe = st_context(ctx)->pipe; 81 struct st_buffer_object *st_obj = st_buffer_object(obj); 82 83 if (st_obj->buffer) 84 pipe->winsys->buffer_reference(pipe->winsys, &st_obj->buffer, NULL); 85 86 free(st_obj); 87} 88 89 90 91/** 92 * Allocate space for and store data in a buffer object. Any data that was 93 * previously stored in the buffer object is lost. If data is NULL, 94 * memory will be allocated, but no copy will occur. 95 * Called via glBufferDataARB(). 96 */ 97static void 98st_bufferobj_data(GLcontext *ctx, 99 GLenum target, 100 GLsizeiptrARB size, 101 const GLvoid * data, 102 GLenum usage, 103 struct gl_buffer_object *obj) 104{ 105 struct pipe_context *pipe = st_context(ctx)->pipe; 106 struct st_buffer_object *st_obj = st_buffer_object(obj); 107 unsigned buffer_usage; 108 109 st_obj->Base.Size = size; 110 st_obj->Base.Usage = usage; 111 112 switch(target) { 113 case GL_PIXEL_PACK_BUFFER_ARB: 114 case GL_PIXEL_UNPACK_BUFFER_ARB: 115 buffer_usage = PIPE_BUFFER_USAGE_PIXEL; 116 break; 117 case GL_ARRAY_BUFFER_ARB: 118 buffer_usage = PIPE_BUFFER_USAGE_VERTEX; 119 break; 120 case GL_ELEMENT_ARRAY_BUFFER_ARB: 121 buffer_usage = PIPE_BUFFER_USAGE_INDEX; 122 break; 123 default: 124 buffer_usage = 0; 125 } 126 127 pipe->winsys->buffer_data( pipe->winsys, st_obj->buffer, 128 size, data, 129 buffer_usage ); 130} 131 132 133/** 134 * Replace data in a subrange of buffer object. If the data range 135 * specified by size + offset extends beyond the end of the buffer or 136 * if data is NULL, no copy is performed. 137 * Called via glBufferSubDataARB(). 138 */ 139static void 140st_bufferobj_subdata(GLcontext *ctx, 141 GLenum target, 142 GLintptrARB offset, 143 GLsizeiptrARB size, 144 const GLvoid * data, struct gl_buffer_object *obj) 145{ 146 struct pipe_context *pipe = st_context(ctx)->pipe; 147 struct st_buffer_object *st_obj = st_buffer_object(obj); 148 149 pipe->winsys->buffer_subdata(pipe->winsys, st_obj->buffer, offset, size, data); 150} 151 152 153/** 154 * Called via glGetBufferSubDataARB(). 155 */ 156static void 157st_bufferobj_get_subdata(GLcontext *ctx, 158 GLenum target, 159 GLintptrARB offset, 160 GLsizeiptrARB size, 161 GLvoid * data, struct gl_buffer_object *obj) 162{ 163 struct pipe_context *pipe = st_context(ctx)->pipe; 164 struct st_buffer_object *st_obj = st_buffer_object(obj); 165 166 pipe->winsys->buffer_get_subdata(pipe->winsys, st_obj->buffer, offset, size, data); 167} 168 169 170/** 171 * Called via glMapBufferARB(). 172 */ 173static void * 174st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, 175 struct gl_buffer_object *obj) 176{ 177 struct pipe_context *pipe = st_context(ctx)->pipe; 178 struct st_buffer_object *st_obj = st_buffer_object(obj); 179 GLuint flags; 180 181 switch (access) { 182 case GL_WRITE_ONLY: 183 flags = PIPE_BUFFER_FLAG_WRITE; 184 break; 185 case GL_READ_ONLY: 186 flags = PIPE_BUFFER_FLAG_READ; 187 break; 188 case GL_READ_WRITE: 189 /* fall-through */ 190 default: 191 flags = PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE; 192 break; 193 } 194 195 obj->Pointer = pipe->winsys->buffer_map(pipe->winsys, st_obj->buffer, flags); 196 return obj->Pointer; 197} 198 199 200/** 201 * Called via glMapBufferARB(). 202 */ 203static GLboolean 204st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) 205{ 206 struct pipe_context *pipe = st_context(ctx)->pipe; 207 struct st_buffer_object *st_obj = st_buffer_object(obj); 208 209 pipe->winsys->buffer_unmap(pipe->winsys, st_obj->buffer); 210 obj->Pointer = NULL; 211 return GL_TRUE; 212} 213 214 215void 216st_init_bufferobject_functions(struct dd_function_table *functions) 217{ 218 functions->NewBufferObject = st_bufferobj_alloc; 219 functions->DeleteBuffer = st_bufferobj_free; 220 functions->BufferData = st_bufferobj_data; 221 functions->BufferSubData = st_bufferobj_subdata; 222 functions->GetBufferSubData = st_bufferobj_get_subdata; 223 functions->MapBuffer = st_bufferobj_map; 224 functions->UnmapBuffer = st_bufferobj_unmap; 225} 226