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