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