1/**************************************************************************
2 *
3 * Copyright 2006 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  * Authors:
29  *   Keith Whitwell <keith@tungstengraphics.com>
30  *   Michel Dänzer <michel@tungstengraphics.com>
31  */
32
33#include <stdio.h>
34
35#include "pipe/p_context.h"
36#include "pipe/p_defines.h"
37
38#include "util/u_inlines.h"
39#include "util/u_cpu_detect.h"
40#include "util/u_format.h"
41#include "util/u_math.h"
42#include "util/u_memory.h"
43#include "util/u_simple_list.h"
44#include "util/u_transfer.h"
45
46#include "lp_context.h"
47#include "lp_flush.h"
48#include "lp_screen.h"
49#include "lp_tile_image.h"
50#include "lp_texture.h"
51#include "lp_setup.h"
52#include "lp_state.h"
53
54#include "state_tracker/sw_winsys.h"
55
56
57#ifdef DEBUG
58static struct llvmpipe_resource resource_list;
59#endif
60static unsigned id_counter = 0;
61
62
63static INLINE boolean
64resource_is_texture(const struct pipe_resource *resource)
65{
66   switch (resource->target) {
67   case PIPE_BUFFER:
68      return FALSE;
69   case PIPE_TEXTURE_1D:
70   case PIPE_TEXTURE_2D:
71   case PIPE_TEXTURE_RECT:
72   case PIPE_TEXTURE_3D:
73   case PIPE_TEXTURE_CUBE:
74      return TRUE;
75   default:
76      assert(0);
77      return FALSE;
78   }
79}
80
81
82
83/**
84 * Allocate storage for llvmpipe_texture::layout array.
85 * The number of elements is width_in_tiles * height_in_tiles.
86 */
87static enum lp_texture_layout *
88alloc_layout_array(unsigned num_slices, unsigned width, unsigned height)
89{
90   const unsigned tx = align(width, TILE_SIZE) / TILE_SIZE;
91   const unsigned ty = align(height, TILE_SIZE) / TILE_SIZE;
92
93   assert(num_slices * tx * ty > 0);
94   assert(LP_TEX_LAYOUT_NONE == 0); /* calloc'ing LP_TEX_LAYOUT_NONE here */
95
96   return (enum lp_texture_layout *)
97      CALLOC(num_slices * tx * ty, sizeof(enum lp_texture_layout));
98}
99
100
101
102/**
103 * Conventional allocation path for non-display textures:
104 * Just compute row strides here.  Storage is allocated on demand later.
105 */
106static boolean
107llvmpipe_texture_layout(struct llvmpipe_screen *screen,
108                        struct llvmpipe_resource *lpr)
109{
110   struct pipe_resource *pt = &lpr->base;
111   unsigned level;
112   unsigned width = pt->width0;
113   unsigned height = pt->height0;
114   unsigned depth = pt->depth0;
115   size_t total_size = 0;
116
117   assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
118   assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
119
120   for (level = 0; level <= pt->last_level; level++) {
121
122      /* Row stride and image stride (for linear layout) */
123      {
124         unsigned alignment, nblocksx, nblocksy, block_size;
125
126         /* For non-compressed formats we need to align the texture size
127          * to the tile size to facilitate render-to-texture.
128          */
129         if (util_format_is_compressed(pt->format))
130            alignment = 1;
131         else
132            alignment = TILE_SIZE;
133
134         nblocksx = util_format_get_nblocksx(pt->format,
135                                             align(width, alignment));
136         nblocksy = util_format_get_nblocksy(pt->format,
137                                             align(height, alignment));
138         block_size = util_format_get_blocksize(pt->format);
139
140         lpr->row_stride[level] = align(nblocksx * block_size, 16);
141
142         lpr->img_stride[level] = lpr->row_stride[level] * nblocksy;
143      }
144
145      /* Size of the image in tiles (for tiled layout) */
146      {
147         const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
148         const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
149         lpr->tiles_per_row[level] = width_t;
150         lpr->tiles_per_image[level] = width_t * height_t;
151      }
152
153      /* Number of 3D image slices or cube faces */
154      {
155         unsigned num_slices;
156
157         if (lpr->base.target == PIPE_TEXTURE_CUBE)
158            num_slices = 6;
159         else if (lpr->base.target == PIPE_TEXTURE_3D)
160            num_slices = depth;
161         else
162            num_slices = 1;
163
164         lpr->num_slices_faces[level] = num_slices;
165
166         lpr->layout[level] = alloc_layout_array(num_slices, width, height);
167         if (!lpr->layout[level]) {
168            goto fail;
169         }
170      }
171
172      total_size += lpr->num_slices_faces[level] * lpr->img_stride[level];
173      if (total_size > LP_MAX_TEXTURE_SIZE) {
174         goto fail;
175      }
176
177      /* Compute size of next mipmap level */
178      width = u_minify(width, 1);
179      height = u_minify(height, 1);
180      depth = u_minify(depth, 1);
181   }
182
183   return TRUE;
184
185fail:
186   for (level = 0; level <= pt->last_level; level++) {
187      if (lpr->layout[level]) {
188         FREE(lpr->layout[level]);
189      }
190   }
191
192   return FALSE;
193}
194
195
196
197static boolean
198llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
199                              struct llvmpipe_resource *lpr)
200{
201   struct sw_winsys *winsys = screen->winsys;
202
203   /* Round up the surface size to a multiple of the tile size to
204    * avoid tile clipping.
205    */
206   const unsigned width = align(lpr->base.width0, TILE_SIZE);
207   const unsigned height = align(lpr->base.height0, TILE_SIZE);
208   const unsigned width_t = width / TILE_SIZE;
209   const unsigned height_t = height / TILE_SIZE;
210
211   lpr->tiles_per_row[0] = width_t;
212   lpr->tiles_per_image[0] = width_t * height_t;
213   lpr->num_slices_faces[0] = 1;
214   lpr->img_stride[0] = 0;
215
216   lpr->layout[0] = alloc_layout_array(1, width, height);
217   if (!lpr->layout[0]) {
218      return FALSE;
219   }
220
221   lpr->dt = winsys->displaytarget_create(winsys,
222                                          lpr->base.bind,
223                                          lpr->base.format,
224                                          width, height,
225                                          16,
226                                          &lpr->row_stride[0] );
227
228   if (lpr->dt == NULL)
229      return FALSE;
230
231   {
232      void *map = winsys->displaytarget_map(winsys, lpr->dt,
233                                            PIPE_TRANSFER_WRITE);
234
235      if (map)
236         memset(map, 0, height * lpr->row_stride[0]);
237
238      winsys->displaytarget_unmap(winsys, lpr->dt);
239   }
240
241   return TRUE;
242}
243
244
245static struct pipe_resource *
246llvmpipe_resource_create(struct pipe_screen *_screen,
247                         const struct pipe_resource *templat)
248{
249   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
250   struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
251   if (!lpr)
252      return NULL;
253
254   lpr->base = *templat;
255   pipe_reference_init(&lpr->base.reference, 1);
256   lpr->base.screen = &screen->base;
257
258   /* assert(lpr->base.bind); */
259
260   if (resource_is_texture(&lpr->base)) {
261      if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) {
262         /* displayable surface */
263         if (!llvmpipe_displaytarget_layout(screen, lpr))
264            goto fail;
265         assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
266      }
267      else {
268         /* texture map */
269         if (!llvmpipe_texture_layout(screen, lpr))
270            goto fail;
271         assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
272      }
273      assert(lpr->layout[0]);
274   }
275   else {
276      /* other data (vertex buffer, const buffer, etc) */
277      const enum pipe_format format = templat->format;
278      const uint w = templat->width0 / util_format_get_blockheight(format);
279      /* XXX buffers should only have one dimension, those values should be 1 */
280      const uint h = templat->height0 / util_format_get_blockwidth(format);
281      const uint d = templat->depth0;
282      const uint bpp = util_format_get_blocksize(format);
283      const uint bytes = w * h * d * bpp;
284      lpr->data = align_malloc(bytes, 16);
285      if (!lpr->data)
286         goto fail;
287      memset(lpr->data, 0, bytes);
288   }
289
290   lpr->id = id_counter++;
291
292#ifdef DEBUG
293   insert_at_tail(&resource_list, lpr);
294#endif
295
296   return &lpr->base;
297
298 fail:
299   FREE(lpr);
300   return NULL;
301}
302
303
304static void
305llvmpipe_resource_destroy(struct pipe_screen *pscreen,
306			  struct pipe_resource *pt)
307{
308   struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
309   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
310
311   if (lpr->dt) {
312      /* display target */
313      struct sw_winsys *winsys = screen->winsys;
314      winsys->displaytarget_destroy(winsys, lpr->dt);
315
316      if (lpr->tiled[0].data) {
317         align_free(lpr->tiled[0].data);
318         lpr->tiled[0].data = NULL;
319      }
320
321      FREE(lpr->layout[0]);
322   }
323   else if (resource_is_texture(pt)) {
324      /* regular texture */
325      uint level;
326
327      /* free linear image data */
328      for (level = 0; level < Elements(lpr->linear); level++) {
329         if (lpr->linear[level].data) {
330            align_free(lpr->linear[level].data);
331            lpr->linear[level].data = NULL;
332         }
333      }
334
335      /* free tiled image data */
336      for (level = 0; level < Elements(lpr->tiled); level++) {
337         if (lpr->tiled[level].data) {
338            align_free(lpr->tiled[level].data);
339            lpr->tiled[level].data = NULL;
340         }
341      }
342
343      /* free layout flag arrays */
344      for (level = 0; level < Elements(lpr->tiled); level++) {
345         FREE(lpr->layout[level]);
346         lpr->layout[level] = NULL;
347      }
348   }
349   else if (!lpr->userBuffer) {
350      assert(lpr->data);
351      align_free(lpr->data);
352   }
353
354#ifdef DEBUG
355   if (lpr->next)
356      remove_from_list(lpr);
357#endif
358
359   FREE(lpr);
360}
361
362
363/**
364 * Map a resource for read/write.
365 */
366void *
367llvmpipe_resource_map(struct pipe_resource *resource,
368                      unsigned level,
369                      unsigned layer,
370                      enum lp_texture_usage tex_usage,
371                      enum lp_texture_layout layout)
372{
373   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
374   uint8_t *map;
375
376   assert(level < LP_MAX_TEXTURE_LEVELS);
377   assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
378
379   assert(tex_usage == LP_TEX_USAGE_READ ||
380          tex_usage == LP_TEX_USAGE_READ_WRITE ||
381          tex_usage == LP_TEX_USAGE_WRITE_ALL);
382
383   assert(layout == LP_TEX_LAYOUT_NONE ||
384          layout == LP_TEX_LAYOUT_TILED ||
385          layout == LP_TEX_LAYOUT_LINEAR);
386
387   if (lpr->dt) {
388      /* display target */
389      struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen);
390      struct sw_winsys *winsys = screen->winsys;
391      unsigned dt_usage;
392      uint8_t *map2;
393
394      if (tex_usage == LP_TEX_USAGE_READ) {
395         dt_usage = PIPE_TRANSFER_READ;
396      }
397      else {
398         dt_usage = PIPE_TRANSFER_READ_WRITE;
399      }
400
401      assert(level == 0);
402      assert(layer == 0);
403
404      /* FIXME: keep map count? */
405      map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
406
407      /* install this linear image in texture data structure */
408      lpr->linear[level].data = map;
409
410      /* make sure tiled data gets converted to linear data */
411      map2 = llvmpipe_get_texture_image(lpr, 0, 0, tex_usage, layout);
412      if (layout == LP_TEX_LAYOUT_LINEAR)
413         assert(map == map2);
414
415      return map2;
416   }
417   else if (resource_is_texture(resource)) {
418
419      map = llvmpipe_get_texture_image(lpr, layer, level,
420                                       tex_usage, layout);
421      return map;
422   }
423   else {
424      return lpr->data;
425   }
426}
427
428
429/**
430 * Unmap a resource.
431 */
432void
433llvmpipe_resource_unmap(struct pipe_resource *resource,
434                       unsigned level,
435                       unsigned layer)
436{
437   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
438
439   if (lpr->dt) {
440      /* display target */
441      struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen);
442      struct sw_winsys *winsys = lp_screen->winsys;
443
444      assert(level == 0);
445      assert(layer == 0);
446
447      /* make sure linear image is up to date */
448      (void) llvmpipe_get_texture_image(lpr, layer, level,
449                                        LP_TEX_USAGE_READ,
450                                        LP_TEX_LAYOUT_LINEAR);
451
452      winsys->displaytarget_unmap(winsys, lpr->dt);
453   }
454}
455
456
457void *
458llvmpipe_resource_data(struct pipe_resource *resource)
459{
460   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
461
462   assert(!resource_is_texture(resource));
463
464   return lpr->data;
465}
466
467
468static struct pipe_resource *
469llvmpipe_resource_from_handle(struct pipe_screen *screen,
470			      const struct pipe_resource *template,
471			      struct winsys_handle *whandle)
472{
473   struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
474   struct llvmpipe_resource *lpr;
475   unsigned width, height, width_t, height_t;
476
477   /* XXX Seems like from_handled depth textures doesn't work that well */
478
479   lpr = CALLOC_STRUCT(llvmpipe_resource);
480   if (!lpr) {
481      goto no_lpr;
482   }
483
484   lpr->base = *template;
485   pipe_reference_init(&lpr->base.reference, 1);
486   lpr->base.screen = screen;
487
488   width = align(lpr->base.width0, TILE_SIZE);
489   height = align(lpr->base.height0, TILE_SIZE);
490   width_t = width / TILE_SIZE;
491   height_t = height / TILE_SIZE;
492
493   /*
494    * Looks like unaligned displaytargets work just fine,
495    * at least sampler/render ones.
496    */
497#if 0
498   assert(lpr->base.width0 == width);
499   assert(lpr->base.height0 == height);
500#endif
501
502   lpr->tiles_per_row[0] = width_t;
503   lpr->tiles_per_image[0] = width_t * height_t;
504   lpr->num_slices_faces[0] = 1;
505   lpr->img_stride[0] = 0;
506
507   lpr->dt = winsys->displaytarget_from_handle(winsys,
508                                               template,
509                                               whandle,
510                                               &lpr->row_stride[0]);
511   if (!lpr->dt) {
512      goto no_dt;
513   }
514
515   lpr->layout[0] = alloc_layout_array(1, lpr->base.width0, lpr->base.height0);
516   if (!lpr->layout[0]) {
517      goto no_layout_0;
518   }
519
520   assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
521
522   lpr->id = id_counter++;
523
524#ifdef DEBUG
525   insert_at_tail(&resource_list, lpr);
526#endif
527
528   return &lpr->base;
529
530no_layout_0:
531   winsys->displaytarget_destroy(winsys, lpr->dt);
532no_dt:
533   FREE(lpr);
534no_lpr:
535   return NULL;
536}
537
538
539static boolean
540llvmpipe_resource_get_handle(struct pipe_screen *screen,
541                            struct pipe_resource *pt,
542                            struct winsys_handle *whandle)
543{
544   struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
545   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
546
547   assert(lpr->dt);
548   if (!lpr->dt)
549      return FALSE;
550
551   return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
552}
553
554
555static struct pipe_surface *
556llvmpipe_create_surface(struct pipe_context *pipe,
557                        struct pipe_resource *pt,
558                        const struct pipe_surface *surf_tmpl)
559{
560   struct pipe_surface *ps;
561
562   assert(surf_tmpl->u.tex.level <= pt->last_level);
563
564   ps = CALLOC_STRUCT(pipe_surface);
565   if (ps) {
566      pipe_reference_init(&ps->reference, 1);
567      pipe_resource_reference(&ps->texture, pt);
568      ps->context = pipe;
569      ps->format = surf_tmpl->format;
570      ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
571      ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
572      ps->usage = surf_tmpl->usage;
573
574      ps->u.tex.level = surf_tmpl->u.tex.level;
575      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
576      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
577   }
578   return ps;
579}
580
581
582static void
583llvmpipe_surface_destroy(struct pipe_context *pipe,
584                         struct pipe_surface *surf)
585{
586   /* Effectively do the texture_update work here - if texture images
587    * needed post-processing to put them into hardware layout, this is
588    * where it would happen.  For llvmpipe, nothing to do.
589    */
590   assert(surf->texture);
591   pipe_resource_reference(&surf->texture, NULL);
592   FREE(surf);
593}
594
595
596static struct pipe_transfer *
597llvmpipe_get_transfer(struct pipe_context *pipe,
598                      struct pipe_resource *resource,
599                      unsigned level,
600                      unsigned usage,
601                      const struct pipe_box *box)
602{
603   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
604   struct llvmpipe_resource *lprex = llvmpipe_resource(resource);
605   struct llvmpipe_transfer *lpr;
606
607   assert(resource);
608   assert(level <= resource->last_level);
609
610   /*
611    * Transfers, like other pipe operations, must happen in order, so flush the
612    * context if necessary.
613    */
614   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
615      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
616      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
617      if (!llvmpipe_flush_resource(pipe, resource,
618                                   level,
619                                   box->depth > 1 ? -1 : box->z,
620                                   read_only,
621                                   TRUE, /* cpu_access */
622                                   do_not_block,
623                                   __FUNCTION__)) {
624         /*
625          * It would have blocked, but state tracker requested no to.
626          */
627         assert(do_not_block);
628         return NULL;
629      }
630   }
631
632   if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][0])
633      llvmpipe->dirty |= LP_NEW_CONSTANTS;
634
635   lpr = CALLOC_STRUCT(llvmpipe_transfer);
636   if (lpr) {
637      struct pipe_transfer *pt = &lpr->base;
638      pipe_resource_reference(&pt->resource, resource);
639      pt->box = *box;
640      pt->level = level;
641      pt->stride = lprex->row_stride[level];
642      pt->layer_stride = lprex->img_stride[level];
643      pt->usage = usage;
644
645      return pt;
646   }
647   return NULL;
648}
649
650
651static void
652llvmpipe_transfer_destroy(struct pipe_context *pipe,
653                              struct pipe_transfer *transfer)
654{
655   /* Effectively do the texture_update work here - if texture images
656    * needed post-processing to put them into hardware layout, this is
657    * where it would happen.  For llvmpipe, nothing to do.
658    */
659   assert (transfer->resource);
660   pipe_resource_reference(&transfer->resource, NULL);
661   FREE(transfer);
662}
663
664
665static void *
666llvmpipe_transfer_map( struct pipe_context *pipe,
667                       struct pipe_transfer *transfer )
668{
669   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
670   ubyte *map;
671   struct llvmpipe_resource *lpr;
672   enum pipe_format format;
673   enum lp_texture_usage tex_usage;
674   const char *mode;
675
676   assert(transfer->level < LP_MAX_TEXTURE_LEVELS);
677
678   /*
679   printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
680          transfer->x, transfer->y, transfer->width, transfer->height,
681          transfer->texture->width0,
682          transfer->texture->height0,
683          transfer->usage);
684   */
685
686   if (transfer->usage == PIPE_TRANSFER_READ) {
687      tex_usage = LP_TEX_USAGE_READ;
688      mode = "read";
689   }
690   else {
691      tex_usage = LP_TEX_USAGE_READ_WRITE;
692      mode = "read/write";
693   }
694
695   if (0) {
696      struct llvmpipe_resource *lpr = llvmpipe_resource(transfer->resource);
697      printf("transfer map tex %u  mode %s\n", lpr->id, mode);
698   }
699
700
701   assert(transfer->resource);
702   lpr = llvmpipe_resource(transfer->resource);
703   format = lpr->base.format;
704
705   map = llvmpipe_resource_map(transfer->resource,
706                               transfer->level,
707                               transfer->box.z,
708                               tex_usage, LP_TEX_LAYOUT_LINEAR);
709
710
711   /* May want to do different things here depending on read/write nature
712    * of the map:
713    */
714   if (transfer->usage & PIPE_TRANSFER_WRITE) {
715      /* Do something to notify sharing contexts of a texture change.
716       */
717      screen->timestamp++;
718   }
719
720   map +=
721      transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
722      transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
723
724   return map;
725}
726
727
728static void
729llvmpipe_transfer_unmap(struct pipe_context *pipe,
730                        struct pipe_transfer *transfer)
731{
732   assert(transfer->resource);
733
734   llvmpipe_resource_unmap(transfer->resource,
735                           transfer->level,
736                           transfer->box.z);
737}
738
739unsigned int
740llvmpipe_is_resource_referenced( struct pipe_context *pipe,
741                                 struct pipe_resource *presource,
742                                 unsigned level, int layer)
743{
744   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
745
746   if (presource->target == PIPE_BUFFER)
747      return LP_UNREFERENCED;
748
749   return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
750}
751
752
753
754/**
755 * Create buffer which wraps user-space data.
756 */
757struct pipe_resource *
758llvmpipe_user_buffer_create(struct pipe_screen *screen,
759                            void *ptr,
760                            unsigned bytes,
761			    unsigned bind_flags)
762{
763   struct llvmpipe_resource *buffer;
764
765   buffer = CALLOC_STRUCT(llvmpipe_resource);
766   if(!buffer)
767      return NULL;
768
769   pipe_reference_init(&buffer->base.reference, 1);
770   buffer->base.screen = screen;
771   buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
772   buffer->base.bind = bind_flags;
773   buffer->base.usage = PIPE_USAGE_IMMUTABLE;
774   buffer->base.flags = 0;
775   buffer->base.width0 = bytes;
776   buffer->base.height0 = 1;
777   buffer->base.depth0 = 1;
778   buffer->base.array_size = 1;
779   buffer->userBuffer = TRUE;
780   buffer->data = ptr;
781
782   return &buffer->base;
783}
784
785
786/**
787 * Compute size (in bytes) need to store a texture image / mipmap level,
788 * for just one cube face or one 3D texture slice
789 */
790static unsigned
791tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
792                    enum lp_texture_layout layout)
793{
794   const unsigned width = u_minify(lpr->base.width0, level);
795   const unsigned height = u_minify(lpr->base.height0, level);
796
797   assert(layout == LP_TEX_LAYOUT_TILED ||
798          layout == LP_TEX_LAYOUT_LINEAR);
799
800   if (layout == LP_TEX_LAYOUT_TILED) {
801      /* for tiled layout, force a 32bpp format */
802      const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM;
803      const unsigned block_size = util_format_get_blocksize(format);
804      const unsigned nblocksy =
805         util_format_get_nblocksy(format, align(height, TILE_SIZE));
806      const unsigned nblocksx =
807         util_format_get_nblocksx(format, align(width, TILE_SIZE));
808      const unsigned buffer_size = block_size * nblocksy * nblocksx;
809      return buffer_size;
810   }
811   else {
812      /* we already computed this */
813      return lpr->img_stride[level];
814   }
815}
816
817
818/**
819 * Compute size (in bytes) need to store a texture image / mipmap level,
820 * including all cube faces or 3D image slices
821 */
822static unsigned
823tex_image_size(const struct llvmpipe_resource *lpr, unsigned level,
824               enum lp_texture_layout layout)
825{
826   const unsigned buf_size = tex_image_face_size(lpr, level, layout);
827   return buf_size * lpr->num_slices_faces[level];
828}
829
830
831/**
832 * This function encapsulates some complicated logic for determining
833 * how to convert a tile of image data from linear layout to tiled
834 * layout, or vice versa.
835 * \param cur_layout  the current tile layout
836 * \param target_layout  the desired tile layout
837 * \param usage  how the tile will be accessed (R/W vs. read-only, etc)
838 * \param new_layout_return  returns the new layout mode
839 * \param convert_return  returns TRUE if image conversion is needed
840 */
841static void
842layout_logic(enum lp_texture_layout cur_layout,
843             enum lp_texture_layout target_layout,
844             enum lp_texture_usage usage,
845             enum lp_texture_layout *new_layout_return,
846             boolean *convert)
847{
848   enum lp_texture_layout other_layout, new_layout;
849
850   *convert = FALSE;
851
852   new_layout = 99; /* debug check */
853
854   if (target_layout == LP_TEX_LAYOUT_LINEAR) {
855      other_layout = LP_TEX_LAYOUT_TILED;
856   }
857   else {
858      assert(target_layout == LP_TEX_LAYOUT_TILED);
859      other_layout = LP_TEX_LAYOUT_LINEAR;
860   }
861
862   new_layout = target_layout;  /* may get changed below */
863
864   if (cur_layout == LP_TEX_LAYOUT_BOTH) {
865      if (usage == LP_TEX_USAGE_READ) {
866         new_layout = LP_TEX_LAYOUT_BOTH;
867      }
868   }
869   else if (cur_layout == other_layout) {
870      if (usage != LP_TEX_USAGE_WRITE_ALL) {
871         /* need to convert tiled data to linear or vice versa */
872         *convert = TRUE;
873
874         if (usage == LP_TEX_USAGE_READ)
875            new_layout = LP_TEX_LAYOUT_BOTH;
876      }
877   }
878   else {
879      assert(cur_layout == LP_TEX_LAYOUT_NONE ||
880             cur_layout == target_layout);
881   }
882
883   assert(new_layout == LP_TEX_LAYOUT_BOTH ||
884          new_layout == target_layout);
885
886   *new_layout_return = new_layout;
887}
888
889
890/**
891 * Return pointer to a 2D texture image/face/slice.
892 * No tiled/linear conversion is done.
893 */
894ubyte *
895llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
896                                   unsigned face_slice, unsigned level,
897                                   enum lp_texture_layout layout)
898{
899   struct llvmpipe_texture_image *img;
900   unsigned offset;
901
902   if (layout == LP_TEX_LAYOUT_LINEAR) {
903      img = &lpr->linear[level];
904   }
905   else {
906      assert (layout == LP_TEX_LAYOUT_TILED);
907      img = &lpr->tiled[level];
908   }
909
910   if (face_slice > 0)
911      offset = face_slice * tex_image_face_size(lpr, level, layout);
912   else
913      offset = 0;
914
915   return (ubyte *) img->data + offset;
916}
917
918
919static INLINE enum lp_texture_layout
920llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr,
921                                 unsigned face_slice, unsigned level,
922                                 unsigned x, unsigned y)
923{
924   uint i;
925   assert(resource_is_texture(&lpr->base));
926   assert(x < lpr->tiles_per_row[level]);
927   i = face_slice * lpr->tiles_per_image[level]
928      + y * lpr->tiles_per_row[level] + x;
929   return lpr->layout[level][i];
930}
931
932
933static INLINE void
934llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr,
935                                 unsigned face_slice, unsigned level,
936                                 unsigned x, unsigned y,
937                                 enum lp_texture_layout layout)
938{
939   uint i;
940   assert(resource_is_texture(&lpr->base));
941   assert(x < lpr->tiles_per_row[level]);
942   i = face_slice * lpr->tiles_per_image[level]
943      + y * lpr->tiles_per_row[level] + x;
944   lpr->layout[level][i] = layout;
945}
946
947
948/**
949 * Set the layout mode for all tiles in a particular image.
950 */
951static INLINE void
952llvmpipe_set_texture_image_layout(struct llvmpipe_resource *lpr,
953                                  unsigned face_slice, unsigned level,
954                                  unsigned width_t, unsigned height_t,
955                                  enum lp_texture_layout layout)
956{
957   const unsigned start = face_slice * lpr->tiles_per_image[level];
958   unsigned i;
959
960   for (i = 0; i < width_t * height_t; i++) {
961      lpr->layout[level][start + i] = layout;
962   }
963}
964
965
966/**
967 * Allocate storage for a linear or tile texture image (all cube
968 * faces and all 3D slices.
969 */
970static void
971alloc_image_data(struct llvmpipe_resource *lpr, unsigned level,
972                 enum lp_texture_layout layout)
973{
974   uint alignment = MAX2(16, util_cpu_caps.cacheline);
975
976   if (lpr->dt)
977      assert(level == 0);
978
979   if (layout == LP_TEX_LAYOUT_TILED) {
980      /* tiled data is stored in regular memory */
981      uint buffer_size = tex_image_size(lpr, level, layout);
982      lpr->tiled[level].data = align_malloc(buffer_size, alignment);
983      if (lpr->tiled[level].data) {
984         memset(lpr->tiled[level].data, 0, buffer_size);
985      }
986   }
987   else {
988      assert(layout == LP_TEX_LAYOUT_LINEAR);
989      if (lpr->dt) {
990         /* we get the linear memory from the winsys, and it has
991          * already been zeroed
992          */
993         struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen);
994         struct sw_winsys *winsys = screen->winsys;
995
996         lpr->linear[0].data =
997            winsys->displaytarget_map(winsys, lpr->dt,
998                                      PIPE_TRANSFER_READ_WRITE);
999      }
1000      else {
1001         /* not a display target - allocate regular memory */
1002         uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
1003         lpr->linear[level].data = align_malloc(buffer_size, alignment);
1004         if (lpr->linear[level].data) {
1005            memset(lpr->linear[level].data, 0, buffer_size);
1006         }
1007      }
1008   }
1009}
1010
1011
1012
1013/**
1014 * Return pointer to texture image data (either linear or tiled layout)
1015 * for a particular cube face or 3D texture slice.
1016 *
1017 * \param face_slice  the cube face or 3D slice of interest
1018 * \param usage  one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE
1019 * \param layout  either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE
1020 */
1021void *
1022llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
1023                           unsigned face_slice, unsigned level,
1024                           enum lp_texture_usage usage,
1025                           enum lp_texture_layout layout)
1026{
1027   /*
1028    * 'target' refers to the image which we're retrieving (either in
1029    * tiled or linear layout).
1030    * 'other' refers to the same image but in the other layout. (it may
1031    *  or may not exist.
1032    */
1033   struct llvmpipe_texture_image *target_img;
1034   struct llvmpipe_texture_image *other_img;
1035   void *target_data;
1036   void *other_data;
1037   const unsigned width = u_minify(lpr->base.width0, level);
1038   const unsigned height = u_minify(lpr->base.height0, level);
1039   const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
1040   const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
1041   enum lp_texture_layout other_layout;
1042   boolean only_allocate;
1043
1044   assert(layout == LP_TEX_LAYOUT_NONE ||
1045          layout == LP_TEX_LAYOUT_TILED ||
1046          layout == LP_TEX_LAYOUT_LINEAR);
1047
1048   assert(usage == LP_TEX_USAGE_READ ||
1049          usage == LP_TEX_USAGE_READ_WRITE ||
1050          usage == LP_TEX_USAGE_WRITE_ALL);
1051
1052   /* check for the special case of layout == LP_TEX_LAYOUT_NONE */
1053   if (layout == LP_TEX_LAYOUT_NONE) {
1054      only_allocate = TRUE;
1055      layout = LP_TEX_LAYOUT_TILED;
1056   }
1057   else {
1058      only_allocate = FALSE;
1059   }
1060
1061   if (lpr->dt) {
1062      assert(lpr->linear[level].data);
1063   }
1064
1065   /* which is target?  which is other? */
1066   if (layout == LP_TEX_LAYOUT_LINEAR) {
1067      target_img = &lpr->linear[level];
1068      other_img = &lpr->tiled[level];
1069      other_layout = LP_TEX_LAYOUT_TILED;
1070   }
1071   else {
1072      target_img = &lpr->tiled[level];
1073      other_img = &lpr->linear[level];
1074      other_layout = LP_TEX_LAYOUT_LINEAR;
1075   }
1076
1077   target_data = target_img->data;
1078   other_data = other_img->data;
1079
1080   if (!target_data) {
1081      /* allocate memory for the target image now */
1082      alloc_image_data(lpr, level, layout);
1083      target_data = target_img->data;
1084   }
1085
1086   if (face_slice > 0) {
1087      unsigned target_offset, other_offset;
1088
1089      target_offset = face_slice * tex_image_face_size(lpr, level, layout);
1090      other_offset = face_slice * tex_image_face_size(lpr, level, other_layout);
1091      if (target_data) {
1092         target_data = (uint8_t *) target_data + target_offset;
1093      }
1094      if (other_data) {
1095         other_data = (uint8_t *) other_data + other_offset;
1096      }
1097   }
1098
1099   if (only_allocate) {
1100      /* Just allocating tiled memory.  Don't initialize it from the
1101       * linear data if it exists.
1102       */
1103      return target_data;
1104   }
1105
1106   if (other_data) {
1107      /* may need to convert other data to the requested layout */
1108      enum lp_texture_layout new_layout;
1109      unsigned x, y;
1110
1111      /* loop over all image tiles, doing layout conversion where needed */
1112      for (y = 0; y < height_t; y++) {
1113         for (x = 0; x < width_t; x++) {
1114            enum lp_texture_layout cur_layout =
1115               llvmpipe_get_texture_tile_layout(lpr, face_slice, level, x, y);
1116            boolean convert;
1117
1118            layout_logic(cur_layout, layout, usage, &new_layout, &convert);
1119
1120            if (convert && other_data && target_data) {
1121               if (layout == LP_TEX_LAYOUT_TILED) {
1122                  lp_linear_to_tiled(other_data, target_data,
1123                                     x * TILE_SIZE, y * TILE_SIZE,
1124                                     TILE_SIZE, TILE_SIZE,
1125                                     lpr->base.format,
1126                                     lpr->row_stride[level],
1127                                     lpr->tiles_per_row[level]);
1128               }
1129               else {
1130                  assert(layout == LP_TEX_LAYOUT_LINEAR);
1131                  lp_tiled_to_linear(other_data, target_data,
1132                                     x * TILE_SIZE, y * TILE_SIZE,
1133                                     TILE_SIZE, TILE_SIZE,
1134                                     lpr->base.format,
1135                                     lpr->row_stride[level],
1136                                     lpr->tiles_per_row[level]);
1137               }
1138            }
1139
1140            if (new_layout != cur_layout)
1141               llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y,
1142                                                new_layout);
1143         }
1144      }
1145   }
1146   else {
1147      /* no other data */
1148      llvmpipe_set_texture_image_layout(lpr, face_slice, level,
1149                                        width_t, height_t, layout);
1150   }
1151
1152   return target_data;
1153}
1154
1155
1156/**
1157 * Return pointer to start of a texture image (1D, 2D, 3D, CUBE).
1158 * All cube faces and 3D slices will be converted to the requested
1159 * layout if needed.
1160 * This is typically used when we're about to sample from a texture.
1161 */
1162void *
1163llvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr,
1164                               unsigned level,
1165                               enum lp_texture_usage usage,
1166                               enum lp_texture_layout layout)
1167{
1168   const int slices = lpr->num_slices_faces[level];
1169   int slice;
1170   void *map = NULL;
1171
1172   assert(slices > 0);
1173
1174   for (slice = slices - 1; slice >= 0; slice--) {
1175      map = llvmpipe_get_texture_image(lpr, slice, level, usage, layout);
1176   }
1177
1178   return map;
1179}
1180
1181
1182/**
1183 * Get pointer to a linear image (not the tile!) where the tile at (x,y)
1184 * is known to be in linear layout.
1185 * Conversion from tiled to linear will be done if necessary.
1186 * \return pointer to start of image/face (not the tile)
1187 */
1188ubyte *
1189llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
1190                                 unsigned face_slice, unsigned level,
1191                                 enum lp_texture_usage usage,
1192                                 unsigned x, unsigned y)
1193{
1194   struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
1195   enum lp_texture_layout cur_layout, new_layout;
1196   const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
1197   boolean convert;
1198   uint8_t *tiled_image, *linear_image;
1199
1200   assert(resource_is_texture(&lpr->base));
1201   assert(x % TILE_SIZE == 0);
1202   assert(y % TILE_SIZE == 0);
1203
1204   if (!linear_img->data) {
1205      /* allocate memory for the linear image now */
1206      alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR);
1207   }
1208
1209   /* compute address of the slice/face of the image that contains the tile */
1210   tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1211                                                    LP_TEX_LAYOUT_TILED);
1212   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1213                                                     LP_TEX_LAYOUT_LINEAR);
1214
1215   /* get current tile layout and determine if data conversion is needed */
1216   cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
1217
1218   layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage,
1219                &new_layout, &convert);
1220
1221   if (convert && tiled_image && linear_image) {
1222      lp_tiled_to_linear(tiled_image, linear_image,
1223                         x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
1224                         lpr->row_stride[level],
1225                         lpr->tiles_per_row[level]);
1226   }
1227
1228   if (new_layout != cur_layout)
1229      llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
1230
1231   return linear_image;
1232}
1233
1234
1235/**
1236 * Get pointer to tiled data for rendering.
1237 * \return pointer to the tiled data at the given tile position
1238 */
1239ubyte *
1240llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
1241                          unsigned face_slice, unsigned level,
1242                          enum lp_texture_usage usage,
1243                          unsigned x, unsigned y)
1244{
1245   struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level];
1246   enum lp_texture_layout cur_layout, new_layout;
1247   const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
1248   boolean convert;
1249   uint8_t *tiled_image, *linear_image;
1250   unsigned tile_offset;
1251
1252   assert(x % TILE_SIZE == 0);
1253   assert(y % TILE_SIZE == 0);
1254
1255   if (!tiled_img->data) {
1256      /* allocate memory for the tiled image now */
1257      alloc_image_data(lpr, level, LP_TEX_LAYOUT_TILED);
1258   }
1259
1260   /* compute address of the slice/face of the image that contains the tile */
1261   tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1262                                                    LP_TEX_LAYOUT_TILED);
1263   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1264                                                     LP_TEX_LAYOUT_LINEAR);
1265
1266   /* get current tile layout and see if we need to convert the data */
1267   cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
1268
1269   layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert);
1270   if (convert && linear_image && tiled_image) {
1271      lp_linear_to_tiled(linear_image, tiled_image,
1272                         x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
1273                         lpr->row_stride[level],
1274                         lpr->tiles_per_row[level]);
1275   }
1276
1277   if (!tiled_image)
1278      return NULL;
1279
1280   if (new_layout != cur_layout)
1281      llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
1282
1283   /* compute, return address of the 64x64 tile */
1284   tile_offset = (ty * lpr->tiles_per_row[level] + tx)
1285         * TILE_SIZE * TILE_SIZE * 4;
1286
1287   return (ubyte *) tiled_image + tile_offset;
1288}
1289
1290
1291/**
1292 * Get pointer to tiled data for rendering.
1293 * \return pointer to the tiled data at the given tile position
1294 */
1295void
1296llvmpipe_unswizzle_cbuf_tile(struct llvmpipe_resource *lpr,
1297                             unsigned face_slice, unsigned level,
1298                             unsigned x, unsigned y,
1299                             uint8_t *tile)
1300{
1301   struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
1302   const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
1303   uint8_t *linear_image;
1304
1305   assert(x % TILE_SIZE == 0);
1306   assert(y % TILE_SIZE == 0);
1307
1308   if (!linear_img->data) {
1309      /* allocate memory for the linear image now */
1310      alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR);
1311   }
1312
1313   /* compute address of the slice/face of the image that contains the tile */
1314   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1315                                                     LP_TEX_LAYOUT_LINEAR);
1316
1317   {
1318      uint ii = x, jj = y;
1319      uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
1320      uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
1321
1322      /* Note that lp_tiled_to_linear expects the tile parameter to
1323       * point at the first tile in a whole-image sized array.  In
1324       * this code, we have only a single tile and have to do some
1325       * pointer arithmetic to figure out where the "image" would have
1326       * started.
1327       */
1328      lp_tiled_to_linear(tile - byte_offset, linear_image,
1329                         x, y, TILE_SIZE, TILE_SIZE,
1330                         lpr->base.format,
1331                         lpr->row_stride[level],
1332                         1);       /* tiles per row */
1333   }
1334
1335   llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty,
1336                                    LP_TEX_LAYOUT_LINEAR);
1337}
1338
1339
1340/**
1341 * Get pointer to tiled data for rendering.
1342 * \return pointer to the tiled data at the given tile position
1343 */
1344void
1345llvmpipe_swizzle_cbuf_tile(struct llvmpipe_resource *lpr,
1346                           unsigned face_slice, unsigned level,
1347                           unsigned x, unsigned y,
1348                           uint8_t *tile)
1349{
1350   uint8_t *linear_image;
1351
1352   assert(x % TILE_SIZE == 0);
1353   assert(y % TILE_SIZE == 0);
1354
1355   /* compute address of the slice/face of the image that contains the tile */
1356   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
1357                                                     LP_TEX_LAYOUT_LINEAR);
1358
1359   if (linear_image) {
1360      uint ii = x, jj = y;
1361      uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
1362      uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
1363
1364      /* Note that lp_linear_to_tiled expects the tile parameter to
1365       * point at the first tile in a whole-image sized array.  In
1366       * this code, we have only a single tile and have to do some
1367       * pointer arithmetic to figure out where the "image" would have
1368       * started.
1369       */
1370      lp_linear_to_tiled(linear_image, tile - byte_offset,
1371                         x, y, TILE_SIZE, TILE_SIZE,
1372                         lpr->base.format,
1373                         lpr->row_stride[level],
1374                         1);       /* tiles per row */
1375   }
1376}
1377
1378
1379/**
1380 * Return size of resource in bytes
1381 */
1382unsigned
1383llvmpipe_resource_size(const struct pipe_resource *resource)
1384{
1385   const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
1386   unsigned lvl, size = 0;
1387
1388   for (lvl = 0; lvl <= lpr->base.last_level; lvl++) {
1389      if (lpr->linear[lvl].data)
1390         size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR);
1391
1392      if (lpr->tiled[lvl].data)
1393         size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED);
1394   }
1395
1396   return size;
1397}
1398
1399
1400#ifdef DEBUG
1401void
1402llvmpipe_print_resources(void)
1403{
1404   struct llvmpipe_resource *lpr;
1405   unsigned n = 0, total = 0;
1406
1407   debug_printf("LLVMPIPE: current resources:\n");
1408   foreach(lpr, &resource_list) {
1409      unsigned size = llvmpipe_resource_size(&lpr->base);
1410      debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
1411                   lpr->id, (void *) lpr,
1412                   lpr->base.width0, lpr->base.height0, lpr->base.depth0,
1413                   size, lpr->base.reference.count);
1414      total += size;
1415      n++;
1416   }
1417   debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
1418}
1419#endif
1420
1421
1422void
1423llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
1424{
1425#ifdef DEBUG
1426   /* init linked list for tracking resources */
1427   {
1428      static boolean first_call = TRUE;
1429      if (first_call) {
1430         memset(&resource_list, 0, sizeof(resource_list));
1431         make_empty_list(&resource_list);
1432         first_call = FALSE;
1433      }
1434   }
1435#endif
1436
1437   screen->resource_create = llvmpipe_resource_create;
1438   screen->resource_destroy = llvmpipe_resource_destroy;
1439   screen->resource_from_handle = llvmpipe_resource_from_handle;
1440   screen->resource_get_handle = llvmpipe_resource_get_handle;
1441}
1442
1443
1444void
1445llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
1446{
1447   pipe->get_transfer = llvmpipe_get_transfer;
1448   pipe->transfer_destroy = llvmpipe_transfer_destroy;
1449   pipe->transfer_map = llvmpipe_transfer_map;
1450   pipe->transfer_unmap = llvmpipe_transfer_unmap;
1451
1452   pipe->transfer_flush_region = u_default_transfer_flush_region;
1453   pipe->transfer_inline_write = u_default_transfer_inline_write;
1454
1455   pipe->create_surface = llvmpipe_create_surface;
1456   pipe->surface_destroy = llvmpipe_surface_destroy;
1457}
1458