r600g: fix r700 cube map sizing.
[mesa.git] / src / gallium / drivers / r600 / r600_texture.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jerome Glisse
25 * Corbin Simpson
26 */
27 #include <errno.h>
28 #include <pipe/p_screen.h>
29 #include <util/u_format.h>
30 #include <util/u_math.h>
31 #include <util/u_inlines.h>
32 #include <util/u_memory.h>
33 #include "state_tracker/drm_driver.h"
34 #include "r600_screen.h"
35 #include "r600_context.h"
36 #include "r600_resource.h"
37 #include "r600_state_inlines.h"
38 #include "r600d.h"
39
40 extern struct u_resource_vtbl r600_texture_vtbl;
41
42 /* Copy from a tiled texture to a detiled one. */
43 static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
44 {
45 struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
46 struct pipe_resource *texture = transfer->resource;
47 struct pipe_subresource subdst;
48
49 subdst.face = 0;
50 subdst.level = 0;
51 ctx->resource_copy_region(ctx, rtransfer->linear_texture,
52 subdst, 0, 0, 0, texture, transfer->sr,
53 transfer->box.x, transfer->box.y, transfer->box.z,
54 transfer->box.width, transfer->box.height);
55 }
56
57 static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex,
58 unsigned level, unsigned zslice,
59 unsigned face)
60 {
61 unsigned long offset = rtex->offset[level];
62
63 switch (rtex->resource.base.b.target) {
64 case PIPE_TEXTURE_3D:
65 assert(face == 0);
66 return offset + zslice * rtex->layer_size[level];
67 case PIPE_TEXTURE_CUBE:
68 assert(zslice == 0);
69 return offset + face * rtex->layer_size[level];
70 default:
71 assert(zslice == 0 && face == 0);
72 return offset;
73 }
74 }
75
76 static void r600_setup_miptree(struct r600_resource_texture *rtex, enum chip_class chipc)
77 {
78 struct pipe_resource *ptex = &rtex->resource.base.b;
79 unsigned long w, h, pitch, size, layer_size, i, offset;
80
81 rtex->bpt = util_format_get_blocksize(ptex->format);
82 for (i = 0, offset = 0; i <= ptex->last_level; i++) {
83 w = u_minify(ptex->width0, i);
84 h = u_minify(ptex->height0, i);
85 h = util_next_power_of_two(h);
86 pitch = util_format_get_stride(ptex->format, align(w, 64));
87 pitch = align(pitch, 256);
88 layer_size = pitch * h;
89 if (ptex->target == PIPE_TEXTURE_CUBE) {
90 if (chipc == R700)
91 size = layer_size * 8;
92 else
93 size = layer_size * 6;
94 }
95 else
96 size = layer_size * u_minify(ptex->depth0, i);
97 rtex->offset[i] = offset;
98 rtex->layer_size[i] = layer_size;
99 rtex->pitch[i] = pitch;
100 rtex->width[i] = w;
101 rtex->height[i] = h;
102 offset += size;
103 }
104 rtex->size = offset;
105 }
106
107 struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
108 const struct pipe_resource *templ)
109 {
110 struct r600_screen *rscreen = r600_screen(screen);
111 struct r600_resource_texture *rtex;
112 struct r600_resource *resource;
113 struct radeon *radeon = (struct radeon *)screen->winsys;
114
115 rtex = CALLOC_STRUCT(r600_resource_texture);
116 if (!rtex) {
117 return NULL;
118 }
119 resource = &rtex->resource;
120 resource->base.b = *templ;
121 resource->base.vtbl = &r600_texture_vtbl;
122 pipe_reference_init(&resource->base.b.reference, 1);
123 resource->base.b.screen = screen;
124 r600_setup_miptree(rtex, rscreen->chip_class);
125
126 /* FIXME alignment 4096 enought ? too much ? */
127 resource->domain = r600_domain_from_usage(resource->base.b.bind);
128 resource->size = rtex->size;
129 resource->bo = radeon_ws_bo(radeon, rtex->size, 4096, 0);
130 if (resource->bo == NULL) {
131 FREE(rtex);
132 return NULL;
133 }
134 return &resource->base.b;
135 }
136
137 static void r600_texture_destroy_state(struct pipe_resource *ptexture)
138 {
139 struct r600_resource_texture *rtexture = (struct r600_resource_texture*)ptexture;
140
141 for (int i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) {
142 radeon_state_fini(&rtexture->scissor[i]);
143 radeon_state_fini(&rtexture->db[i]);
144 for (int j = 0; j < 8; j++) {
145 radeon_state_fini(&rtexture->cb[j][i]);
146 }
147 }
148 }
149
150 static void r600_texture_destroy(struct pipe_screen *screen,
151 struct pipe_resource *ptex)
152 {
153 struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
154 struct r600_resource *resource = &rtex->resource;
155 struct radeon *radeon = (struct radeon *)screen->winsys;
156
157 if (resource->bo) {
158 radeon_ws_bo_reference(radeon, &resource->bo, NULL);
159 }
160 if (rtex->uncompressed) {
161 radeon_ws_bo_reference(radeon, &rtex->uncompressed, NULL);
162 }
163 r600_texture_destroy_state(ptex);
164 FREE(rtex);
165 }
166
167 static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
168 struct pipe_resource *texture,
169 unsigned face, unsigned level,
170 unsigned zslice, unsigned flags)
171 {
172 struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
173 struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
174 unsigned long offset;
175
176 if (surface == NULL)
177 return NULL;
178 offset = r600_texture_get_offset(rtex, level, zslice, face);
179 pipe_reference_init(&surface->reference, 1);
180 pipe_resource_reference(&surface->texture, texture);
181 surface->format = texture->format;
182 surface->width = u_minify(texture->width0, level);
183 surface->height = u_minify(texture->height0, level);
184 surface->offset = offset;
185 surface->usage = flags;
186 surface->zslice = zslice;
187 surface->texture = texture;
188 surface->face = face;
189 surface->level = level;
190 return surface;
191 }
192
193 static void r600_tex_surface_destroy(struct pipe_surface *surface)
194 {
195 pipe_resource_reference(&surface->texture, NULL);
196 FREE(surface);
197 }
198
199 struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
200 const struct pipe_resource *templ,
201 struct winsys_handle *whandle)
202 {
203 struct radeon *rw = (struct radeon*)screen->winsys;
204 struct r600_resource_texture *rtex;
205 struct r600_resource *resource;
206 struct radeon_ws_bo *bo = NULL;
207
208 /* Support only 2D textures without mipmaps */
209 if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
210 templ->depth0 != 1 || templ->last_level != 0)
211 return NULL;
212
213 rtex = CALLOC_STRUCT(r600_resource_texture);
214 if (rtex == NULL)
215 return NULL;
216
217 bo = radeon_ws_bo_handle(rw, whandle->handle);
218 if (bo == NULL) {
219 FREE(rtex);
220 return NULL;
221 }
222
223 resource = &rtex->resource;
224 resource->base.b = *templ;
225 resource->base.vtbl = &r600_texture_vtbl;
226 pipe_reference_init(&resource->base.b.reference, 1);
227 resource->base.b.screen = screen;
228 resource->bo = bo;
229 rtex->depth = 0;
230 rtex->pitch_override = whandle->stride;
231 rtex->bpt = util_format_get_blocksize(templ->format);
232 rtex->pitch[0] = whandle->stride;
233 rtex->width[0] = templ->width0;
234 rtex->height[0] = templ->height0;
235 rtex->offset[0] = 0;
236 rtex->size = align(rtex->pitch[0] * templ->height0, 64);
237
238 return &resource->base.b;
239 }
240
241 static unsigned int r600_texture_is_referenced(struct pipe_context *context,
242 struct pipe_resource *texture,
243 unsigned face, unsigned level)
244 {
245 /* FIXME */
246 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
247 }
248
249 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
250 struct pipe_resource *texture,
251 struct pipe_subresource sr,
252 unsigned usage,
253 const struct pipe_box *box)
254 {
255 struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
256 struct pipe_resource resource;
257 struct r600_transfer *trans;
258
259 trans = CALLOC_STRUCT(r600_transfer);
260 if (trans == NULL)
261 return NULL;
262 pipe_resource_reference(&trans->transfer.resource, texture);
263 trans->transfer.sr = sr;
264 trans->transfer.usage = usage;
265 trans->transfer.box = *box;
266 trans->transfer.stride = rtex->pitch[sr.level];
267 trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
268 if (rtex->tilled && !rtex->depth) {
269 resource.target = PIPE_TEXTURE_2D;
270 resource.format = texture->format;
271 resource.width0 = box->width;
272 resource.height0 = box->height;
273 resource.depth0 = 0;
274 resource.last_level = 0;
275 resource.nr_samples = 0;
276 resource.usage = PIPE_USAGE_DYNAMIC;
277 resource.bind = 0;
278 resource.flags = 0;
279 /* For texture reading, the temporary (detiled) texture is used as
280 * a render target when blitting from a tiled texture. */
281 if (usage & PIPE_TRANSFER_READ) {
282 resource.bind |= PIPE_BIND_RENDER_TARGET;
283 }
284 /* For texture writing, the temporary texture is used as a sampler
285 * when blitting into a tiled texture. */
286 if (usage & PIPE_TRANSFER_WRITE) {
287 resource.bind |= PIPE_BIND_SAMPLER_VIEW;
288 }
289 /* Create the temporary texture. */
290 trans->linear_texture = ctx->screen->resource_create(ctx->screen, &resource);
291 if (trans->linear_texture == NULL) {
292 R600_ERR("failed to create temporary texture to hold untiled copy\n");
293 pipe_resource_reference(&trans->transfer.resource, NULL);
294 FREE(trans);
295 return NULL;
296 }
297 if (usage & PIPE_TRANSFER_READ) {
298 /* We cannot map a tiled texture directly because the data is
299 * in a different order, therefore we do detiling using a blit. */
300 r600_copy_from_tiled_texture(ctx, trans);
301 /* Always referenced in the blit. */
302 ctx->flush(ctx, 0, NULL);
303 }
304 }
305 return &trans->transfer;
306 }
307
308 void r600_texture_transfer_destroy(struct pipe_context *ctx,
309 struct pipe_transfer *transfer)
310 {
311 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
312
313 if (rtransfer->linear_texture) {
314 pipe_resource_reference(&rtransfer->linear_texture, NULL);
315 }
316 pipe_resource_reference(&transfer->resource, NULL);
317 FREE(transfer);
318 }
319
320 void* r600_texture_transfer_map(struct pipe_context *ctx,
321 struct pipe_transfer* transfer)
322 {
323 struct r600_screen *rscreen = r600_screen(ctx->screen);
324 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
325 struct radeon_ws_bo *bo;
326 enum pipe_format format = transfer->resource->format;
327 struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
328 struct r600_resource_texture *rtex;
329 unsigned long offset = 0;
330 char *map;
331 int r;
332
333 if (rtransfer->linear_texture) {
334 bo = ((struct r600_resource *)rtransfer->linear_texture)->bo;
335 } else {
336 rtex = (struct r600_resource_texture*)transfer->resource;
337 if (rtex->depth && rscreen->chip_class != EVERGREEN) {
338 r = r600_texture_from_depth(ctx, rtex, transfer->sr.level);
339 if (r) {
340 return NULL;
341 }
342 r600_flush(ctx, 0, NULL);
343 bo = rtex->uncompressed;
344 } else {
345 bo = ((struct r600_resource *)transfer->resource)->bo;
346 }
347 offset = rtransfer->offset +
348 transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
349 transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
350 }
351 map = radeon_ws_bo_map(radeon, bo, 0, r600_context(ctx));
352 if (!map) {
353 return NULL;
354 }
355
356 return map + offset;
357 }
358
359 void r600_texture_transfer_unmap(struct pipe_context *ctx,
360 struct pipe_transfer* transfer)
361 {
362 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
363 struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
364 struct r600_resource_texture *rtex;
365 struct radeon_ws_bo *bo;
366
367 if (rtransfer->linear_texture) {
368 bo = ((struct r600_resource *)rtransfer->linear_texture)->bo;
369 } else {
370 rtex = (struct r600_resource_texture*)transfer->resource;
371 if (rtex->depth) {
372 bo = rtex->uncompressed;
373 } else {
374 bo = ((struct r600_resource *)transfer->resource)->bo;
375 }
376 }
377 radeon_ws_bo_unmap(radeon, bo);
378 }
379
380 struct u_resource_vtbl r600_texture_vtbl =
381 {
382 u_default_resource_get_handle, /* get_handle */
383 r600_texture_destroy, /* resource_destroy */
384 r600_texture_is_referenced, /* is_resource_referenced */
385 r600_texture_get_transfer, /* get_transfer */
386 r600_texture_transfer_destroy, /* transfer_destroy */
387 r600_texture_transfer_map, /* transfer_map */
388 u_default_transfer_flush_region,/* transfer_flush_region */
389 r600_texture_transfer_unmap, /* transfer_unmap */
390 u_default_transfer_inline_write /* transfer_inline_write */
391 };
392
393 void r600_init_screen_texture_functions(struct pipe_screen *screen)
394 {
395 screen->get_tex_surface = r600_get_tex_surface;
396 screen->tex_surface_destroy = r600_tex_surface_destroy;
397 }
398
399 static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
400 const unsigned char *swizzle_view)
401 {
402 unsigned i;
403 unsigned char swizzle[4];
404 unsigned result = 0;
405 const uint32_t swizzle_shift[4] = {
406 16, 19, 22, 25,
407 };
408 const uint32_t swizzle_bit[4] = {
409 0, 1, 2, 3,
410 };
411
412 if (swizzle_view) {
413 /* Combine two sets of swizzles. */
414 for (i = 0; i < 4; i++) {
415 swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
416 swizzle_format[swizzle_view[i]] : swizzle_view[i];
417 }
418 } else {
419 memcpy(swizzle, swizzle_format, 4);
420 }
421
422 /* Get swizzle. */
423 for (i = 0; i < 4; i++) {
424 switch (swizzle[i]) {
425 case UTIL_FORMAT_SWIZZLE_Y:
426 result |= swizzle_bit[1] << swizzle_shift[i];
427 break;
428 case UTIL_FORMAT_SWIZZLE_Z:
429 result |= swizzle_bit[2] << swizzle_shift[i];
430 break;
431 case UTIL_FORMAT_SWIZZLE_W:
432 result |= swizzle_bit[3] << swizzle_shift[i];
433 break;
434 case UTIL_FORMAT_SWIZZLE_0:
435 result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
436 break;
437 case UTIL_FORMAT_SWIZZLE_1:
438 result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
439 break;
440 default: /* UTIL_FORMAT_SWIZZLE_X */
441 result |= swizzle_bit[0] << swizzle_shift[i];
442 }
443 }
444 return result;
445 }
446
447 /* texture format translate */
448 uint32_t r600_translate_texformat(enum pipe_format format,
449 const unsigned char *swizzle_view,
450 uint32_t *word4_p, uint32_t *yuv_format_p)
451 {
452 uint32_t result = 0, word4 = 0, yuv_format = 0;
453 const struct util_format_description *desc;
454 boolean uniform = TRUE;
455 int i;
456 const uint32_t sign_bit[4] = {
457 S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
458 S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
459 S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
460 S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
461 };
462 desc = util_format_description(format);
463
464 word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
465
466 /* Colorspace (return non-RGB formats directly). */
467 switch (desc->colorspace) {
468 /* Depth stencil formats */
469 case UTIL_FORMAT_COLORSPACE_ZS:
470 switch (format) {
471 case PIPE_FORMAT_Z16_UNORM:
472 result = V_0280A0_COLOR_16;
473 goto out_word4;
474 case PIPE_FORMAT_Z24X8_UNORM:
475 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
476 result = V_0280A0_COLOR_8_24;
477 goto out_word4;
478 case PIPE_FORMAT_X8Z24_UNORM:
479 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
480 result = V_0280A0_COLOR_24_8;
481 goto out_word4;
482 default:
483 goto out_unknown;
484 }
485
486 case UTIL_FORMAT_COLORSPACE_YUV:
487 yuv_format |= (1 << 30);
488 switch (format) {
489 case PIPE_FORMAT_UYVY:
490 case PIPE_FORMAT_YUYV:
491 default:
492 break;
493 }
494 goto out_unknown; /* TODO */
495
496 case UTIL_FORMAT_COLORSPACE_SRGB:
497 word4 |= S_038010_FORCE_DEGAMMA(1);
498 if (format == PIPE_FORMAT_L8A8_SRGB || format == PIPE_FORMAT_L8_SRGB)
499 goto out_unknown; /* fails for some reason - TODO */
500 break;
501
502 default:
503 break;
504 }
505
506 /* S3TC formats. TODO */
507 if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
508 goto out_unknown;
509 }
510
511
512 for (i = 0; i < desc->nr_channels; i++) {
513 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
514 word4 |= sign_bit[i];
515 }
516 }
517
518 /* R8G8Bx_SNORM - TODO CxV8U8 */
519
520 /* RGTC - TODO */
521
522 /* See whether the components are of the same size. */
523 for (i = 1; i < desc->nr_channels; i++) {
524 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
525 }
526
527 /* Non-uniform formats. */
528 if (!uniform) {
529 switch(desc->nr_channels) {
530 case 3:
531 if (desc->channel[0].size == 5 &&
532 desc->channel[1].size == 6 &&
533 desc->channel[2].size == 5) {
534 result = V_0280A0_COLOR_5_6_5;
535 goto out_word4;
536 }
537 goto out_unknown;
538 case 4:
539 if (desc->channel[0].size == 5 &&
540 desc->channel[1].size == 5 &&
541 desc->channel[2].size == 5 &&
542 desc->channel[3].size == 1) {
543 result = V_0280A0_COLOR_1_5_5_5;
544 goto out_word4;
545 }
546 if (desc->channel[0].size == 10 &&
547 desc->channel[1].size == 10 &&
548 desc->channel[2].size == 10 &&
549 desc->channel[3].size == 2) {
550 result = V_0280A0_COLOR_10_10_10_2;
551 goto out_word4;
552 }
553 goto out_unknown;
554 }
555 goto out_unknown;
556 }
557
558 /* uniform formats */
559 switch (desc->channel[0].type) {
560 case UTIL_FORMAT_TYPE_UNSIGNED:
561 case UTIL_FORMAT_TYPE_SIGNED:
562 if (!desc->channel[0].normalized &&
563 desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
564 goto out_unknown;
565 }
566
567 switch (desc->channel[0].size) {
568 case 4:
569 switch (desc->nr_channels) {
570 case 2:
571 result = V_0280A0_COLOR_4_4;
572 goto out_word4;
573 case 4:
574 result = V_0280A0_COLOR_4_4_4_4;
575 goto out_word4;
576 }
577 goto out_unknown;
578 case 8:
579 switch (desc->nr_channels) {
580 case 1:
581 result = V_0280A0_COLOR_8;
582 goto out_word4;
583 case 2:
584 result = V_0280A0_COLOR_8_8;
585 goto out_word4;
586 case 4:
587 result = V_0280A0_COLOR_8_8_8_8;
588 goto out_word4;
589 }
590 goto out_unknown;
591 case 16:
592 switch (desc->nr_channels) {
593 case 1:
594 result = V_0280A0_COLOR_16;
595 goto out_word4;
596 case 2:
597 result = V_0280A0_COLOR_16_16;
598 goto out_word4;
599 case 4:
600 result = V_0280A0_COLOR_16_16_16_16;
601 goto out_word4;
602 }
603 }
604 goto out_unknown;
605
606 case UTIL_FORMAT_TYPE_FLOAT:
607 switch (desc->channel[0].size) {
608 case 16:
609 switch (desc->nr_channels) {
610 case 1:
611 result = V_0280A0_COLOR_16_FLOAT;
612 goto out_word4;
613 case 2:
614 result = V_0280A0_COLOR_16_16_FLOAT;
615 goto out_word4;
616 case 4:
617 result = V_0280A0_COLOR_16_16_16_16_FLOAT;
618 goto out_word4;
619 }
620 goto out_unknown;
621 case 32:
622 switch (desc->nr_channels) {
623 case 1:
624 result = V_0280A0_COLOR_32_FLOAT;
625 goto out_word4;
626 case 2:
627 result = V_0280A0_COLOR_32_32_FLOAT;
628 goto out_word4;
629 case 4:
630 result = V_0280A0_COLOR_32_32_32_32_FLOAT;
631 goto out_word4;
632 }
633 }
634
635 }
636 out_word4:
637 if (word4_p)
638 *word4_p = word4;
639 if (yuv_format_p)
640 *yuv_format_p = yuv_format;
641 return result;
642 out_unknown:
643 // R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
644 return ~0;
645 }
646
647 int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
648 {
649 struct r600_screen *rscreen = r600_screen(ctx->screen);
650 int r;
651
652 if (!rtexture->depth) {
653 /* This shouldn't happen maybe print a warning */
654 return 0;
655 }
656 if (rtexture->uncompressed && !rtexture->dirty) {
657 /* Uncompressed bo already in good state */
658 return 0;
659 }
660
661 /* allocate uncompressed texture */
662 if (rtexture->uncompressed == NULL) {
663 rtexture->uncompressed = radeon_ws_bo(rscreen->rw, rtexture->size, 4096, 0);
664 if (rtexture->uncompressed == NULL) {
665 return -ENOMEM;
666 }
667 }
668
669 /* render a rectangle covering whole buffer to uncompress depth */
670 r = r600_blit_uncompress_depth(ctx, rtexture, level);
671 if (r) {
672 return r;
673 }
674
675 rtexture->dirty = 0;
676 return 0;
677 }
678
679
680
681 int r600_texture_scissor(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
682 {
683 struct r600_screen *rscreen = r600_screen(ctx->screen);
684 struct r600_context *rctx = r600_context(ctx);
685
686 if (!rtexture->scissor[level].cpm4) {
687 rctx->vtbl->texture_state_scissor(rscreen, rtexture, level);
688 }
689 return 0;
690 }
691
692 int r600_texture_cb(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned cb, unsigned level)
693 {
694 struct r600_screen *rscreen = r600_screen(ctx->screen);
695 struct r600_context *rctx = r600_context(ctx);
696
697 if (!rtexture->cb[cb][level].cpm4) {
698 rctx->vtbl->texture_state_cb(rscreen, rtexture, cb, level);
699 }
700 return 0;
701 }
702
703 int r600_texture_db(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
704 {
705 struct r600_screen *rscreen = r600_screen(ctx->screen);
706 struct r600_context *rctx = r600_context(ctx);
707
708 if (!rtexture->db[level].cpm4) {
709 rctx->vtbl->texture_state_db(rscreen, rtexture, level);
710 }
711 return 0;
712 }
713
714 int r600_texture_viewport(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
715 {
716 struct r600_screen *rscreen = r600_screen(ctx->screen);
717 struct r600_context *rctx = r600_context(ctx);
718
719 if (!rtexture->viewport[level].cpm4) {
720 rctx->vtbl->texture_state_viewport(rscreen, rtexture, level);
721 }
722 return 0;
723 }