~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/intel_buffer_objects.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2003 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 "imports.h"
 
30
#include "mtypes.h"
 
31
#include "bufferobj.h"
 
32
 
 
33
#include "intel_context.h"
 
34
#include "intel_buffer_objects.h"
 
35
#include "intel_regions.h"
 
36
#include "dri_bufmgr.h"
 
37
 
 
38
/**
 
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.
 
43
 */
 
44
static struct gl_buffer_object *
 
45
intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target)
 
46
{
 
47
   struct intel_context *intel = intel_context(ctx);
 
48
   struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object);
 
49
 
 
50
   _mesa_initialize_buffer_object(&obj->Base, name, target);
 
51
 
 
52
   driGenBuffers(intel->intelScreen->regionPool,
 
53
                 "bufferobj", 1, &obj->buffer, 64, 0, 0);
 
54
 
 
55
   return &obj->Base;
 
56
}
 
57
 
 
58
 
 
59
/* Break the COW tie to the region.  The region gets to keep the data.
 
60
 */
 
61
void
 
62
intel_bufferobj_release_region(struct intel_context *intel,
 
63
                               struct intel_buffer_object *intel_obj)
 
64
{
 
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;
 
70
 
 
71
   /* This leads to a large number of buffer deletion/creation events.
 
72
    * Currently the drm doesn't like that:
 
73
    */
 
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);
 
77
}
 
78
 
 
79
/* Break the COW tie to the region.  Both the pbo and the region end
 
80
 * up with a copy of the data.
 
81
 */
 
82
void
 
83
intel_bufferobj_cow(struct intel_context *intel,
 
84
                    struct intel_buffer_object *intel_obj)
 
85
{
 
86
   assert(intel_obj->region);
 
87
   intel_region_cow(intel->intelScreen, intel_obj->region);
 
88
}
 
89
 
 
90
 
 
91
/**
 
92
 * Deallocate/free a vertex/pixel buffer object.
 
93
 * Called via glDeleteBuffersARB().
 
94
 */
 
95
static void
 
96
intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
 
97
{
 
98
   struct intel_context *intel = intel_context(ctx);
 
99
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
100
 
 
101
   assert(intel_obj);
 
102
 
 
103
   if (intel_obj->region) {
 
104
      intel_bufferobj_release_region(intel, intel_obj);
 
105
   }
 
106
   else if (intel_obj->buffer) {
 
107
      driDeleteBuffers(1, &intel_obj->buffer);
 
108
   }
 
109
 
 
110
   _mesa_free(intel_obj);
 
111
}
 
112
 
 
113
 
 
114
 
 
115
/**
 
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().
 
120
 */
 
121
static void
 
122
intel_bufferobj_data(GLcontext * ctx,
 
123
                     GLenum target,
 
124
                     GLsizeiptrARB size,
 
125
                     const GLvoid * data,
 
126
                     GLenum usage, struct gl_buffer_object *obj)
 
127
{
 
128
   struct intel_context *intel = intel_context(ctx);
 
129
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
130
 
 
131
   intel_obj->Base.Size = size;
 
132
   intel_obj->Base.Usage = usage;
 
133
 
 
134
   if (intel_obj->region)
 
135
      intel_bufferobj_release_region(intel, intel_obj);
 
136
 
 
137
   driBOData(intel_obj->buffer, size, data, 0);
 
138
}
 
139
 
 
140
 
 
141
/**
 
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().
 
146
 */
 
147
static void
 
148
intel_bufferobj_subdata(GLcontext * ctx,
 
149
                        GLenum target,
 
150
                        GLintptrARB offset,
 
151
                        GLsizeiptrARB size,
 
152
                        const GLvoid * data, struct gl_buffer_object *obj)
 
153
{
 
154
   struct intel_context *intel = intel_context(ctx);
 
155
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
156
 
 
157
   assert(intel_obj);
 
158
 
 
159
   if (intel_obj->region)
 
160
      intel_bufferobj_cow(intel, intel_obj);
 
161
 
 
162
   driBOSubData(intel_obj->buffer, offset, size, data);
 
163
}
 
164
 
 
165
 
 
166
/**
 
167
 * Called via glGetBufferSubDataARB().
 
168
 */
 
169
static void
 
170
intel_bufferobj_get_subdata(GLcontext * ctx,
 
171
                            GLenum target,
 
172
                            GLintptrARB offset,
 
173
                            GLsizeiptrARB size,
 
174
                            GLvoid * data, struct gl_buffer_object *obj)
 
175
{
 
176
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
177
 
 
178
   assert(intel_obj);
 
179
   driBOGetSubData(intel_obj->buffer, offset, size, data);
 
180
}
 
181
 
 
182
 
 
183
 
 
184
/**
 
185
 * Called via glMapBufferARB().
 
186
 */
 
187
static void *
 
188
intel_bufferobj_map(GLcontext * ctx,
 
189
                    GLenum target,
 
190
                    GLenum access, struct gl_buffer_object *obj)
 
191
{
 
192
   struct intel_context *intel = intel_context(ctx);
 
193
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
194
 
 
195
   /* XXX: Translate access to flags arg below:
 
196
    */
 
197
   assert(intel_obj);
 
198
 
 
199
   if (intel_obj->region)
 
200
      intel_bufferobj_cow(intel, intel_obj);
 
201
 
 
202
   obj->Pointer = driBOMap(intel_obj->buffer,
 
203
                           DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0);
 
204
   return obj->Pointer;
 
205
}
 
206
 
 
207
 
 
208
/**
 
209
 * Called via glMapBufferARB().
 
210
 */
 
211
static GLboolean
 
212
intel_bufferobj_unmap(GLcontext * ctx,
 
213
                      GLenum target, struct gl_buffer_object *obj)
 
214
{
 
215
   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
216
 
 
217
   assert(intel_obj);
 
218
   assert(obj->Pointer);
 
219
   driBOUnmap(intel_obj->buffer);
 
220
   obj->Pointer = NULL;
 
221
   return GL_TRUE;
 
222
}
 
223
 
 
224
struct _DriBufferObject *
 
225
intel_bufferobj_buffer(struct intel_context *intel,
 
226
                       struct intel_buffer_object *intel_obj, GLuint flag)
 
227
{
 
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);
 
233
   }
 
234
 
 
235
   return intel_obj->buffer;
 
236
}
 
237
 
 
238
void
 
239
intel_bufferobj_init(struct intel_context *intel)
 
240
{
 
241
   GLcontext *ctx = &intel->ctx;
 
242
 
 
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;
 
250
}