blob: ae4c61efb3bee91e072a545578a6de91ae13c442 [file] [log] [blame]
Brian18119652008-01-21 20:26:40 -07001/**************************************************************************
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>
Brian Paul88360912008-11-05 17:20:35 -070031 * Brian Paul
Brian18119652008-01-21 20:26:40 -070032 */
33
34#include "pipe/p_context.h"
35#include "pipe/p_defines.h"
36#include "pipe/p_inlines.h"
Zack Rusinadfbba42009-01-30 15:56:00 -050037#include "pipe/internal/p_winsys_screen.h"
Brian6ba9fb92008-08-25 11:31:59 -060038#include "util/u_math.h"
39#include "util/u_memory.h"
Brian18119652008-01-21 20:26:40 -070040
41#include "cell_context.h"
42#include "cell_state.h"
43#include "cell_texture.h"
44
Brian18119652008-01-21 20:26:40 -070045
Brian Paul88360912008-11-05 17:20:35 -070046
Brian18119652008-01-21 20:26:40 -070047static void
Brian Paulb7609be2008-10-14 10:05:23 -060048cell_texture_layout(struct cell_texture *ct)
Brian18119652008-01-21 20:26:40 -070049{
Brian Paulb7609be2008-10-14 10:05:23 -060050 struct pipe_texture *pt = &ct->base;
Brian18119652008-01-21 20:26:40 -070051 unsigned level;
52 unsigned width = pt->width[0];
53 unsigned height = pt->height[0];
54 unsigned depth = pt->depth[0];
55
Brian Paulb7609be2008-10-14 10:05:23 -060056 ct->buffer_size = 0;
Brian18119652008-01-21 20:26:40 -070057
Brian Paul192b7f22009-02-24 20:58:46 -070058 for (level = 0; level <= pt->last_level; level++) {
Brian Paul8b8952a2008-09-03 11:43:11 -060059 unsigned size;
60 unsigned w_tile, h_tile;
61
Brian Paul978799b2008-10-13 16:43:11 -060062 assert(level < CELL_MAX_TEXTURE_LEVELS);
63
Brian Paul8b8952a2008-09-03 11:43:11 -060064 /* width, height, rounded up to tile size */
65 w_tile = align(width, TILE_SIZE);
66 h_tile = align(height, TILE_SIZE);
67
Brian18119652008-01-21 20:26:40 -070068 pt->width[level] = width;
69 pt->height[level] = height;
70 pt->depth[level] = depth;
Brian Paul8b8952a2008-09-03 11:43:11 -060071 pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w_tile);
72 pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h_tile);
Brian18119652008-01-21 20:26:40 -070073
Brian Paulb7609be2008-10-14 10:05:23 -060074 ct->stride[level] = pt->nblocksx[level] * pt->block.size;
Brian6ba9fb92008-08-25 11:31:59 -060075
Brian Paulb7609be2008-10-14 10:05:23 -060076 ct->level_offset[level] = ct->buffer_size;
Brian18119652008-01-21 20:26:40 -070077
Brian Paul8b8952a2008-09-03 11:43:11 -060078 size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
79 if (pt->target == PIPE_TEXTURE_CUBE)
80 size *= 6;
81 else
82 size *= depth;
83
Brian Paulb7609be2008-10-14 10:05:23 -060084 ct->buffer_size += size;
Brian18119652008-01-21 20:26:40 -070085
Brian Paul192b7f22009-02-24 20:58:46 -070086 width = minify(width);
Brian18119652008-01-21 20:26:40 -070087 height = minify(height);
88 depth = minify(depth);
89 }
90}
91
92
Brian9171e632008-02-20 14:21:45 -070093static struct pipe_texture *
Brian Paul01a76f42008-08-27 16:45:41 -060094cell_texture_create(struct pipe_screen *screen,
95 const struct pipe_texture *templat)
Brianf04736c2008-02-27 09:55:17 -070096{
Brian Paulb7609be2008-10-14 10:05:23 -060097 struct cell_texture *ct = CALLOC_STRUCT(cell_texture);
98 if (!ct)
Brian31c98ea2008-02-06 09:24:30 -070099 return NULL;
Brian18119652008-01-21 20:26:40 -0700100
Brian Paulb7609be2008-10-14 10:05:23 -0600101 ct->base = *templat;
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100102 pipe_reference_init(&ct->base.reference, 1);
Brian Paulb7609be2008-10-14 10:05:23 -0600103 ct->base.screen = screen;
Brian18119652008-01-21 20:26:40 -0700104
Brian Paulb7609be2008-10-14 10:05:23 -0600105 cell_texture_layout(ct);
Brian18119652008-01-21 20:26:40 -0700106
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100107 ct->buffer = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_PIXEL,
Zack Rusinb3028ac2009-01-29 21:43:15 -0500108 ct->buffer_size);
Brian18119652008-01-21 20:26:40 -0700109
Brian Paulb7609be2008-10-14 10:05:23 -0600110 if (!ct->buffer) {
111 FREE(ct);
Brian31c98ea2008-02-06 09:24:30 -0700112 return NULL;
Brian18119652008-01-21 20:26:40 -0700113 }
114
Brian Paulb7609be2008-10-14 10:05:23 -0600115 return &ct->base;
Brian18119652008-01-21 20:26:40 -0700116}
117
Brian31c98ea2008-02-06 09:24:30 -0700118
Brian9171e632008-02-20 14:21:45 -0700119static void
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100120cell_texture_destroy(struct pipe_texture *pt)
Brianf04736c2008-02-27 09:55:17 -0700121{
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100122 struct cell_texture *ct = cell_texture(pt);
Brian18119652008-01-21 20:26:40 -0700123
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100124 if (ct->mapped) {
Brian Paulca06c0c2009-03-04 09:34:46 -0700125 pipe_buffer_unmap(ct->buffer->screen, ct->buffer);
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100126 ct->mapped = NULL;
Brian18119652008-01-21 20:26:40 -0700127 }
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100128
129 pipe_buffer_reference(&ct->buffer, NULL);
130
131 FREE(ct);
Brian18119652008-01-21 20:26:40 -0700132}
133
134
Briand5640a22008-02-20 13:24:52 -0700135
Brian Paul0bee1562008-10-14 10:55:38 -0600136/**
137 * Convert image from linear layout to tiled layout. 4-byte pixels.
138 */
139static void
Brian Paul58ea98d2008-10-14 12:41:46 -0600140twiddle_image_uint(uint w, uint h, uint tile_size, uint *dst,
Brian Paul3baf83d2008-10-14 12:10:27 -0600141 uint src_stride, const uint *src)
Brian Paul0bee1562008-10-14 10:55:38 -0600142{
143 const uint tile_size2 = tile_size * tile_size;
144 const uint h_t = (h + tile_size - 1) / tile_size;
145 const uint w_t = (w + tile_size - 1) / tile_size;
146
147 uint it, jt; /* tile counters */
148 uint i, j; /* intra-tile counters */
149
Brian Paul3baf83d2008-10-14 12:10:27 -0600150 src_stride /= 4; /* convert from bytes to pixels */
151
Brian Paul0bee1562008-10-14 10:55:38 -0600152 /* loop over dest tiles */
153 for (it = 0; it < h_t; it++) {
154 for (jt = 0; jt < w_t; jt++) {
155 /* start of dest tile: */
156 uint *tdst = dst + (it * w_t + jt) * tile_size2;
Brian Paul38d396e2008-10-14 14:02:07 -0600157
158 /* compute size of this tile (may be smaller than tile_size) */
159 /* XXX note: a compiler bug was found here. That's why the code
160 * looks as it does.
161 */
162 uint tile_width = w - jt * tile_size;
163 tile_width = MIN2(tile_width, tile_size);
164 uint tile_height = h - it * tile_size;
165 tile_height = MIN2(tile_height, tile_size);
166
Brian Paul0bee1562008-10-14 10:55:38 -0600167 /* loop over texels in the tile */
Brian Paul0bee1562008-10-14 10:55:38 -0600168 for (i = 0; i < tile_height; i++) {
169 for (j = 0; j < tile_width; j++) {
170 const uint srci = it * tile_size + i;
171 const uint srcj = jt * tile_size + j;
Brian Paul58ea98d2008-10-14 12:41:46 -0600172 ASSERT(srci < h);
173 ASSERT(srcj < w);
Brian Paul3baf83d2008-10-14 12:10:27 -0600174 tdst[i * tile_size + j] = src[srci * src_stride + srcj];
Brian Paul0bee1562008-10-14 10:55:38 -0600175 }
176 }
177 }
178 }
Briand5640a22008-02-20 13:24:52 -0700179}
Brian Paul0bee1562008-10-14 10:55:38 -0600180
Brian Paul88360912008-11-05 17:20:35 -0700181
Jonathan White582ca6e2008-10-27 16:29:20 -0600182/**
183 * For Cell. Basically, rearrange the pixels/quads from this layout:
184 * +--+--+--+--+
185 * |p0|p1|p2|p3|....
186 * +--+--+--+--+
187 *
188 * to this layout:
189 * +--+--+
190 * |p0|p1|....
191 * +--+--+
192 * |p2|p3|
193 * +--+--+
194 */
195static void
196twiddle_tile(const uint *tileIn, uint *tileOut)
197{
198 int y, x;
199
200 for (y = 0; y < TILE_SIZE; y+=2) {
201 for (x = 0; x < TILE_SIZE; x+=2) {
202 int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
203 tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
204 tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
205 tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
206 tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
207 }
208 }
209}
210
Brian Paul88360912008-11-05 17:20:35 -0700211
Jonathan White582ca6e2008-10-27 16:29:20 -0600212/**
213 * Convert image from tiled layout to linear layout. 4-byte pixels.
214 */
215static void
216untwiddle_image_uint(uint w, uint h, uint tile_size, uint *dst,
Brian Paul88360912008-11-05 17:20:35 -0700217 uint dst_stride, const uint *src)
Jonathan White582ca6e2008-10-27 16:29:20 -0600218{
219 const uint tile_size2 = tile_size * tile_size;
220 const uint h_t = (h + tile_size - 1) / tile_size;
221 const uint w_t = (w + tile_size - 1) / tile_size;
222 uint *tile_buf;
Jonathan White582ca6e2008-10-27 16:29:20 -0600223 uint it, jt; /* tile counters */
224 uint i, j; /* intra-tile counters */
225
Brian Paul88360912008-11-05 17:20:35 -0700226 dst_stride /= 4; /* convert from bytes to pixels */
Jonathan White582ca6e2008-10-27 16:29:20 -0600227
228 tile_buf = align_malloc(tile_size * tile_size * 4, 16);
229
230 /* loop over src tiles */
231 for (it = 0; it < h_t; it++) {
232 for (jt = 0; jt < w_t; jt++) {
233 /* start of src tile: */
234 const uint *tsrc = src + (it * w_t + jt) * tile_size2;
235
236 twiddle_tile(tsrc, tile_buf);
237 tsrc = tile_buf;
238
239 /* compute size of this tile (may be smaller than tile_size) */
240 /* XXX note: a compiler bug was found here. That's why the code
241 * looks as it does.
242 */
243 uint tile_width = w - jt * tile_size;
244 tile_width = MIN2(tile_width, tile_size);
245 uint tile_height = h - it * tile_size;
246 tile_height = MIN2(tile_height, tile_size);
247
248 /* loop over texels in the tile */
249 for (i = 0; i < tile_height; i++) {
250 for (j = 0; j < tile_width; j++) {
251 uint dsti = it * tile_size + i;
252 uint dstj = jt * tile_size + j;
253 ASSERT(dsti < h);
254 ASSERT(dstj < w);
Brian Paul88360912008-11-05 17:20:35 -0700255 dst[dsti * dst_stride + dstj] = tsrc[i * tile_size + j];
Jonathan White582ca6e2008-10-27 16:29:20 -0600256 }
257 }
258 }
259 }
260
261 align_free(tile_buf);
262}
Brian Paul0bee1562008-10-14 10:55:38 -0600263
Brian Paul88360912008-11-05 17:20:35 -0700264
Brianf04736c2008-02-27 09:55:17 -0700265static struct pipe_surface *
Brian Paul01a76f42008-08-27 16:45:41 -0600266cell_get_tex_surface(struct pipe_screen *screen,
267 struct pipe_texture *pt,
268 unsigned face, unsigned level, unsigned zslice,
269 unsigned usage)
Brianf04736c2008-02-27 09:55:17 -0700270{
Brian Paulb7609be2008-10-14 10:05:23 -0600271 struct cell_texture *ct = cell_texture(pt);
Brian18119652008-01-21 20:26:40 -0700272 struct pipe_surface *ps;
273
Brian Paul91948cd2009-02-07 13:04:53 -0700274 ps = CALLOC_STRUCT(pipe_surface);
Brian18119652008-01-21 20:26:40 -0700275 if (ps) {
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100276 pipe_reference_init(&ps->reference, 1);
Brian Paul91948cd2009-02-07 13:04:53 -0700277 pipe_texture_reference(&ps->texture, pt);
Brian18119652008-01-21 20:26:40 -0700278 ps->format = pt->format;
Brian18119652008-01-21 20:26:40 -0700279 ps->width = pt->width[level];
280 ps->height = pt->height[level];
Brian Paulb7609be2008-10-14 10:05:23 -0600281 ps->offset = ct->level_offset[level];
Brian6ba9fb92008-08-25 11:31:59 -0600282 /* XXX may need to override usage flags (see sp_texture.c) */
Brian Paul192b7f22009-02-24 20:58:46 -0700283 ps->usage = usage;
Brian Paul439dca42008-09-03 13:31:14 -0600284 ps->face = face;
285 ps->level = level;
286 ps->zslice = zslice;
Brian18119652008-01-21 20:26:40 -0700287
Brian Paul192b7f22009-02-24 20:58:46 -0700288 if (pt->target == PIPE_TEXTURE_CUBE) {
289 ps->offset += face * pt->nblocksy[level] * ct->stride[level];
290 }
291 else if (pt->target == PIPE_TEXTURE_3D) {
292 ps->offset += zslice * pt->nblocksy[level] * ct->stride[level];
Brian Paul8b8952a2008-09-03 11:43:11 -0600293 }
294 else {
Jonathan White582ca6e2008-10-27 16:29:20 -0600295 assert(face == 0);
296 assert(zslice == 0);
297 }
Brian18119652008-01-21 20:26:40 -0700298 }
299 return ps;
300}
Brian425f2702008-01-28 17:23:44 -0700301
302
Brian Paul01a76f42008-08-27 16:45:41 -0600303static void
Brian Paulca06c0c2009-03-04 09:34:46 -0700304cell_tex_surface_destroy(struct pipe_surface *surf)
Brian Paul01a76f42008-08-27 16:45:41 -0600305{
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100306 pipe_texture_reference(&surf->texture, NULL);
307 FREE(surf);
Brian Paul01a76f42008-08-27 16:45:41 -0600308}
309
310
Brian Paul192b7f22009-02-24 20:58:46 -0700311/**
312 * Create new pipe_transfer object.
313 * This is used by the user to put tex data into a texture (and get it
314 * back out for glGetTexImage).
315 */
Brian Paul0a323fe2009-02-18 21:50:20 -0700316static struct pipe_transfer *
317cell_get_tex_transfer(struct pipe_screen *screen,
318 struct pipe_texture *texture,
319 unsigned face, unsigned level, unsigned zslice,
320 enum pipe_transfer_usage usage,
321 unsigned x, unsigned y, unsigned w, unsigned h)
322{
323 struct cell_texture *ct = cell_texture(texture);
324 struct cell_transfer *ctrans;
Brian Paul0a323fe2009-02-18 21:50:20 -0700325
326 assert(texture);
327 assert(level <= texture->last_level);
328
329 ctrans = CALLOC_STRUCT(cell_transfer);
Brian Paul0a323fe2009-02-18 21:50:20 -0700330 if (ctrans) {
Brian Paul192b7f22009-02-24 20:58:46 -0700331 struct pipe_transfer *pt = &ctrans->base;
Brian Paul0a323fe2009-02-18 21:50:20 -0700332 pipe_texture_reference(&pt->texture, texture);
333 pt->format = texture->format;
334 pt->block = texture->block;
335 pt->x = x;
336 pt->y = y;
337 pt->width = w;
338 pt->height = h;
339 pt->nblocksx = texture->nblocksx[level];
340 pt->nblocksy = texture->nblocksy[level];
341 pt->stride = ct->stride[level];
Brian Paul0a323fe2009-02-18 21:50:20 -0700342 pt->usage = usage;
343 pt->face = face;
344 pt->level = level;
345 pt->zslice = zslice;
346
Brian Paul192b7f22009-02-24 20:58:46 -0700347 ctrans->offset = ct->level_offset[level];
348
349 if (texture->target == PIPE_TEXTURE_CUBE) {
350 ctrans->offset += face * pt->nblocksy * pt->stride;
351 }
352 else if (texture->target == PIPE_TEXTURE_3D) {
353 ctrans->offset += zslice * pt->nblocksy * pt->stride;
Brian Paul0a323fe2009-02-18 21:50:20 -0700354 }
355 else {
356 assert(face == 0);
357 assert(zslice == 0);
358 }
Brian Paul192b7f22009-02-24 20:58:46 -0700359 return pt;
Brian Paul0a323fe2009-02-18 21:50:20 -0700360 }
Brian Paul192b7f22009-02-24 20:58:46 -0700361 return NULL;
Brian Paul0a323fe2009-02-18 21:50:20 -0700362}
363
364
365static void
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100366cell_tex_transfer_destroy(struct pipe_transfer *t)
Brian Paul0a323fe2009-02-18 21:50:20 -0700367{
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100368 struct cell_transfer *transfer = cell_transfer(t);
Brian Paul0a323fe2009-02-18 21:50:20 -0700369 /* Effectively do the texture_update work here - if texture images
370 * needed post-processing to put them into hardware layout, this is
371 * where it would happen. For cell, nothing to do.
372 */
373 assert (transfer->base.texture);
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100374 pipe_texture_reference(&transfer->base.texture, NULL);
375 FREE(transfer);
Brian Paul0a323fe2009-02-18 21:50:20 -0700376}
377
378
Brian Paul192b7f22009-02-24 20:58:46 -0700379/**
380 * Return pointer to texture image data in linear layout.
381 */
Brian Paul0a323fe2009-02-18 21:50:20 -0700382static void *
Brian Paul192b7f22009-02-24 20:58:46 -0700383cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
Brian Paul0a323fe2009-02-18 21:50:20 -0700384{
Brian Paul192b7f22009-02-24 20:58:46 -0700385 struct cell_transfer *ctrans = cell_transfer(transfer);
386 struct pipe_texture *pt = transfer->texture;
387 struct cell_texture *ct = cell_texture(pt);
388 const uint level = ctrans->base.level;
389 const uint texWidth = pt->width[level];
390 const uint texHeight = pt->height[level];
391 const uint stride = ct->stride[level];
Brian Paul192b7f22009-02-24 20:58:46 -0700392 unsigned size;
Brian Paul0a323fe2009-02-18 21:50:20 -0700393
394 assert(transfer->texture);
Brian Paul0a323fe2009-02-18 21:50:20 -0700395
Brian Paul192b7f22009-02-24 20:58:46 -0700396 if (!ct->mapped) {
397 /* map now */
Michel Dänzer47e41b02009-10-02 18:13:26 +0200398 ct->mapped = pipe_buffer_map(screen, ct->buffer,
399 pipe_transfer_buffer_flags(transfer));
Brian Paul192b7f22009-02-24 20:58:46 -0700400 }
Brian Paul0a323fe2009-02-18 21:50:20 -0700401
Brian Paul192b7f22009-02-24 20:58:46 -0700402 /*
403 * Create a buffer of ordinary memory for the linear texture.
404 * This is the memory that the user will read/write.
Brian Paul0a323fe2009-02-18 21:50:20 -0700405 */
Brian Paul192b7f22009-02-24 20:58:46 -0700406 size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
Brian Paul0a323fe2009-02-18 21:50:20 -0700407
Brian Paul192b7f22009-02-24 20:58:46 -0700408 ctrans->map = align_malloc(size, 16);
409 if (!ctrans->map)
410 return NULL; /* out of memory */
Brian Paul0a323fe2009-02-18 21:50:20 -0700411
Michel Dänzer47e41b02009-10-02 18:13:26 +0200412 if (transfer->usage & PIPE_TRANSFER_READ) {
Brian Paul192b7f22009-02-24 20:58:46 -0700413 /* need to untwiddle the texture to make a linear version */
414 const uint bpp = pf_get_size(ct->base.format);
415 if (bpp == 4) {
416 const uint *src = (uint *) (ct->mapped + ctrans->offset);
417 uint *dst = ctrans->map;
418 untwiddle_image_uint(texWidth, texHeight, TILE_SIZE,
419 dst, stride, src);
Jonathan White582ca6e2008-10-27 16:29:20 -0600420 }
421 else {
Brian Paul192b7f22009-02-24 20:58:46 -0700422 // xxx fix
Jonathan White582ca6e2008-10-27 16:29:20 -0600423 }
424 }
Brian Paul192b7f22009-02-24 20:58:46 -0700425
426 return ctrans->map;
Brian6ba9fb92008-08-25 11:31:59 -0600427}
428
429
Brian Paul192b7f22009-02-24 20:58:46 -0700430/**
431 * Called when user is done reading/writing texture data.
432 * If new data was written, this is where we convert the linear data
433 * to tiled data.
434 */
Brian6ba9fb92008-08-25 11:31:59 -0600435static void
Brian Paul192b7f22009-02-24 20:58:46 -0700436cell_transfer_unmap(struct pipe_screen *screen,
437 struct pipe_transfer *transfer)
Brian6ba9fb92008-08-25 11:31:59 -0600438{
Brian Paul192b7f22009-02-24 20:58:46 -0700439 struct cell_transfer *ctrans = cell_transfer(transfer);
440 struct pipe_texture *pt = transfer->texture;
441 struct cell_texture *ct = cell_texture(pt);
442 const uint level = ctrans->base.level;
443 const uint texWidth = pt->width[level];
444 const uint texHeight = pt->height[level];
445 const uint stride = ct->stride[level];
Brian Paul0bee1562008-10-14 10:55:38 -0600446
Brian Paul192b7f22009-02-24 20:58:46 -0700447 if (!ct->mapped) {
448 /* map now */
449 ct->mapped = pipe_buffer_map(screen, ct->buffer,
450 PIPE_BUFFER_USAGE_CPU_READ);
451 }
Brian Paul0bee1562008-10-14 10:55:38 -0600452
Michel Dänzer47e41b02009-10-02 18:13:26 +0200453 if (transfer->usage & PIPE_TRANSFER_WRITE) {
Brian Paul192b7f22009-02-24 20:58:46 -0700454 /* The user wrote new texture data into the mapped buffer.
455 * We need to convert the new linear data into the twiddled/tiled format.
456 */
457 const uint bpp = pf_get_size(ct->base.format);
458 if (bpp == 4) {
459 const uint *src = ctrans->map;
460 uint *dst = (uint *) (ct->mapped + ctrans->offset);
461 twiddle_image_uint(texWidth, texHeight, TILE_SIZE, dst, stride, src);
462 }
463 else {
464 // xxx fix
465 }
466 }
467
468 align_free(ctrans->map);
469 ctrans->map = NULL;
Brian6ba9fb92008-08-25 11:31:59 -0600470}
471
472
Brianf04736c2008-02-27 09:55:17 -0700473void
474cell_init_screen_texture_funcs(struct pipe_screen *screen)
475{
Brian Paul01a76f42008-08-27 16:45:41 -0600476 screen->texture_create = cell_texture_create;
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100477 screen->texture_destroy = cell_texture_destroy;
Brian Paul01a76f42008-08-27 16:45:41 -0600478
479 screen->get_tex_surface = cell_get_tex_surface;
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100480 screen->tex_surface_destroy = cell_tex_surface_destroy;
Brian6ba9fb92008-08-25 11:31:59 -0600481
Brian Paul0a323fe2009-02-18 21:50:20 -0700482 screen->get_tex_transfer = cell_get_tex_transfer;
Michel Dänzer5e27cd42009-03-04 11:58:48 +0100483 screen->tex_transfer_destroy = cell_tex_transfer_destroy;
Brian Paul192b7f22009-02-24 20:58:46 -0700484
Brian Paul0a323fe2009-02-18 21:50:20 -0700485 screen->transfer_map = cell_transfer_map;
486 screen->transfer_unmap = cell_transfer_unmap;
Brianf04736c2008-02-27 09:55:17 -0700487}