1
/**************************************************************************
3
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
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.
26
**************************************************************************/
31
#include "bufferobj.h"
33
#include "intel_context.h"
34
#include "intel_buffer_objects.h"
35
#include "intel_regions.h"
36
#include "dri_bufmgr.h"
39
* There is some duplication between mesa's bufferobjects and our
40
* bufmgr buffers. Both have an integer handle and a hashtable to
41
* lookup an opaque structure. It would be nice if the handles and
42
* internal structure where somehow shared.
44
static struct gl_buffer_object *
45
intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target)
47
struct intel_context *intel = intel_context(ctx);
48
struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object);
50
_mesa_initialize_buffer_object(&obj->Base, name, target);
52
driGenBuffers(intel->intelScreen->regionPool,
53
"bufferobj", 1, &obj->buffer, 64, 0, 0);
59
/* Break the COW tie to the region. The region gets to keep the data.
62
intel_bufferobj_release_region(struct intel_context *intel,
63
struct intel_buffer_object *intel_obj)
65
assert(intel_obj->region->buffer == intel_obj->buffer);
66
intel_obj->region->pbo = NULL;
67
intel_obj->region = NULL;
68
driBOUnReference(intel_obj->buffer);
69
intel_obj->buffer = NULL;
71
/* This leads to a large number of buffer deletion/creation events.
72
* Currently the drm doesn't like that:
74
driGenBuffers(intel->intelScreen->regionPool,
75
"buffer object", 1, &intel_obj->buffer, 64, 0, 0);
76
driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0);
79
/* Break the COW tie to the region. Both the pbo and the region end
80
* up with a copy of the data.
83
intel_bufferobj_cow(struct intel_context *intel,
84
struct intel_buffer_object *intel_obj)
86
assert(intel_obj->region);
87
intel_region_cow(intel->intelScreen, intel_obj->region);
92
* Deallocate/free a vertex/pixel buffer object.
93
* Called via glDeleteBuffersARB().
96
intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
98
struct intel_context *intel = intel_context(ctx);
99
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
103
if (intel_obj->region) {
104
intel_bufferobj_release_region(intel, intel_obj);
106
else if (intel_obj->buffer) {
107
driDeleteBuffers(1, &intel_obj->buffer);
110
_mesa_free(intel_obj);
116
* Allocate space for and store data in a buffer object. Any data that was
117
* previously stored in the buffer object is lost. If data is NULL,
118
* memory will be allocated, but no copy will occur.
119
* Called via glBufferDataARB().
122
intel_bufferobj_data(GLcontext * ctx,
126
GLenum usage, struct gl_buffer_object *obj)
128
struct intel_context *intel = intel_context(ctx);
129
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
131
intel_obj->Base.Size = size;
132
intel_obj->Base.Usage = usage;
134
if (intel_obj->region)
135
intel_bufferobj_release_region(intel, intel_obj);
137
driBOData(intel_obj->buffer, size, data, 0);
142
* Replace data in a subrange of buffer object. If the data range
143
* specified by size + offset extends beyond the end of the buffer or
144
* if data is NULL, no copy is performed.
145
* Called via glBufferSubDataARB().
148
intel_bufferobj_subdata(GLcontext * ctx,
152
const GLvoid * data, struct gl_buffer_object *obj)
154
struct intel_context *intel = intel_context(ctx);
155
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
159
if (intel_obj->region)
160
intel_bufferobj_cow(intel, intel_obj);
162
driBOSubData(intel_obj->buffer, offset, size, data);
167
* Called via glGetBufferSubDataARB().
170
intel_bufferobj_get_subdata(GLcontext * ctx,
174
GLvoid * data, struct gl_buffer_object *obj)
176
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
179
driBOGetSubData(intel_obj->buffer, offset, size, data);
185
* Called via glMapBufferARB().
188
intel_bufferobj_map(GLcontext * ctx,
190
GLenum access, struct gl_buffer_object *obj)
192
struct intel_context *intel = intel_context(ctx);
193
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
195
/* XXX: Translate access to flags arg below:
199
if (intel_obj->region)
200
intel_bufferobj_cow(intel, intel_obj);
202
obj->Pointer = driBOMap(intel_obj->buffer,
203
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0);
209
* Called via glMapBufferARB().
212
intel_bufferobj_unmap(GLcontext * ctx,
213
GLenum target, struct gl_buffer_object *obj)
215
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
218
assert(obj->Pointer);
219
driBOUnmap(intel_obj->buffer);
224
struct _DriBufferObject *
225
intel_bufferobj_buffer(struct intel_context *intel,
226
struct intel_buffer_object *intel_obj, GLuint flag)
228
if (intel_obj->region) {
229
if (flag == INTEL_WRITE_PART)
230
intel_bufferobj_cow(intel, intel_obj);
231
else if (flag == INTEL_WRITE_FULL)
232
intel_bufferobj_release_region(intel, intel_obj);
235
return intel_obj->buffer;
239
intel_bufferobj_init(struct intel_context *intel)
241
GLcontext *ctx = &intel->ctx;
243
ctx->Driver.NewBufferObject = intel_bufferobj_alloc;
244
ctx->Driver.DeleteBuffer = intel_bufferobj_free;
245
ctx->Driver.BufferData = intel_bufferobj_data;
246
ctx->Driver.BufferSubData = intel_bufferobj_subdata;
247
ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata;
248
ctx->Driver.MapBuffer = intel_bufferobj_map;
249
ctx->Driver.UnmapBuffer = intel_bufferobj_unmap;