~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/softpipe/sp_texture.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include "util/u_format.h"
37
37
#include "util/u_math.h"
38
38
#include "util/u_memory.h"
 
39
#include "util/u_transfer.h"
39
40
 
40
41
#include "sp_context.h"
 
42
#include "sp_flush.h"
41
43
#include "sp_texture.h"
42
44
#include "sp_screen.h"
43
 
#include "sp_winsys.h"
 
45
 
 
46
#include "state_tracker/sw_winsys.h"
44
47
 
45
48
 
46
49
/**
48
51
 * Use a simple, maximally packed layout.
49
52
 */
50
53
static boolean
51
 
softpipe_texture_layout(struct pipe_screen *screen,
52
 
                        struct softpipe_texture * spt)
 
54
softpipe_resource_layout(struct pipe_screen *screen,
 
55
                         struct softpipe_resource *spr)
53
56
{
54
 
   struct pipe_texture *pt = &spt->base;
 
57
   struct pipe_resource *pt = &spr->base;
55
58
   unsigned level;
56
59
   unsigned width = pt->width0;
57
60
   unsigned height = pt->height0;
59
62
   unsigned buffer_size = 0;
60
63
 
61
64
   for (level = 0; level <= pt->last_level; level++) {
62
 
      spt->stride[level] = util_format_get_stride(pt->format, width);
 
65
      spr->stride[level] = util_format_get_stride(pt->format, width);
63
66
 
64
 
      spt->level_offset[level] = buffer_size;
 
67
      spr->level_offset[level] = buffer_size;
65
68
 
66
69
      buffer_size += (util_format_get_nblocksy(pt->format, height) *
67
70
                      ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
68
 
                      spt->stride[level]);
 
71
                      spr->stride[level]);
69
72
 
70
73
      width  = u_minify(width, 1);
71
74
      height = u_minify(height, 1);
72
75
      depth = u_minify(depth, 1);
73
76
   }
74
77
 
75
 
   spt->buffer = screen->buffer_create(screen, 32,
76
 
                                       PIPE_BUFFER_USAGE_PIXEL,
77
 
                                       buffer_size);
 
78
   spr->data = align_malloc(buffer_size, 16);
78
79
 
79
 
   return spt->buffer != NULL;
 
80
   return spr->data != NULL;
80
81
}
81
82
 
82
83
 
85
86
 */
86
87
static boolean
87
88
softpipe_displaytarget_layout(struct pipe_screen *screen,
88
 
                              struct softpipe_texture * spt)
 
89
                              struct softpipe_resource *spr)
89
90
{
90
 
   unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
91
 
                     PIPE_BUFFER_USAGE_GPU_READ_WRITE);
92
 
   unsigned tex_usage = spt->base.tex_usage;
93
 
 
94
 
   spt->buffer = screen->surface_buffer_create( screen, 
95
 
                                                spt->base.width0, 
96
 
                                                spt->base.height0,
97
 
                                                spt->base.format,
98
 
                                                usage,
99
 
                                                tex_usage,
100
 
                                                &spt->stride[0]);
101
 
 
102
 
   return spt->buffer != NULL;
 
91
   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
 
92
 
 
93
   /* Round up the surface size to a multiple of the tile size?
 
94
    */
 
95
   spr->dt = winsys->displaytarget_create(winsys,
 
96
                                          spr->base.bind,
 
97
                                          spr->base.format,
 
98
                                          spr->base.width0, 
 
99
                                          spr->base.height0,
 
100
                                          16,
 
101
                                          &spr->stride[0] );
 
102
 
 
103
   return spr->dt != NULL;
103
104
}
104
105
 
105
106
 
106
107
/**
107
 
 * Create new pipe_texture given the template information.
 
108
 * Create new pipe_resource given the template information.
108
109
 */
109
 
static struct pipe_texture *
110
 
softpipe_texture_create(struct pipe_screen *screen,
111
 
                        const struct pipe_texture *template)
 
110
static struct pipe_resource *
 
111
softpipe_resource_create(struct pipe_screen *screen,
 
112
                         const struct pipe_resource *templat)
112
113
{
113
 
   struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
114
 
   if (!spt)
 
114
   struct softpipe_resource *spr = CALLOC_STRUCT(softpipe_resource);
 
115
   if (!spr)
115
116
      return NULL;
116
117
 
117
 
   spt->base = *template;
118
 
   pipe_reference_init(&spt->base.reference, 1);
119
 
   spt->base.screen = screen;
120
 
 
121
 
   spt->pot = (util_is_power_of_two(template->width0) &&
122
 
               util_is_power_of_two(template->height0) &&
123
 
               util_is_power_of_two(template->depth0));
124
 
 
125
 
   if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
126
 
                              PIPE_TEXTURE_USAGE_PRIMARY)) {
127
 
      if (!softpipe_displaytarget_layout(screen, spt))
 
118
   assert(templat->format != PIPE_FORMAT_NONE);
 
119
 
 
120
   spr->base = *templat;
 
121
   pipe_reference_init(&spr->base.reference, 1);
 
122
   spr->base.screen = screen;
 
123
 
 
124
   spr->pot = (util_is_power_of_two(templat->width0) &&
 
125
               util_is_power_of_two(templat->height0) &&
 
126
               util_is_power_of_two(templat->depth0));
 
127
 
 
128
   if (spr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
 
129
                         PIPE_BIND_SCANOUT |
 
130
                         PIPE_BIND_SHARED)) {
 
131
      if (!softpipe_displaytarget_layout(screen, spr))
128
132
         goto fail;
129
133
   }
130
134
   else {
131
 
      if (!softpipe_texture_layout(screen, spt))
 
135
      if (!softpipe_resource_layout(screen, spr))
132
136
         goto fail;
133
137
   }
134
138
    
135
 
   return &spt->base;
 
139
   return &spr->base;
136
140
 
137
141
 fail:
138
 
   FREE(spt);
 
142
   FREE(spr);
139
143
   return NULL;
140
144
}
141
145
 
142
146
 
143
 
/**
144
 
 * Create a new pipe_texture which wraps an existing buffer.
145
 
 */
146
 
static struct pipe_texture *
147
 
softpipe_texture_blanket(struct pipe_screen * screen,
148
 
                         const struct pipe_texture *base,
149
 
                         const unsigned *stride,
150
 
                         struct pipe_buffer *buffer)
151
 
{
152
 
   struct softpipe_texture *spt;
153
 
   assert(screen);
154
 
 
155
 
   /* Only supports one type */
156
 
   if (base->target != PIPE_TEXTURE_2D ||
157
 
       base->last_level != 0 ||
158
 
       base->depth0 != 1) {
159
 
      return NULL;
160
 
   }
161
 
 
162
 
   spt = CALLOC_STRUCT(softpipe_texture);
163
 
   if (!spt)
164
 
      return NULL;
165
 
 
166
 
   spt->base = *base;
167
 
   pipe_reference_init(&spt->base.reference, 1);
168
 
   spt->base.screen = screen;
169
 
   spt->stride[0] = stride[0];
170
 
 
171
 
   pipe_buffer_reference(&spt->buffer, buffer);
172
 
 
173
 
   return &spt->base;
174
 
}
175
 
 
176
 
 
177
147
static void
178
 
softpipe_texture_destroy(struct pipe_texture *pt)
179
 
{
180
 
   struct softpipe_texture *spt = softpipe_texture(pt);
181
 
 
182
 
   pipe_buffer_reference(&spt->buffer, NULL);
183
 
   FREE(spt);
184
 
}
185
 
 
186
 
 
187
 
/**
188
 
 * Get a pipe_surface "view" into a texture.
 
148
softpipe_resource_destroy(struct pipe_screen *pscreen,
 
149
                          struct pipe_resource *pt)
 
150
{
 
151
   struct softpipe_screen *screen = softpipe_screen(pscreen);
 
152
   struct softpipe_resource *spr = softpipe_resource(pt);
 
153
 
 
154
   if (spr->dt) {
 
155
      /* display target */
 
156
      struct sw_winsys *winsys = screen->winsys;
 
157
      winsys->displaytarget_destroy(winsys, spr->dt);
 
158
   }
 
159
   else if (!spr->userBuffer) {
 
160
      /* regular texture */
 
161
      align_free(spr->data);
 
162
   }
 
163
 
 
164
   FREE(spr);
 
165
}
 
166
 
 
167
 
 
168
static struct pipe_resource *
 
169
softpipe_resource_from_handle(struct pipe_screen *screen,
 
170
                              const struct pipe_resource *templat,
 
171
                              struct winsys_handle *whandle)
 
172
{
 
173
   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
 
174
   struct softpipe_resource *spr = CALLOC_STRUCT(softpipe_resource);
 
175
   if (!spr)
 
176
      return NULL;
 
177
 
 
178
   spr->base = *templat;
 
179
   pipe_reference_init(&spr->base.reference, 1);
 
180
   spr->base.screen = screen;
 
181
 
 
182
   spr->pot = (util_is_power_of_two(templat->width0) &&
 
183
               util_is_power_of_two(templat->height0) &&
 
184
               util_is_power_of_two(templat->depth0));
 
185
 
 
186
   spr->dt = winsys->displaytarget_from_handle(winsys,
 
187
                                               templat,
 
188
                                               whandle,
 
189
                                               &spr->stride[0]);
 
190
   if (!spr->dt)
 
191
      goto fail;
 
192
 
 
193
   return &spr->base;
 
194
 
 
195
 fail:
 
196
   FREE(spr);
 
197
   return NULL;
 
198
}
 
199
 
 
200
 
 
201
static boolean
 
202
softpipe_resource_get_handle(struct pipe_screen *screen,
 
203
                             struct pipe_resource *pt,
 
204
                             struct winsys_handle *whandle)
 
205
{
 
206
   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
 
207
   struct softpipe_resource *spr = softpipe_resource(pt);
 
208
 
 
209
   assert(spr->dt);
 
210
   if (!spr->dt)
 
211
      return FALSE;
 
212
 
 
213
   return winsys->displaytarget_get_handle(winsys, spr->dt, whandle);
 
214
}
 
215
 
 
216
 
 
217
/**
 
218
 * Helper function to compute offset (in bytes) for a particular
 
219
 * texture level/face/slice from the start of the buffer.
 
220
 */
 
221
static unsigned
 
222
sp_get_tex_image_offset(const struct softpipe_resource *spr,
 
223
                        unsigned level, unsigned face, unsigned zslice)
 
224
{
 
225
   const unsigned hgt = u_minify(spr->base.height0, level);
 
226
   const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
 
227
   unsigned offset = spr->level_offset[level];
 
228
 
 
229
   if (spr->base.target == PIPE_TEXTURE_CUBE) {
 
230
      assert(zslice == 0);
 
231
      offset += face * nblocksy * spr->stride[level];
 
232
   }
 
233
   else if (spr->base.target == PIPE_TEXTURE_3D) {
 
234
      assert(face == 0);
 
235
      offset += zslice * nblocksy * spr->stride[level];
 
236
   }
 
237
   else {
 
238
      assert(face == 0);
 
239
      assert(zslice == 0);
 
240
   }
 
241
 
 
242
   return offset;
 
243
}
 
244
 
 
245
 
 
246
/**
 
247
 * Get a pipe_surface "view" into a texture resource.
189
248
 */
190
249
static struct pipe_surface *
191
250
softpipe_get_tex_surface(struct pipe_screen *screen,
192
 
                         struct pipe_texture *pt,
 
251
                         struct pipe_resource *pt,
193
252
                         unsigned face, unsigned level, unsigned zslice,
194
253
                         unsigned usage)
195
254
{
196
 
   struct softpipe_texture *spt = softpipe_texture(pt);
 
255
   struct softpipe_resource *spr = softpipe_resource(pt);
197
256
   struct pipe_surface *ps;
198
257
 
199
258
   assert(level <= pt->last_level);
201
260
   ps = CALLOC_STRUCT(pipe_surface);
202
261
   if (ps) {
203
262
      pipe_reference_init(&ps->reference, 1);
204
 
      pipe_texture_reference(&ps->texture, pt);
 
263
      pipe_resource_reference(&ps->texture, pt);
205
264
      ps->format = pt->format;
206
265
      ps->width = u_minify(pt->width0, level);
207
266
      ps->height = u_minify(pt->height0, level);
208
 
      ps->offset = spt->level_offset[level];
 
267
      ps->offset = sp_get_tex_image_offset(spr, level, face, zslice);
209
268
      ps->usage = usage;
210
269
 
211
 
      /* Because we are softpipe, anything that the state tracker
212
 
       * thought was going to be done with the GPU will actually get
213
 
       * done with the CPU.  Let's adjust the flags to take that into
214
 
       * account.
215
 
       */
216
 
      if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
217
 
         /* GPU_WRITE means "render" and that can involve reads (blending) */
218
 
         ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ;
219
 
      }
220
 
 
221
 
      if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
222
 
         ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
223
 
 
224
 
      if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
225
 
                       PIPE_BUFFER_USAGE_GPU_WRITE)) {
226
 
         /* Mark the surface as dirty.  The tile cache will look for this. */
227
 
         spt->timestamp++;
228
 
         softpipe_screen(screen)->timestamp++;
229
 
      }
230
 
 
231
270
      ps->face = face;
232
271
      ps->level = level;
233
272
      ps->zslice = zslice;
234
 
 
235
 
      if (pt->target == PIPE_TEXTURE_CUBE) {
236
 
         ps->offset += face * util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)) *
237
 
                       spt->stride[level];
238
 
      }
239
 
      else if (pt->target == PIPE_TEXTURE_3D) {
240
 
         ps->offset += zslice * util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)) *
241
 
                       spt->stride[level];
242
 
      }
243
 
      else {
244
 
         assert(face == 0);
245
 
         assert(zslice == 0);
246
 
      }
247
273
   }
248
274
   return ps;
249
275
}
260
286
    * where it would happen.  For softpipe, nothing to do.
261
287
    */
262
288
   assert(surf->texture);
263
 
   pipe_texture_reference(&surf->texture, NULL);
 
289
   pipe_resource_reference(&surf->texture, NULL);
264
290
   FREE(surf);
265
291
}
266
292
 
267
293
 
268
294
/**
269
295
 * Geta pipe_transfer object which is used for moving data in/out of
270
 
 * a texture object.
271
 
 * \param face  one of PIPE_TEX_FACE_x or 0
272
 
 * \param level  texture mipmap level
273
 
 * \param zslice  2D slice of a 3D texture
274
 
 * \param usage  one of PIPE_TRANSFER_READ/WRITE/READ_WRITE
275
 
 * \param x  X position of region to read/write
276
 
 * \param y  Y position of region to read/write
277
 
 * \param width  width of region to read/write
278
 
 * \param height  height of region to read/write
 
296
 * a resource object.
 
297
 * \param pipe  rendering context
 
298
 * \param resource  the resource to transfer in/out of
 
299
 * \param sr  indicates cube face or 3D texture slice
 
300
 * \param usage  bitmask of PIPE_TRANSFER_x flags
 
301
 * \param box  the 1D/2D/3D region of interest
279
302
 */
280
303
static struct pipe_transfer *
281
 
softpipe_get_tex_transfer(struct pipe_screen *screen,
282
 
                          struct pipe_texture *texture,
283
 
                          unsigned face, unsigned level, unsigned zslice,
284
 
                          enum pipe_transfer_usage usage,
285
 
                          unsigned x, unsigned y, unsigned w, unsigned h)
 
304
softpipe_get_transfer(struct pipe_context *pipe,
 
305
                      struct pipe_resource *resource,
 
306
                      struct pipe_subresource sr,
 
307
                      unsigned usage,
 
308
                      const struct pipe_box *box)
286
309
{
287
 
   struct softpipe_texture *sptex = softpipe_texture(texture);
 
310
   struct softpipe_resource *spr = softpipe_resource(resource);
288
311
   struct softpipe_transfer *spt;
289
312
 
290
 
   assert(texture);
291
 
   assert(level <= texture->last_level);
 
313
   assert(resource);
 
314
   assert(sr.level <= resource->last_level);
292
315
 
293
316
   /* make sure the requested region is in the image bounds */
294
 
   assert(x + w <= u_minify(texture->width0, level));
295
 
   assert(y + h <= u_minify(texture->height0, level));
 
317
   assert(box->x + box->width <= u_minify(resource->width0, sr.level));
 
318
   assert(box->y + box->height <= u_minify(resource->height0, sr.level));
 
319
   assert(box->z + box->depth <= u_minify(resource->depth0, sr.level));
 
320
 
 
321
   /*
 
322
    * Transfers, like other pipe operations, must happen in order, so flush the
 
323
    * context if necessary.
 
324
    */
 
325
   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
 
326
      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
 
327
      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
 
328
      if (!softpipe_flush_resource(pipe, resource,
 
329
                                   sr.face, sr.level,
 
330
                                   0, /* flush_flags */
 
331
                                   read_only,
 
332
                                   TRUE, /* cpu_access */
 
333
                                   do_not_block)) {
 
334
         /*
 
335
          * It would have blocked, but state tracker requested no to.
 
336
          */
 
337
         assert(do_not_block);
 
338
         return NULL;
 
339
      }
 
340
   }
296
341
 
297
342
   spt = CALLOC_STRUCT(softpipe_transfer);
298
343
   if (spt) {
299
344
      struct pipe_transfer *pt = &spt->base;
300
 
      int nblocksy = util_format_get_nblocksy(texture->format, u_minify(texture->height0, level));
301
 
      pipe_texture_reference(&pt->texture, texture);
302
 
      pt->x = x;
303
 
      pt->y = y;
304
 
      pt->width = w;
305
 
      pt->height = h;
306
 
      pt->stride = sptex->stride[level];
 
345
      enum pipe_format format = resource->format;
 
346
      const unsigned hgt = u_minify(spr->base.height0, sr.level);
 
347
      const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
 
348
 
 
349
      pipe_resource_reference(&pt->resource, resource);
 
350
      pt->sr = sr;
307
351
      pt->usage = usage;
308
 
      pt->face = face;
309
 
      pt->level = level;
310
 
      pt->zslice = zslice;
311
 
 
312
 
      spt->offset = sptex->level_offset[level];
313
 
 
314
 
      if (texture->target == PIPE_TEXTURE_CUBE) {
315
 
         spt->offset += face * nblocksy * pt->stride;
316
 
      }
317
 
      else if (texture->target == PIPE_TEXTURE_3D) {
318
 
         spt->offset += zslice * nblocksy * pt->stride;
319
 
      }
320
 
      else {
321
 
         assert(face == 0);
322
 
         assert(zslice == 0);
323
 
      }
 
352
      pt->box = *box;
 
353
      pt->stride = spr->stride[sr.level];
 
354
      pt->slice_stride = pt->stride * nblocksy;
 
355
 
 
356
      spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z);
 
357
 
 
358
      spt->offset += 
 
359
         box->y / util_format_get_blockheight(format) * spt->base.stride +
 
360
         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
 
361
 
324
362
      return pt;
325
363
   }
326
364
   return NULL;
329
367
 
330
368
/**
331
369
 * Free a pipe_transfer object which was created with
332
 
 * softpipe_get_tex_transfer().
 
370
 * softpipe_get_transfer().
333
371
 */
334
372
static void 
335
 
softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
 
373
softpipe_transfer_destroy(struct pipe_context *pipe,
 
374
                          struct pipe_transfer *transfer)
336
375
{
337
 
   /* Effectively do the texture_update work here - if texture images
338
 
    * needed post-processing to put them into hardware layout, this is
339
 
    * where it would happen.  For softpipe, nothing to do.
340
 
    */
341
 
   assert (transfer->texture);
342
 
   pipe_texture_reference(&transfer->texture, NULL);
 
376
   pipe_resource_reference(&transfer->resource, NULL);
343
377
   FREE(transfer);
344
378
}
345
379
 
348
382
 * Create memory mapping for given pipe_transfer object.
349
383
 */
350
384
static void *
351
 
softpipe_transfer_map( struct pipe_screen *screen,
352
 
                       struct pipe_transfer *transfer )
 
385
softpipe_transfer_map(struct pipe_context *pipe,
 
386
                      struct pipe_transfer *transfer)
353
387
{
354
 
   ubyte *map, *xfer_map;
355
 
   struct softpipe_texture *spt;
356
 
   enum pipe_format format;
357
 
 
358
 
   assert(transfer->texture);
359
 
   spt = softpipe_texture(transfer->texture);
360
 
   format = transfer->texture->format;
361
 
 
362
 
   map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
 
388
   struct softpipe_transfer *spt = softpipe_transfer(transfer);
 
389
   struct softpipe_resource *spr = softpipe_resource(transfer->resource);
 
390
   struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
 
391
   uint8_t *map;
 
392
   
 
393
   /* resources backed by display target treated specially:
 
394
    */
 
395
   if (spr->dt) {
 
396
      map = winsys->displaytarget_map(winsys, spr->dt, transfer->usage);
 
397
   }
 
398
   else {
 
399
      map = spr->data;
 
400
   }
 
401
 
363
402
   if (map == NULL)
364
403
      return NULL;
365
 
 
366
 
   /* May want to different things here depending on read/write nature
367
 
    * of the map:
368
 
    */
369
 
   if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
370
 
      /* Do something to notify sharing contexts of a texture change.
371
 
       * In softpipe, that would mean flushing the texture cache.
372
 
       */
373
 
      softpipe_screen(screen)->timestamp++;
374
 
   }
375
 
 
376
 
   xfer_map = map + softpipe_transfer(transfer)->offset +
377
 
      transfer->y / util_format_get_blockheight(format) * transfer->stride +
378
 
      transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
379
 
   /*printf("map = %p  xfer map = %p\n", map, xfer_map);*/
380
 
   return xfer_map;
 
404
   else
 
405
      return map + spt->offset;
381
406
}
382
407
 
383
408
 
385
410
 * Unmap memory mapping for given pipe_transfer object.
386
411
 */
387
412
static void
388
 
softpipe_transfer_unmap(struct pipe_screen *screen,
 
413
softpipe_transfer_unmap(struct pipe_context *pipe,
389
414
                        struct pipe_transfer *transfer)
390
415
{
391
 
   struct softpipe_texture *spt;
392
 
 
393
 
   assert(transfer->texture);
394
 
   spt = softpipe_texture(transfer->texture);
395
 
 
396
 
   pipe_buffer_unmap( screen, spt->buffer );
 
416
   struct softpipe_resource *spr;
 
417
 
 
418
   assert(transfer->resource);
 
419
   spr = softpipe_resource(transfer->resource);
 
420
 
 
421
   if (spr->dt) {
 
422
      /* display target */
 
423
      struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
 
424
      winsys->displaytarget_unmap(winsys, spr->dt);
 
425
   }
397
426
 
398
427
   if (transfer->usage & PIPE_TRANSFER_WRITE) {
399
428
      /* Mark the texture as dirty to expire the tile caches. */
400
 
      spt->timestamp++;
401
 
   }
402
 
}
403
 
 
404
 
 
405
 
static struct pipe_video_surface*
406
 
softpipe_video_surface_create(struct pipe_screen *screen,
407
 
                              enum pipe_video_chroma_format chroma_format,
408
 
                              unsigned width, unsigned height)
409
 
{
410
 
   struct softpipe_video_surface *sp_vsfc;
411
 
   struct pipe_texture template;
412
 
 
413
 
   assert(screen);
414
 
   assert(width && height);
415
 
 
416
 
   sp_vsfc = CALLOC_STRUCT(softpipe_video_surface);
417
 
   if (!sp_vsfc)
418
 
      return NULL;
419
 
 
420
 
   pipe_reference_init(&sp_vsfc->base.reference, 1);
421
 
   sp_vsfc->base.screen = screen;
422
 
   sp_vsfc->base.chroma_format = chroma_format;
423
 
   /*sp_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/
424
 
   sp_vsfc->base.width = width;
425
 
   sp_vsfc->base.height = height;
426
 
 
427
 
   memset(&template, 0, sizeof(struct pipe_texture));
428
 
   template.target = PIPE_TEXTURE_2D;
429
 
   template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
430
 
   template.last_level = 0;
431
 
   /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */
432
 
   template.width0 = util_next_power_of_two(width);
433
 
   template.height0 = util_next_power_of_two(height);
434
 
   template.depth0 = 1;
435
 
   template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET;
436
 
 
437
 
   sp_vsfc->tex = screen->texture_create(screen, &template);
438
 
   if (!sp_vsfc->tex) {
439
 
      FREE(sp_vsfc);
440
 
      return NULL;
441
 
   }
442
 
 
443
 
   return &sp_vsfc->base;
444
 
}
445
 
 
446
 
 
447
 
static void
448
 
softpipe_video_surface_destroy(struct pipe_video_surface *vsfc)
449
 
{
450
 
   struct softpipe_video_surface *sp_vsfc = softpipe_video_surface(vsfc);
451
 
 
452
 
   pipe_texture_reference(&sp_vsfc->tex, NULL);
453
 
   FREE(sp_vsfc);
 
429
      spr->timestamp++;
 
430
   }
 
431
}
 
432
 
 
433
/**
 
434
 * Create buffer which wraps user-space data.
 
435
 */
 
436
static struct pipe_resource *
 
437
softpipe_user_buffer_create(struct pipe_screen *screen,
 
438
                            void *ptr,
 
439
                            unsigned bytes,
 
440
                            unsigned bind_flags)
 
441
{
 
442
   struct softpipe_resource *spr;
 
443
 
 
444
   spr = CALLOC_STRUCT(softpipe_resource);
 
445
   if (!spr)
 
446
      return NULL;
 
447
 
 
448
   pipe_reference_init(&spr->base.reference, 1);
 
449
   spr->base.screen = screen;
 
450
   spr->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
 
451
   spr->base.bind = bind_flags;
 
452
   spr->base.usage = PIPE_USAGE_IMMUTABLE;
 
453
   spr->base.flags = 0;
 
454
   spr->base.width0 = bytes;
 
455
   spr->base.height0 = 1;
 
456
   spr->base.depth0 = 1;
 
457
   spr->userBuffer = TRUE;
 
458
   spr->data = ptr;
 
459
 
 
460
   return &spr->base;
 
461
}
 
462
 
 
463
 
 
464
void
 
465
softpipe_init_texture_funcs(struct pipe_context *pipe)
 
466
{
 
467
   pipe->get_transfer = softpipe_get_transfer;
 
468
   pipe->transfer_destroy = softpipe_transfer_destroy;
 
469
   pipe->transfer_map = softpipe_transfer_map;
 
470
   pipe->transfer_unmap = softpipe_transfer_unmap;
 
471
 
 
472
   pipe->transfer_flush_region = u_default_transfer_flush_region;
 
473
   pipe->transfer_inline_write = u_default_transfer_inline_write;
454
474
}
455
475
 
456
476
 
457
477
void
458
478
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
459
479
{
460
 
   screen->texture_create = softpipe_texture_create;
461
 
   screen->texture_blanket = softpipe_texture_blanket;
462
 
   screen->texture_destroy = softpipe_texture_destroy;
 
480
   screen->resource_create = softpipe_resource_create;
 
481
   screen->resource_destroy = softpipe_resource_destroy;
 
482
   screen->resource_from_handle = softpipe_resource_from_handle;
 
483
   screen->resource_get_handle = softpipe_resource_get_handle;
 
484
   screen->user_buffer_create = softpipe_user_buffer_create;
463
485
 
464
486
   screen->get_tex_surface = softpipe_get_tex_surface;
465
487
   screen->tex_surface_destroy = softpipe_tex_surface_destroy;
466
 
 
467
 
   screen->get_tex_transfer = softpipe_get_tex_transfer;
468
 
   screen->tex_transfer_destroy = softpipe_tex_transfer_destroy;
469
 
   screen->transfer_map = softpipe_transfer_map;
470
 
   screen->transfer_unmap = softpipe_transfer_unmap;
471
 
 
472
 
   screen->video_surface_create = softpipe_video_surface_create;
473
 
   screen->video_surface_destroy = softpipe_video_surface_destroy;
474
 
}
475
 
 
476
 
 
477
 
/**
478
 
 * Return pipe_buffer handle and stride for given texture object.
479
 
 * XXX used for???
480
 
 */
481
 
boolean
482
 
softpipe_get_texture_buffer( struct pipe_texture *texture,
483
 
                             struct pipe_buffer **buf,
484
 
                             unsigned *stride )
485
 
{
486
 
   struct softpipe_texture *tex = (struct softpipe_texture *) texture;
487
 
 
488
 
   if (!tex)
489
 
      return FALSE;
490
 
 
491
 
   pipe_buffer_reference(buf, tex->buffer);
492
 
 
493
 
   if (stride)
494
 
      *stride = tex->stride[0];
495
 
 
496
 
   return TRUE;
497
488
}