1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Functions for pixel buffer objects and vertex/element buffer objects. 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/arrayobj.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/bufferobj.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_context.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_cb_bufferobjects.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * There is some duplication between mesa's bufferobjects and our 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * bufmgr buffers. Both have an integer handle and a hashtable to 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lookup an opaque structure. It would be nice if the handles and 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * internal structure where somehow shared. 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_buffer_object * 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_alloc(struct gl_context *ctx, GLuint name, GLenum target) 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = ST_CALLOC_STRUCT(st_buffer_object); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!st_obj) 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_initialize_buffer_object(ctx, &st_obj->Base, name, target); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &st_obj->Base; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Deallocate/free a vertex/pixel buffer object. 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glDeleteBuffersARB(). 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(obj->RefCount == 0); 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(st_obj->transfer == NULL); 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (st_obj->buffer) 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&st_obj->buffer, NULL); 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(st_obj); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Replace data in a subrange of buffer object. If the data range 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specified by size + offset extends beyond the end of the buffer or 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if data is NULL, no copy is performed. 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glBufferSubDataARB(). 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_subdata(struct gl_context *ctx, 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLintptrARB offset, 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLsizeiptrARB size, 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLvoid * data, struct gl_buffer_object *obj) 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we may be called from VBO code, so double-check params here */ 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(offset >= 0); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(size >= 0); 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(offset + size <= obj->Size); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!size) 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * According to ARB_vertex_buffer_object specification, if data is null, 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * then the contents of the buffer object's data store is undefined. We just 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ignore, and leave it unchanged. 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!data) 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!st_obj->buffer) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we probably ran out of memory during buffer allocation */ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now that transfers are per-context, we don't have to figure out 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * flushing here. Usually drivers won't need to flush in this case 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * even if the buffer is currently referenced by hardware - they 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * just queue the upload as dma rather than mapping the underlying 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * buffer directly. 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_write(st_context(ctx)->pipe, 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->buffer, 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, size, data); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glGetBufferSubDataARB(). 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_get_subdata(struct gl_context *ctx, 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLintptrARB offset, 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLsizeiptrARB size, 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid * data, struct gl_buffer_object *obj) 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we may be called from VBO code, so double-check params here */ 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(offset >= 0); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(size >= 0); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(offset + size <= obj->Size); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!size) 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!st_obj->buffer) { 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we probably ran out of memory during buffer allocation */ 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_read(st_context(ctx)->pipe, st_obj->buffer, 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, size, data); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate space for and store data in a buffer object. Any data that was 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * previously stored in the buffer object is lost. If data is NULL, 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * memory will be allocated, but no copy will occur. 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via ctx->Driver.BufferData(). 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE for success, GL_FALSE if out of memory 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_data(struct gl_context *ctx, 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum target, 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLsizeiptrARB size, 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLvoid * data, 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum usage, 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_buffer_object *obj) 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_context *st = st_context(ctx); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context *pipe = st->pipe; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bind, pipe_usage; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->Base.Size = size; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->Base.Usage = usage; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(target) { 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_PIXEL_PACK_BUFFER_ARB: 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_PIXEL_UNPACK_BUFFER_ARB: 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_ARRAY_BUFFER_ARB: 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bind = PIPE_BIND_VERTEX_BUFFER; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_ELEMENT_ARRAY_BUFFER_ARB: 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bind = PIPE_BIND_INDEX_BUFFER; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_TRANSFORM_FEEDBACK_BUFFER: 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bind = PIPE_BIND_STREAM_OUTPUT; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bind = 0; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (usage) { 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STATIC_DRAW: 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STATIC_READ: 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STATIC_COPY: 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_usage = PIPE_USAGE_STATIC; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DYNAMIC_DRAW: 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DYNAMIC_READ: 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DYNAMIC_COPY: 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_usage = PIPE_USAGE_DYNAMIC; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STREAM_DRAW: 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STREAM_READ: 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STREAM_COPY: 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_usage = PIPE_USAGE_STREAM; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_usage = PIPE_USAGE_DEFAULT; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference( &st_obj->buffer, NULL ); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (size != 0) { 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->buffer = pipe_buffer_create(pipe->screen, bind, 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_usage, size); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!st_obj->buffer) { 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* out of memory */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->Base.Size = 0; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (data) 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_write(pipe, st_obj->buffer, 0, size, data); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glMapBufferRange(). 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void * 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_map_range(struct gl_context *ctx, 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLintptr offset, GLsizeiptr length, GLbitfield access, 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_buffer_object *obj) 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context *pipe = st_context(ctx)->pipe; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_transfer_usage flags = 0x0; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & GL_MAP_WRITE_BIT) 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_WRITE; 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & GL_MAP_READ_BIT) 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_READ; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & GL_MAP_FLUSH_EXPLICIT_BIT) 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_FLUSH_EXPLICIT; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & GL_MAP_INVALIDATE_BUFFER_BIT) { 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (access & GL_MAP_INVALIDATE_RANGE_BIT) { 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (offset == 0 && length == obj->Size) 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_DISCARD_RANGE; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & GL_MAP_UNSYNCHRONIZED_BIT) 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_UNSYNCHRONIZED; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* ... other flags ... 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (access & MESA_MAP_NOWAIT_BIT) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags |= PIPE_TRANSFER_DONTBLOCK; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(offset >= 0); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(length >= 0); 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(offset < obj->Size); 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(offset + length <= obj->Size); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Pointer = pipe_buffer_map_range(pipe, 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->buffer, 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, length, 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flags, 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &st_obj->transfer); 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (obj->Pointer) { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Offset = offset; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Length = length; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->AccessFlags = access; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return obj->Pointer; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_flush_mapped_range(struct gl_context *ctx, 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLintptr offset, GLsizeiptr length, 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_buffer_object *obj) 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context *pipe = st_context(ctx)->pipe; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Subrange is relative to mapped range */ 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(offset >= 0); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(length >= 0); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(offset + length <= obj->Length); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(obj->Pointer); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!length) 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_flush_mapped_range(pipe, st_obj->transfer, 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Offset + offset, length); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glUnmapBufferARB(). 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj) 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context *pipe = st_context(ctx)->pipe; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *st_obj = st_buffer_object(obj); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (obj->Length) 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_unmap(pipe, st_obj->transfer); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_obj->transfer = NULL; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Pointer = NULL; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Offset = 0; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obj->Length = 0; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glCopyBufferSubData(). 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_copy_buffer_subdata(struct gl_context *ctx, 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_buffer_object *src, 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_buffer_object *dst, 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLintptr readOffset, GLintptr writeOffset, 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLsizeiptr size) 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context *pipe = st_context(ctx)->pipe; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *srcObj = st_buffer_object(src); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *dstObj = st_buffer_object(dst); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_box box; 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!size) 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* buffer should not already be mapped */ 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!src->Pointer); 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!dst->Pointer); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org u_box_1d(readOffset, size, &box); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->resource_copy_region(pipe, dstObj->buffer, 0, writeOffset, 0, 0, 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcObj->buffer, 0, &box); 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* TODO: if buffer wasn't created with appropriate usage flags, need 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to recreate it now and copy contents -- or possibly create a 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gallium entrypoint to extend the usage flags and let the driver 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * decide if a copy is necessary. 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_bufferobj_validate_usage(struct st_context *st, 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_buffer_object *obj, 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned usage) 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_init_bufferobject_functions(struct dd_function_table *functions) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->NewBufferObject = st_bufferobj_alloc; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->DeleteBuffer = st_bufferobj_free; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->BufferData = st_bufferobj_data; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->BufferSubData = st_bufferobj_subdata; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->GetBufferSubData = st_bufferobj_get_subdata; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->MapBufferRange = st_bufferobj_map_range; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->UnmapBuffer = st_bufferobj_unmap; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->CopyBufferSubData = st_copy_buffer_subdata; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For GL_APPLE_vertex_array_object */ 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->NewArrayObject = _mesa_new_array_object; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functions->DeleteArrayObject = _mesa_delete_array_object; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 407