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