1/**************************************************************************
2 *
3 * Copyright 2006 VMware, Inc.
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 VMWARE 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 <keithw@vmware.com>
30  *   Michel Dänzer <daenzer@vmware.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/format/u_format.h"
41#include "util/u_math.h"
42#include "util/u_memory.h"
43#include "util/u_transfer.h"
44
45#include "lp_context.h"
46#include "lp_flush.h"
47#include "lp_screen.h"
48#include "lp_texture.h"
49#include "lp_setup.h"
50#include "lp_state.h"
51#include "lp_rast.h"
52
53#include "frontend/sw_winsys.h"
54#include "git_sha1.h"
55
56#ifndef _WIN32
57#include "drm-uapi/drm_fourcc.h"
58#endif
59
60
61#ifdef DEBUG
62static struct llvmpipe_resource resource_list;
63static mtx_t resource_list_mutex = _MTX_INITIALIZER_NP;
64#endif
65static unsigned id_counter = 0;
66
67
68/**
69 * Conventional allocation path for non-display textures:
70 * Compute strides and allocate data (unless asked not to).
71 */
72static boolean
73llvmpipe_texture_layout(struct llvmpipe_screen *screen,
74                        struct llvmpipe_resource *lpr,
75                        boolean allocate)
76{
77   struct pipe_resource *pt = &lpr->base;
78   unsigned level;
79   unsigned width = pt->width0;
80   unsigned height = pt->height0;
81   unsigned depth = pt->depth0;
82   uint64_t total_size = 0;
83   unsigned layers = pt->array_size;
84   unsigned num_samples = util_res_sample_count(pt);
85
86   /* XXX:
87    * This alignment here (same for displaytarget) was added for the purpose of
88    * ARB_map_buffer_alignment. I am not convinced it's needed for non-buffer
89    * resources. Otherwise we'd want the max of cacheline size and 16 (max size
90    * of a block for all formats) though this should not be strictly necessary
91    * neither. In any case it can only affect compressed or 1d textures.
92    */
93   unsigned mip_align = MAX2(64, util_get_cpu_caps()->cacheline);
94
95   assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
96   assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
97
98   for (level = 0; level <= pt->last_level; level++) {
99      uint64_t mipsize;
100      unsigned align_x, align_y, nblocksx, nblocksy, block_size, num_slices;
101
102      /* Row stride and image stride */
103
104      /* For non-compressed formats we need 4x4 pixel alignment
105       * so we can read/write LP_RASTER_BLOCK_SIZE when rendering to them.
106       * We also want cache line size in x direction,
107       * otherwise same cache line could end up in multiple threads.
108       * For explicit 1d resources however we reduce this to 4x1 and
109       * handle specially in render output code (as we need to do special
110       * handling there for buffers in any case).
111       */
112      if (util_format_is_compressed(pt->format))
113         align_x = align_y = 1;
114      else {
115         align_x = LP_RASTER_BLOCK_SIZE;
116         if (llvmpipe_resource_is_1d(&lpr->base))
117            align_y = 1;
118         else
119            align_y = LP_RASTER_BLOCK_SIZE;
120      }
121
122      nblocksx = util_format_get_nblocksx(pt->format,
123                                          align(width, align_x));
124      nblocksy = util_format_get_nblocksy(pt->format,
125                                          align(height, align_y));
126      block_size = util_format_get_blocksize(pt->format);
127
128      if (util_format_is_compressed(pt->format))
129         lpr->row_stride[level] = nblocksx * block_size;
130      else
131         lpr->row_stride[level] = align(nblocksx * block_size, util_get_cpu_caps()->cacheline);
132
133      lpr->img_stride[level] = (uint64_t)lpr->row_stride[level] * nblocksy;
134
135      /* Number of 3D image slices, cube faces or texture array layers */
136      if (lpr->base.target == PIPE_TEXTURE_CUBE) {
137         assert(layers == 6);
138      }
139
140      if (lpr->base.target == PIPE_TEXTURE_3D)
141         num_slices = depth;
142      else if (lpr->base.target == PIPE_TEXTURE_1D_ARRAY ||
143               lpr->base.target == PIPE_TEXTURE_2D_ARRAY ||
144               lpr->base.target == PIPE_TEXTURE_CUBE ||
145               lpr->base.target == PIPE_TEXTURE_CUBE_ARRAY)
146         num_slices = layers;
147      else
148         num_slices = 1;
149
150      mipsize = lpr->img_stride[level] * num_slices;
151      lpr->mip_offsets[level] = total_size;
152
153      total_size += align64(mipsize, mip_align);
154
155      /* Compute size of next mipmap level */
156      width = u_minify(width, 1);
157      height = u_minify(height, 1);
158      depth = u_minify(depth, 1);
159   }
160
161   lpr->sample_stride = total_size;
162   total_size *= num_samples;
163
164   lpr->size_required = total_size;
165   if (allocate) {
166      if (total_size > LP_MAX_TEXTURE_SIZE)
167         goto fail;
168
169      lpr->tex_data = align_malloc(total_size, mip_align);
170      if (!lpr->tex_data) {
171         return FALSE;
172      }
173      else {
174         memset(lpr->tex_data, 0, total_size);
175      }
176   }
177
178   return TRUE;
179
180fail:
181   return FALSE;
182}
183
184
185/**
186 * Check the size of the texture specified by 'res'.
187 * \return TRUE if OK, FALSE if too large.
188 */
189static bool
190llvmpipe_can_create_resource(struct pipe_screen *screen,
191                             const struct pipe_resource *res)
192{
193   struct llvmpipe_resource lpr;
194   memset(&lpr, 0, sizeof(lpr));
195   lpr.base = *res;
196   if (!llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, false))
197      return false;
198
199   return lpr.size_required <= LP_MAX_TEXTURE_SIZE;
200}
201
202
203static boolean
204llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
205                              struct llvmpipe_resource *lpr,
206                              const void *map_front_private)
207{
208   struct sw_winsys *winsys = screen->winsys;
209
210   /* Round up the surface size to a multiple of the tile size to
211    * avoid tile clipping.
212    */
213   const unsigned width = MAX2(1, align(lpr->base.width0, TILE_SIZE));
214   const unsigned height = MAX2(1, align(lpr->base.height0, TILE_SIZE));
215
216   lpr->dt = winsys->displaytarget_create(winsys,
217                                          lpr->base.bind,
218                                          lpr->base.format,
219                                          width, height,
220                                          64,
221                                          map_front_private,
222                                          &lpr->row_stride[0] );
223
224   return lpr->dt != NULL;
225}
226
227
228static struct pipe_resource *
229llvmpipe_resource_create_all(struct pipe_screen *_screen,
230                             const struct pipe_resource *templat,
231                             const void *map_front_private, bool alloc_backing)
232{
233   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
234   struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
235   if (!lpr)
236      return NULL;
237
238   lpr->base = *templat;
239   lpr->screen = screen;
240   pipe_reference_init(&lpr->base.reference, 1);
241   lpr->base.screen = &screen->base;
242
243   /* assert(lpr->base.bind); */
244
245   if (llvmpipe_resource_is_texture(&lpr->base)) {
246      if (lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
247                            PIPE_BIND_SCANOUT |
248                            PIPE_BIND_SHARED)) {
249         /* displayable surface */
250         if (!llvmpipe_displaytarget_layout(screen, lpr, map_front_private))
251            goto fail;
252      }
253      else {
254         /* texture map */
255         if (!llvmpipe_texture_layout(screen, lpr, alloc_backing))
256            goto fail;
257      }
258   }
259   else {
260      /* other data (vertex buffer, const buffer, etc) */
261      const uint bytes = templat->width0;
262      assert(util_format_get_blocksize(templat->format) == 1);
263      assert(templat->height0 == 1);
264      assert(templat->depth0 == 1);
265      assert(templat->last_level == 0);
266      /*
267       * Reserve some extra storage since if we'd render to a buffer we
268       * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element
269       * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE.
270       */
271      /*
272       * buffers don't really have stride but it's probably safer
273       * (for code doing same calculations for buffers and textures)
274       * to put something sane in there.
275       */
276      lpr->row_stride[0] = bytes;
277
278      lpr->size_required = bytes;
279      if (!(templat->flags & PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE))
280         lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float);
281
282      if (alloc_backing) {
283         lpr->data = align_malloc(lpr->size_required, 64);
284
285         if (!lpr->data)
286            goto fail;
287         memset(lpr->data, 0, bytes);
288      }
289   }
290
291   lpr->id = id_counter++;
292
293#ifdef DEBUG
294   mtx_lock(&resource_list_mutex);
295   list_addtail(&lpr->list, &resource_list.list);
296   mtx_unlock(&resource_list_mutex);
297#endif
298
299   return &lpr->base;
300
301 fail:
302   FREE(lpr);
303   return NULL;
304}
305
306static struct pipe_resource *
307llvmpipe_resource_create_front(struct pipe_screen *_screen,
308                               const struct pipe_resource *templat,
309                               const void *map_front_private)
310{
311   return llvmpipe_resource_create_all(_screen, templat, map_front_private, true);
312}
313
314static struct pipe_resource *
315llvmpipe_resource_create(struct pipe_screen *_screen,
316                         const struct pipe_resource *templat)
317{
318   return llvmpipe_resource_create_front(_screen, templat, NULL);
319}
320
321static struct pipe_resource *
322llvmpipe_resource_create_unbacked(struct pipe_screen *_screen,
323                                  const struct pipe_resource *templat,
324                                  uint64_t *size_required)
325{
326   struct pipe_resource *pt;
327   struct llvmpipe_resource *lpr;
328   pt = llvmpipe_resource_create_all(_screen, templat, NULL, false);
329   if (!pt)
330      return pt;
331   lpr = llvmpipe_resource(pt);
332   lpr->backable = true;
333   *size_required = lpr->size_required;
334   return pt;
335}
336
337static struct pipe_memory_object *
338llvmpipe_memobj_create_from_handle(struct pipe_screen *pscreen,
339                                   struct winsys_handle *handle,
340                                   bool dedicated)
341{
342#ifdef PIPE_MEMORY_FD
343   struct llvmpipe_memory_object *memobj = CALLOC_STRUCT(llvmpipe_memory_object);
344
345   if (handle->type == WINSYS_HANDLE_TYPE_FD &&
346       pscreen->import_memory_fd(pscreen, handle->handle, &memobj->data, &memobj->size)) {
347      return &memobj->b;
348   }
349   free(memobj);
350#endif
351   return NULL;
352}
353
354static void
355llvmpipe_memobj_destroy(struct pipe_screen *pscreen,
356                        struct pipe_memory_object *memobj)
357{
358   if (!memobj)
359      return;
360   struct llvmpipe_memory_object *lpmo = llvmpipe_memory_object(memobj);
361#ifdef PIPE_MEMORY_FD
362   pscreen->free_memory_fd(pscreen, lpmo->data);
363#endif
364   free(lpmo);
365}
366
367static struct pipe_resource *
368llvmpipe_resource_from_memobj(struct pipe_screen *pscreen,
369                              const struct pipe_resource *templat,
370                              struct pipe_memory_object *memobj,
371                              uint64_t offset)
372{
373   if (!memobj)
374      return NULL;
375   struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
376   struct llvmpipe_memory_object *lpmo = llvmpipe_memory_object(memobj);
377   struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
378   lpr->base = *templat;
379
380   lpr->screen = screen;
381   pipe_reference_init(&lpr->base.reference, 1);
382   lpr->base.screen = &screen->base;
383
384   if (llvmpipe_resource_is_texture(&lpr->base)) {
385      /* texture map */
386      if (!llvmpipe_texture_layout(screen, lpr, false))
387         goto fail;
388      if(lpmo->size < lpr->size_required)
389         goto fail;
390      lpr->tex_data = lpmo->data;
391   }
392   else {
393      /* other data (vertex buffer, const buffer, etc) */
394      const uint bytes = templat->width0;
395      assert(util_format_get_blocksize(templat->format) == 1);
396      assert(templat->height0 == 1);
397      assert(templat->depth0 == 1);
398      assert(templat->last_level == 0);
399      /*
400       * Reserve some extra storage since if we'd render to a buffer we
401       * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element
402       * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE.
403       */
404      /*
405       * buffers don't really have stride but it's probably safer
406       * (for code doing same calculations for buffers and textures)
407       * to put something reasonable in there.
408       */
409      lpr->row_stride[0] = bytes;
410
411      lpr->size_required = bytes;
412      if (!(templat->flags & PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE))
413         lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float);
414
415      if(lpmo->size < lpr->size_required)
416         goto fail;
417      lpr->data = lpmo->data;
418   }
419   lpr->id = id_counter++;
420   lpr->imported_memory = true;
421
422#ifdef DEBUG
423   mtx_lock(&resource_list_mutex);
424   list_addtail(&lpr->list, &resource_list.list);
425   mtx_unlock(&resource_list_mutex);
426#endif
427
428   return &lpr->base;
429
430fail:
431   free(lpr);
432   return NULL;
433}
434
435static void
436llvmpipe_resource_destroy(struct pipe_screen *pscreen,
437                          struct pipe_resource *pt)
438{
439   struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
440   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
441
442   if (!lpr->backable && !lpr->user_ptr) {
443      if (lpr->dt) {
444         /* display target */
445         struct sw_winsys *winsys = screen->winsys;
446         winsys->displaytarget_destroy(winsys, lpr->dt);
447      }
448      else if (llvmpipe_resource_is_texture(pt)) {
449         /* free linear image data */
450         if (lpr->tex_data) {
451            if (!lpr->imported_memory)
452               align_free(lpr->tex_data);
453            lpr->tex_data = NULL;
454         }
455      }
456      else if (lpr->data) {
457            if (!lpr->imported_memory)
458               align_free(lpr->data);
459      }
460   }
461#ifdef DEBUG
462   mtx_lock(&resource_list_mutex);
463   if (!list_is_empty(&lpr->list))
464      list_del(&lpr->list);
465   mtx_unlock(&resource_list_mutex);
466#endif
467
468   FREE(lpr);
469}
470
471
472/**
473 * Map a resource for read/write.
474 */
475void *
476llvmpipe_resource_map(struct pipe_resource *resource,
477                      unsigned level,
478                      unsigned layer,
479                      enum lp_texture_usage tex_usage)
480{
481   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
482   uint8_t *map;
483
484   assert(level < LP_MAX_TEXTURE_LEVELS);
485   assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
486
487   assert(tex_usage == LP_TEX_USAGE_READ ||
488          tex_usage == LP_TEX_USAGE_READ_WRITE ||
489          tex_usage == LP_TEX_USAGE_WRITE_ALL);
490
491   if (lpr->dt) {
492      /* display target */
493      struct llvmpipe_screen *screen = lpr->screen;
494      struct sw_winsys *winsys = screen->winsys;
495      unsigned dt_usage;
496
497      if (tex_usage == LP_TEX_USAGE_READ) {
498         dt_usage = PIPE_MAP_READ;
499      }
500      else {
501         dt_usage = PIPE_MAP_READ_WRITE;
502      }
503
504      assert(level == 0);
505      assert(layer == 0);
506
507      /* FIXME: keep map count? */
508      map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
509
510      /* install this linear image in texture data structure */
511      lpr->tex_data = map;
512
513      return map;
514   }
515   else if (llvmpipe_resource_is_texture(resource)) {
516
517      map = llvmpipe_get_texture_image_address(lpr, layer, level);
518      return map;
519   }
520   else {
521      return lpr->data;
522   }
523}
524
525
526/**
527 * Unmap a resource.
528 */
529void
530llvmpipe_resource_unmap(struct pipe_resource *resource,
531                       unsigned level,
532                       unsigned layer)
533{
534   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
535
536   if (lpr->dt) {
537      /* display target */
538      struct llvmpipe_screen *lp_screen = lpr->screen;
539      struct sw_winsys *winsys = lp_screen->winsys;
540
541      assert(level == 0);
542      assert(layer == 0);
543
544      winsys->displaytarget_unmap(winsys, lpr->dt);
545   }
546}
547
548
549void *
550llvmpipe_resource_data(struct pipe_resource *resource)
551{
552   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
553
554   assert(!llvmpipe_resource_is_texture(resource));
555
556   return lpr->data;
557}
558
559
560static struct pipe_resource *
561llvmpipe_resource_from_handle(struct pipe_screen *_screen,
562                              const struct pipe_resource *template,
563                              struct winsys_handle *whandle,
564                              unsigned usage)
565{
566   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
567   struct sw_winsys *winsys = screen->winsys;
568   struct llvmpipe_resource *lpr;
569
570   /* XXX Seems like from_handled depth textures doesn't work that well */
571
572   lpr = CALLOC_STRUCT(llvmpipe_resource);
573   if (!lpr) {
574      goto no_lpr;
575   }
576
577   lpr->base = *template;
578   lpr->screen = screen;
579   pipe_reference_init(&lpr->base.reference, 1);
580   lpr->base.screen = _screen;
581
582   /*
583    * Looks like unaligned displaytargets work just fine,
584    * at least sampler/render ones.
585    */
586#if 0
587   assert(lpr->base.width0 == width);
588   assert(lpr->base.height0 == height);
589#endif
590
591   lpr->dt = winsys->displaytarget_from_handle(winsys,
592                                               template,
593                                               whandle,
594                                               &lpr->row_stride[0]);
595   if (!lpr->dt) {
596      goto no_dt;
597   }
598
599   lpr->id = id_counter++;
600
601#ifdef DEBUG
602   mtx_lock(&resource_list_mutex);
603   list_addtail(&lpr->list, &resource_list.list);
604   mtx_unlock(&resource_list_mutex);
605#endif
606
607   return &lpr->base;
608
609no_dt:
610   FREE(lpr);
611no_lpr:
612   return NULL;
613}
614
615
616static bool
617llvmpipe_resource_get_handle(struct pipe_screen *screen,
618                             struct pipe_context *ctx,
619                            struct pipe_resource *pt,
620                            struct winsys_handle *whandle,
621                             unsigned usage)
622{
623   struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
624   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
625
626   assert(lpr->dt);
627   if (!lpr->dt)
628      return false;
629
630   return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
631}
632
633static struct pipe_resource *
634llvmpipe_resource_from_user_memory(struct pipe_screen *_screen,
635				   const struct pipe_resource *resource,
636				   void *user_memory)
637{
638   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
639   struct llvmpipe_resource *lpr;
640
641   lpr = CALLOC_STRUCT(llvmpipe_resource);
642   if (!lpr) {
643      return NULL;
644   }
645
646   lpr->base = *resource;
647   lpr->screen = screen;
648   pipe_reference_init(&lpr->base.reference, 1);
649   lpr->base.screen = _screen;
650
651   if (llvmpipe_resource_is_texture(&lpr->base)) {
652      if (!llvmpipe_texture_layout(screen, lpr, false))
653         goto fail;
654
655      lpr->tex_data = user_memory;
656   } else
657      lpr->data = user_memory;
658   lpr->user_ptr = true;
659#ifdef DEBUG
660   mtx_lock(&resource_list_mutex);
661   list_addtail(&lpr->list, &resource_list.list);
662   mtx_unlock(&resource_list_mutex);
663#endif
664   return &lpr->base;
665fail:
666   FREE(lpr);
667   return NULL;
668}
669
670void *
671llvmpipe_transfer_map_ms( struct pipe_context *pipe,
672                          struct pipe_resource *resource,
673                          unsigned level,
674                          unsigned usage,
675                          unsigned sample,
676                          const struct pipe_box *box,
677                          struct pipe_transfer **transfer )
678{
679   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
680   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
681   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
682   struct llvmpipe_transfer *lpt;
683   struct pipe_transfer *pt;
684   ubyte *map;
685   enum pipe_format format;
686   enum lp_texture_usage tex_usage;
687   const char *mode;
688
689   assert(resource);
690   assert(level <= resource->last_level);
691
692   /*
693    * Transfers, like other pipe operations, must happen in order, so flush the
694    * context if necessary.
695    */
696   if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) {
697      boolean read_only = !(usage & PIPE_MAP_WRITE);
698      boolean do_not_block = !!(usage & PIPE_MAP_DONTBLOCK);
699      if (!llvmpipe_flush_resource(pipe, resource,
700                                   level,
701                                   read_only,
702                                   TRUE, /* cpu_access */
703                                   do_not_block,
704                                   __FUNCTION__)) {
705         /*
706          * It would have blocked, but gallium frontend requested no to.
707          */
708         assert(do_not_block);
709         return NULL;
710      }
711   }
712
713   /* Check if we're mapping a current constant buffer */
714   if ((usage & PIPE_MAP_WRITE) &&
715       (resource->bind & PIPE_BIND_CONSTANT_BUFFER)) {
716      unsigned i;
717      for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) {
718         if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][i].buffer) {
719            /* constants may have changed */
720            llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
721            break;
722         }
723      }
724   }
725
726   lpt = CALLOC_STRUCT(llvmpipe_transfer);
727   if (!lpt)
728      return NULL;
729   pt = &lpt->base;
730   pipe_resource_reference(&pt->resource, resource);
731   pt->box = *box;
732   pt->level = level;
733   pt->stride = lpr->row_stride[level];
734   pt->layer_stride = lpr->img_stride[level];
735   pt->usage = usage;
736   *transfer = pt;
737
738   assert(level < LP_MAX_TEXTURE_LEVELS);
739
740   /*
741   printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
742          transfer->x, transfer->y, transfer->width, transfer->height,
743          transfer->texture->width0,
744          transfer->texture->height0,
745          transfer->usage);
746   */
747
748   if (usage == PIPE_MAP_READ) {
749      tex_usage = LP_TEX_USAGE_READ;
750      mode = "read";
751   }
752   else {
753      tex_usage = LP_TEX_USAGE_READ_WRITE;
754      mode = "read/write";
755   }
756
757   if (0) {
758      printf("transfer map tex %u  mode %s\n", lpr->id, mode);
759   }
760
761   format = lpr->base.format;
762
763   map = llvmpipe_resource_map(resource,
764                               level,
765                               box->z,
766                               tex_usage);
767
768
769   /* May want to do different things here depending on read/write nature
770    * of the map:
771    */
772   if (usage & PIPE_MAP_WRITE) {
773      /* Do something to notify sharing contexts of a texture change.
774       */
775      screen->timestamp++;
776   }
777
778   map +=
779      box->y / util_format_get_blockheight(format) * pt->stride +
780      box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
781
782   map += sample * lpr->sample_stride;
783   return map;
784}
785
786static void *
787llvmpipe_transfer_map( struct pipe_context *pipe,
788                       struct pipe_resource *resource,
789                       unsigned level,
790                       unsigned usage,
791                       const struct pipe_box *box,
792                       struct pipe_transfer **transfer )
793{
794   return llvmpipe_transfer_map_ms(pipe, resource, level, usage, 0, box, transfer);
795}
796
797static void
798llvmpipe_transfer_unmap(struct pipe_context *pipe,
799                        struct pipe_transfer *transfer)
800{
801   assert(transfer->resource);
802
803   llvmpipe_resource_unmap(transfer->resource,
804                           transfer->level,
805                           transfer->box.z);
806
807   /* Effectively do the texture_update work here - if texture images
808    * needed post-processing to put them into hardware layout, this is
809    * where it would happen.  For llvmpipe, nothing to do.
810    */
811   assert (transfer->resource);
812   pipe_resource_reference(&transfer->resource, NULL);
813   FREE(transfer);
814}
815
816unsigned int
817llvmpipe_is_resource_referenced( struct pipe_context *pipe,
818                                 struct pipe_resource *presource,
819                                 unsigned level)
820{
821   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
822   if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
823                            PIPE_BIND_RENDER_TARGET |
824                            PIPE_BIND_SAMPLER_VIEW |
825                            PIPE_BIND_SHADER_BUFFER |
826                            PIPE_BIND_SHADER_IMAGE)))
827      return LP_UNREFERENCED;
828
829   return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
830}
831
832
833/**
834 * Returns the largest possible alignment for a format in llvmpipe
835 */
836unsigned
837llvmpipe_get_format_alignment( enum pipe_format format )
838{
839   const struct util_format_description *desc = util_format_description(format);
840   unsigned size = 0;
841   unsigned bytes;
842   unsigned i;
843
844   for (i = 0; i < desc->nr_channels; ++i) {
845      size += desc->channel[i].size;
846   }
847
848   bytes = size / 8;
849
850   if (!util_is_power_of_two_or_zero(bytes)) {
851      bytes /= desc->nr_channels;
852   }
853
854   if (bytes % 2 || bytes < 1) {
855      return 1;
856   } else {
857      return bytes;
858   }
859}
860
861
862/**
863 * Create buffer which wraps user-space data.
864 * XXX unreachable.
865 */
866struct pipe_resource *
867llvmpipe_user_buffer_create(struct pipe_screen *screen,
868                            void *ptr,
869                            unsigned bytes,
870                            unsigned bind_flags)
871{
872   struct llvmpipe_resource *buffer;
873
874   buffer = CALLOC_STRUCT(llvmpipe_resource);
875   if (!buffer)
876      return NULL;
877
878   buffer->screen = llvmpipe_screen(screen);
879   pipe_reference_init(&buffer->base.reference, 1);
880   buffer->base.screen = screen;
881   buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
882   buffer->base.bind = bind_flags;
883   buffer->base.usage = PIPE_USAGE_IMMUTABLE;
884   buffer->base.flags = 0;
885   buffer->base.width0 = bytes;
886   buffer->base.height0 = 1;
887   buffer->base.depth0 = 1;
888   buffer->base.array_size = 1;
889   buffer->user_ptr = true;
890   buffer->data = ptr;
891
892   return &buffer->base;
893}
894
895
896/**
897 * Compute size (in bytes) need to store a texture image / mipmap level,
898 * for just one cube face, one array layer or one 3D texture slice
899 */
900static unsigned
901tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level)
902{
903   return lpr->img_stride[level];
904}
905
906
907/**
908 * Return pointer to a 2D texture image/face/slice.
909 * No tiled/linear conversion is done.
910 */
911ubyte *
912llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
913                                   unsigned face_slice, unsigned level)
914{
915   unsigned offset;
916
917   assert(llvmpipe_resource_is_texture(&lpr->base));
918
919   offset = lpr->mip_offsets[level];
920
921   if (face_slice > 0)
922      offset += face_slice * tex_image_face_size(lpr, level);
923
924   return (ubyte *) lpr->tex_data + offset;
925}
926
927
928/**
929 * Return size of resource in bytes
930 */
931unsigned
932llvmpipe_resource_size(const struct pipe_resource *resource)
933{
934   const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
935   unsigned size = 0;
936
937   if (llvmpipe_resource_is_texture(resource)) {
938      /* Note this will always return 0 for displaytarget resources */
939      size = lpr->total_alloc_size;
940   }
941   else {
942      size = resource->width0;
943   }
944   return size;
945}
946
947static void
948llvmpipe_memory_barrier(struct pipe_context *pipe,
949			unsigned flags)
950{
951   /* this may be an overly large hammer for this nut. */
952   llvmpipe_finish(pipe, "barrier");
953}
954
955static struct pipe_memory_allocation *llvmpipe_allocate_memory(struct pipe_screen *screen, uint64_t size)
956{
957   uint64_t alignment;
958   if (!os_get_page_size(&alignment))
959      alignment = 256;
960   return os_malloc_aligned(size, alignment);
961}
962
963static void llvmpipe_free_memory(struct pipe_screen *screen,
964                                 struct pipe_memory_allocation *pmem)
965{
966   os_free_aligned(pmem);
967}
968
969#ifdef PIPE_MEMORY_FD
970
971static const char *driver_id = "llvmpipe" MESA_GIT_SHA1;
972
973static struct pipe_memory_allocation *llvmpipe_allocate_memory_fd(struct pipe_screen *screen, uint64_t size, int *fd)
974{
975   uint64_t alignment;
976   if (!os_get_page_size(&alignment))
977      alignment = 256;
978   return os_malloc_aligned_fd(size, alignment, fd, "llvmpipe memory fd", driver_id);
979}
980
981static bool llvmpipe_import_memory_fd(struct pipe_screen *screen, int fd, struct pipe_memory_allocation **ptr, uint64_t *size)
982{
983   return os_import_memory_fd(fd, (void**)ptr, size, driver_id);
984}
985
986static void llvmpipe_free_memory_fd(struct pipe_screen *screen,
987                                    struct pipe_memory_allocation *pmem)
988{
989   os_free_fd(pmem);
990}
991
992#endif
993
994static bool llvmpipe_resource_bind_backing(struct pipe_screen *screen,
995                                           struct pipe_resource *pt,
996                                           struct pipe_memory_allocation *pmem,
997                                           uint64_t offset)
998{
999   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
1000
1001   if (!lpr->backable)
1002      return FALSE;
1003
1004   if (llvmpipe_resource_is_texture(&lpr->base)) {
1005      if (lpr->size_required > LP_MAX_TEXTURE_SIZE)
1006         return FALSE;
1007
1008      lpr->tex_data = (char *)pmem + offset;
1009   } else
1010      lpr->data = (char *)pmem + offset;
1011   lpr->backing_offset = offset;
1012
1013   return TRUE;
1014}
1015
1016static void *llvmpipe_map_memory(struct pipe_screen *screen,
1017                                 struct pipe_memory_allocation *pmem)
1018{
1019   return pmem;
1020}
1021
1022static void llvmpipe_unmap_memory(struct pipe_screen *screen,
1023                                  struct pipe_memory_allocation *pmem)
1024{
1025}
1026
1027#ifdef DEBUG
1028void
1029llvmpipe_print_resources(void)
1030{
1031   struct llvmpipe_resource *lpr;
1032   unsigned n = 0, total = 0;
1033
1034   debug_printf("LLVMPIPE: current resources:\n");
1035   mtx_lock(&resource_list_mutex);
1036   LIST_FOR_EACH_ENTRY(lpr, &resource_list.list, list) {
1037      unsigned size = llvmpipe_resource_size(&lpr->base);
1038      debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
1039                   lpr->id, (void *) lpr,
1040                   lpr->base.width0, lpr->base.height0, lpr->base.depth0,
1041                   size, lpr->base.reference.count);
1042      total += size;
1043      n++;
1044   }
1045   mtx_unlock(&resource_list_mutex);
1046   debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
1047}
1048#endif
1049
1050static void
1051llvmpipe_get_resource_info(struct pipe_screen *screen,
1052			   struct pipe_resource *resource,
1053			   unsigned *stride,
1054			   unsigned *offset)
1055{
1056   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
1057
1058   *stride = lpr->row_stride[0];
1059   *offset = 0;
1060}
1061
1062static bool
1063llvmpipe_resource_get_param(struct pipe_screen *screen,
1064                            struct pipe_context *context,
1065                            struct pipe_resource *resource,
1066                            unsigned plane,
1067                            unsigned layer,
1068                            unsigned level,
1069                            enum pipe_resource_param param,
1070                            unsigned handle_usage,
1071                            uint64_t *value)
1072{
1073   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
1074   struct winsys_handle whandle;
1075
1076   switch (param) {
1077   case PIPE_RESOURCE_PARAM_NPLANES:
1078      *value = 1;
1079      return true;
1080   case PIPE_RESOURCE_PARAM_STRIDE:
1081      *value = lpr->row_stride[level];
1082      return true;
1083   case PIPE_RESOURCE_PARAM_OFFSET:
1084      *value = lpr->mip_offsets[level] + (lpr->img_stride[level] * layer);
1085      return true;
1086   case PIPE_RESOURCE_PARAM_LAYER_STRIDE:
1087      *value = lpr->img_stride[level];
1088      return true;
1089#ifndef _WIN32
1090   case PIPE_RESOURCE_PARAM_MODIFIER:
1091      *value = DRM_FORMAT_MOD_INVALID;
1092      return true;
1093#endif
1094   case PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED:
1095   case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS:
1096   case PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD:
1097      if (!lpr->dt)
1098         return false;
1099
1100      memset(&whandle, 0, sizeof(whandle));
1101      if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED)
1102         whandle.type = WINSYS_HANDLE_TYPE_SHARED;
1103      else if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS)
1104         whandle.type = WINSYS_HANDLE_TYPE_KMS;
1105      else if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD)
1106         whandle.type = WINSYS_HANDLE_TYPE_FD;
1107
1108      if (!llvmpipe_resource_get_handle(screen, context, resource, &whandle, handle_usage))
1109         return false;
1110      *value = (uint64_t)(uintptr_t)whandle.handle;
1111      return true;
1112   default:
1113      break;
1114   }
1115   assert(0);
1116   *value = 0;
1117   return false;
1118}
1119
1120void
1121llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
1122{
1123#ifdef DEBUG
1124   /* init linked list for tracking resources */
1125   {
1126      static boolean first_call = TRUE;
1127      if (first_call) {
1128         memset(&resource_list, 0, sizeof(resource_list));
1129         list_inithead(&resource_list.list);
1130         first_call = FALSE;
1131      }
1132   }
1133#endif
1134
1135   screen->resource_create = llvmpipe_resource_create;
1136/*   screen->resource_create_front = llvmpipe_resource_create_front; */
1137   screen->resource_destroy = llvmpipe_resource_destroy;
1138   screen->resource_from_handle = llvmpipe_resource_from_handle;
1139   screen->resource_from_memobj = llvmpipe_resource_from_memobj;
1140   screen->resource_get_handle = llvmpipe_resource_get_handle;
1141   screen->can_create_resource = llvmpipe_can_create_resource;
1142
1143   screen->resource_create_unbacked = llvmpipe_resource_create_unbacked;
1144
1145   screen->memobj_create_from_handle = llvmpipe_memobj_create_from_handle;
1146   screen->memobj_destroy = llvmpipe_memobj_destroy;
1147
1148   screen->resource_get_info = llvmpipe_get_resource_info;
1149   screen->resource_get_param = llvmpipe_resource_get_param;
1150   screen->resource_from_user_memory = llvmpipe_resource_from_user_memory;
1151   screen->allocate_memory = llvmpipe_allocate_memory;
1152   screen->free_memory = llvmpipe_free_memory;
1153#ifdef PIPE_MEMORY_FD
1154   screen->allocate_memory_fd = llvmpipe_allocate_memory_fd;
1155   screen->import_memory_fd = llvmpipe_import_memory_fd;
1156   screen->free_memory_fd = llvmpipe_free_memory_fd;
1157#endif
1158   screen->map_memory = llvmpipe_map_memory;
1159   screen->unmap_memory = llvmpipe_unmap_memory;
1160
1161   screen->resource_bind_backing = llvmpipe_resource_bind_backing;
1162}
1163
1164
1165void
1166llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
1167{
1168   pipe->buffer_map = llvmpipe_transfer_map;
1169   pipe->buffer_unmap = llvmpipe_transfer_unmap;
1170   pipe->texture_map = llvmpipe_transfer_map;
1171   pipe->texture_unmap = llvmpipe_transfer_unmap;
1172
1173   pipe->transfer_flush_region = u_default_transfer_flush_region;
1174   pipe->buffer_subdata = u_default_buffer_subdata;
1175   pipe->texture_subdata = u_default_texture_subdata;
1176
1177   pipe->memory_barrier = llvmpipe_memory_barrier;
1178}
1179