fc69f48bb70d01c5aa72c6e72cc6fded58ecc62b
[mesa.git] / src / gallium / drivers / radeon / 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 "r600_pipe_common.h"
28 #include "r600_cs.h"
29 #include "util/u_format.h"
30 #include "util/u_memory.h"
31 #include "util/u_pack_color.h"
32 #include <errno.h>
33 #include <inttypes.h>
34
35 /* Same as resource_copy_region, except that both upsampling and downsampling are allowed. */
36 static void r600_copy_region_with_blit(struct pipe_context *pipe,
37 struct pipe_resource *dst,
38 unsigned dst_level,
39 unsigned dstx, unsigned dsty, unsigned dstz,
40 struct pipe_resource *src,
41 unsigned src_level,
42 const struct pipe_box *src_box)
43 {
44 struct pipe_blit_info blit;
45
46 memset(&blit, 0, sizeof(blit));
47 blit.src.resource = src;
48 blit.src.format = src->format;
49 blit.src.level = src_level;
50 blit.src.box = *src_box;
51 blit.dst.resource = dst;
52 blit.dst.format = dst->format;
53 blit.dst.level = dst_level;
54 blit.dst.box.x = dstx;
55 blit.dst.box.y = dsty;
56 blit.dst.box.z = dstz;
57 blit.dst.box.width = src_box->width;
58 blit.dst.box.height = src_box->height;
59 blit.dst.box.depth = src_box->depth;
60 blit.mask = util_format_get_mask(src->format) &
61 util_format_get_mask(dst->format);
62 blit.filter = PIPE_TEX_FILTER_NEAREST;
63
64 if (blit.mask) {
65 pipe->blit(pipe, &blit);
66 }
67 }
68
69 /* Copy from a full GPU texture to a transfer's staging one. */
70 static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
71 {
72 struct r600_common_context *rctx = (struct r600_common_context*)ctx;
73 struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
74 struct pipe_resource *dst = &rtransfer->staging->b.b;
75 struct pipe_resource *src = transfer->resource;
76
77 if (src->nr_samples > 1) {
78 r600_copy_region_with_blit(ctx, dst, 0, 0, 0, 0,
79 src, transfer->level, &transfer->box);
80 return;
81 }
82
83 rctx->dma_copy(ctx, dst, 0, 0, 0, 0, src, transfer->level,
84 &transfer->box);
85 }
86
87 /* Copy from a transfer's staging texture to a full GPU one. */
88 static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
89 {
90 struct r600_common_context *rctx = (struct r600_common_context*)ctx;
91 struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
92 struct pipe_resource *dst = transfer->resource;
93 struct pipe_resource *src = &rtransfer->staging->b.b;
94 struct pipe_box sbox;
95
96 u_box_3d(0, 0, 0, transfer->box.width, transfer->box.height, transfer->box.depth, &sbox);
97
98 if (dst->nr_samples > 1) {
99 r600_copy_region_with_blit(ctx, dst, transfer->level,
100 transfer->box.x, transfer->box.y, transfer->box.z,
101 src, 0, &sbox);
102 return;
103 }
104
105 rctx->dma_copy(ctx, dst, transfer->level,
106 transfer->box.x, transfer->box.y, transfer->box.z,
107 src, 0, &sbox);
108 }
109
110 static unsigned r600_texture_get_offset(struct r600_texture *rtex, unsigned level,
111 const struct pipe_box *box)
112 {
113 enum pipe_format format = rtex->resource.b.b.format;
114
115 return rtex->surface.level[level].offset +
116 box->z * rtex->surface.level[level].slice_size +
117 box->y / util_format_get_blockheight(format) * rtex->surface.level[level].pitch_bytes +
118 box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
119 }
120
121 static int r600_init_surface(struct r600_common_screen *rscreen,
122 struct radeon_surf *surface,
123 const struct pipe_resource *ptex,
124 unsigned array_mode,
125 bool is_flushed_depth)
126 {
127 const struct util_format_description *desc =
128 util_format_description(ptex->format);
129 bool is_depth, is_stencil;
130
131 is_depth = util_format_has_depth(desc);
132 is_stencil = util_format_has_stencil(desc);
133
134 surface->npix_x = ptex->width0;
135 surface->npix_y = ptex->height0;
136 surface->npix_z = ptex->depth0;
137 surface->blk_w = util_format_get_blockwidth(ptex->format);
138 surface->blk_h = util_format_get_blockheight(ptex->format);
139 surface->blk_d = 1;
140 surface->array_size = 1;
141 surface->last_level = ptex->last_level;
142
143 if (rscreen->chip_class >= EVERGREEN && !is_flushed_depth &&
144 ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
145 surface->bpe = 4; /* stencil is allocated separately on evergreen */
146 } else {
147 surface->bpe = util_format_get_blocksize(ptex->format);
148 /* align byte per element on dword */
149 if (surface->bpe == 3) {
150 surface->bpe = 4;
151 }
152 }
153
154 surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1;
155 surface->flags = RADEON_SURF_SET(array_mode, MODE);
156
157 switch (ptex->target) {
158 case PIPE_TEXTURE_1D:
159 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
160 break;
161 case PIPE_TEXTURE_RECT:
162 case PIPE_TEXTURE_2D:
163 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
164 break;
165 case PIPE_TEXTURE_3D:
166 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
167 break;
168 case PIPE_TEXTURE_1D_ARRAY:
169 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
170 surface->array_size = ptex->array_size;
171 break;
172 case PIPE_TEXTURE_2D_ARRAY:
173 case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */
174 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
175 surface->array_size = ptex->array_size;
176 break;
177 case PIPE_TEXTURE_CUBE:
178 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
179 break;
180 case PIPE_BUFFER:
181 default:
182 return -EINVAL;
183 }
184 if (ptex->bind & PIPE_BIND_SCANOUT) {
185 surface->flags |= RADEON_SURF_SCANOUT;
186 }
187
188 if (!is_flushed_depth && is_depth) {
189 surface->flags |= RADEON_SURF_ZBUFFER;
190
191 if (is_stencil) {
192 surface->flags |= RADEON_SURF_SBUFFER |
193 RADEON_SURF_HAS_SBUFFER_MIPTREE;
194 }
195 }
196 if (rscreen->chip_class >= SI) {
197 surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
198 }
199 return 0;
200 }
201
202 static int r600_setup_surface(struct pipe_screen *screen,
203 struct r600_texture *rtex,
204 unsigned pitch_in_bytes_override)
205 {
206 struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
207 int r;
208
209 r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
210 if (r) {
211 return r;
212 }
213
214 rtex->size = rtex->surface.bo_size;
215
216 if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
217 /* old ddx on evergreen over estimate alignment for 1d, only 1 level
218 * for those
219 */
220 rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
221 rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
222 rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
223 if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
224 rtex->surface.stencil_offset =
225 rtex->surface.stencil_level[0].offset = rtex->surface.level[0].slice_size;
226 }
227 }
228 return 0;
229 }
230
231 static boolean r600_texture_get_handle(struct pipe_screen* screen,
232 struct pipe_resource *ptex,
233 struct winsys_handle *whandle)
234 {
235 struct r600_texture *rtex = (struct r600_texture*)ptex;
236 struct r600_resource *resource = &rtex->resource;
237 struct radeon_surf *surface = &rtex->surface;
238 struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
239
240 rscreen->ws->buffer_set_tiling(resource->buf,
241 NULL,
242 surface->level[0].mode >= RADEON_SURF_MODE_1D ?
243 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
244 surface->level[0].mode >= RADEON_SURF_MODE_2D ?
245 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
246 surface->pipe_config,
247 surface->bankw, surface->bankh,
248 surface->tile_split,
249 surface->stencil_tile_split,
250 surface->mtilea, surface->num_banks,
251 surface->level[0].pitch_bytes,
252 (surface->flags & RADEON_SURF_SCANOUT) != 0);
253
254 return rscreen->ws->buffer_get_handle(resource->buf,
255 surface->level[0].pitch_bytes, whandle);
256 }
257
258 static void r600_texture_destroy(struct pipe_screen *screen,
259 struct pipe_resource *ptex)
260 {
261 struct r600_texture *rtex = (struct r600_texture*)ptex;
262 struct r600_resource *resource = &rtex->resource;
263
264 if (rtex->flushed_depth_texture)
265 pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
266
267 pipe_resource_reference((struct pipe_resource**)&rtex->htile_buffer, NULL);
268 if (rtex->cmask_buffer != &rtex->resource) {
269 pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
270 }
271 pb_reference(&resource->buf, NULL);
272 FREE(rtex);
273 }
274
275 static const struct u_resource_vtbl r600_texture_vtbl;
276
277 /* The number of samples can be specified independently of the texture. */
278 void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
279 struct r600_texture *rtex,
280 unsigned nr_samples,
281 struct r600_fmask_info *out)
282 {
283 /* FMASK is allocated like an ordinary texture. */
284 struct radeon_surf fmask = rtex->surface;
285
286 memset(out, 0, sizeof(*out));
287
288 fmask.bo_alignment = 0;
289 fmask.bo_size = 0;
290 fmask.nsamples = 1;
291 fmask.flags |= RADEON_SURF_FMASK;
292
293 /* Force 2D tiling if it wasn't set. This may occur when creating
294 * FMASK for MSAA resolve on R6xx. On R6xx, the single-sample
295 * destination buffer must have an FMASK too. */
296 fmask.flags = RADEON_SURF_CLR(fmask.flags, MODE);
297 fmask.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
298
299 if (rscreen->chip_class >= SI) {
300 fmask.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
301 }
302
303 switch (nr_samples) {
304 case 2:
305 case 4:
306 fmask.bpe = 1;
307 if (rscreen->chip_class <= CAYMAN) {
308 fmask.bankh = 4;
309 }
310 break;
311 case 8:
312 fmask.bpe = 4;
313 break;
314 default:
315 R600_ERR("Invalid sample count for FMASK allocation.\n");
316 return;
317 }
318
319 /* Overallocate FMASK on R600-R700 to fix colorbuffer corruption.
320 * This can be fixed by writing a separate FMASK allocator specifically
321 * for R600-R700 asics. */
322 if (rscreen->chip_class <= R700) {
323 fmask.bpe *= 2;
324 }
325
326 if (rscreen->ws->surface_init(rscreen->ws, &fmask)) {
327 R600_ERR("Got error in surface_init while allocating FMASK.\n");
328 return;
329 }
330
331 assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
332
333 out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) / 64;
334 if (out->slice_tile_max)
335 out->slice_tile_max -= 1;
336
337 out->tile_mode_index = fmask.tiling_index[0];
338 out->pitch = fmask.level[0].nblk_x;
339 out->bank_height = fmask.bankh;
340 out->alignment = MAX2(256, fmask.bo_alignment);
341 out->size = fmask.bo_size;
342 }
343
344 static void r600_texture_allocate_fmask(struct r600_common_screen *rscreen,
345 struct r600_texture *rtex)
346 {
347 r600_texture_get_fmask_info(rscreen, rtex,
348 rtex->resource.b.b.nr_samples, &rtex->fmask);
349
350 rtex->fmask.offset = align(rtex->size, rtex->fmask.alignment);
351 rtex->size = rtex->fmask.offset + rtex->fmask.size;
352 }
353
354 void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
355 struct r600_texture *rtex,
356 struct r600_cmask_info *out)
357 {
358 unsigned cmask_tile_width = 8;
359 unsigned cmask_tile_height = 8;
360 unsigned cmask_tile_elements = cmask_tile_width * cmask_tile_height;
361 unsigned element_bits = 4;
362 unsigned cmask_cache_bits = 1024;
363 unsigned num_pipes = rscreen->tiling_info.num_channels;
364 unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
365
366 unsigned elements_per_macro_tile = (cmask_cache_bits / element_bits) * num_pipes;
367 unsigned pixels_per_macro_tile = elements_per_macro_tile * cmask_tile_elements;
368 unsigned sqrt_pixels_per_macro_tile = sqrt(pixels_per_macro_tile);
369 unsigned macro_tile_width = util_next_power_of_two(sqrt_pixels_per_macro_tile);
370 unsigned macro_tile_height = pixels_per_macro_tile / macro_tile_width;
371
372 unsigned pitch_elements = align(rtex->surface.npix_x, macro_tile_width);
373 unsigned height = align(rtex->surface.npix_y, macro_tile_height);
374
375 unsigned base_align = num_pipes * pipe_interleave_bytes;
376 unsigned slice_bytes =
377 ((pitch_elements * height * element_bits + 7) / 8) / cmask_tile_elements;
378
379 assert(macro_tile_width % 128 == 0);
380 assert(macro_tile_height % 128 == 0);
381
382 out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
383 out->alignment = MAX2(256, base_align);
384 out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
385 align(slice_bytes, base_align);
386 }
387
388 static void si_texture_get_cmask_info(struct r600_common_screen *rscreen,
389 struct r600_texture *rtex,
390 struct r600_cmask_info *out)
391 {
392 unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
393 unsigned num_pipes = rscreen->tiling_info.num_channels;
394 unsigned cl_width, cl_height;
395
396 switch (num_pipes) {
397 case 2:
398 cl_width = 32;
399 cl_height = 16;
400 break;
401 case 4:
402 cl_width = 32;
403 cl_height = 32;
404 break;
405 case 8:
406 cl_width = 64;
407 cl_height = 32;
408 break;
409 case 16: /* Hawaii */
410 cl_width = 64;
411 cl_height = 64;
412 break;
413 default:
414 assert(0);
415 return;
416 }
417
418 unsigned base_align = num_pipes * pipe_interleave_bytes;
419
420 unsigned width = align(rtex->surface.npix_x, cl_width*8);
421 unsigned height = align(rtex->surface.npix_y, cl_height*8);
422 unsigned slice_elements = (width * height) / (8*8);
423
424 /* Each element of CMASK is a nibble. */
425 unsigned slice_bytes = slice_elements / 2;
426
427 out->slice_tile_max = (width * height) / (128*128);
428 if (out->slice_tile_max)
429 out->slice_tile_max -= 1;
430
431 out->alignment = MAX2(256, base_align);
432 out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
433 align(slice_bytes, base_align);
434 }
435
436 static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen,
437 struct r600_texture *rtex)
438 {
439 if (rscreen->chip_class >= SI) {
440 si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
441 } else {
442 r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
443 }
444
445 rtex->cmask.offset = align(rtex->size, rtex->cmask.alignment);
446 rtex->size = rtex->cmask.offset + rtex->cmask.size;
447
448 if (rscreen->chip_class >= SI)
449 rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
450 else
451 rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
452 }
453
454 static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
455 struct r600_texture *rtex)
456 {
457 if (rtex->cmask_buffer)
458 return;
459
460 assert(rtex->cmask.size == 0);
461
462 if (rscreen->chip_class >= SI) {
463 si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
464 } else {
465 r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
466 }
467
468 rtex->cmask_buffer = (struct r600_resource *)
469 pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
470 PIPE_USAGE_DEFAULT, rtex->cmask.size);
471 if (rtex->cmask_buffer == NULL) {
472 rtex->cmask.size = 0;
473 return;
474 }
475
476 /* update colorbuffer state bits */
477 rtex->cmask.base_address_reg = rtex->cmask_buffer->gpu_address >> 8;
478
479 if (rscreen->chip_class >= SI)
480 rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
481 else
482 rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
483 }
484
485 static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
486 struct r600_texture *rtex)
487 {
488 unsigned cl_width, cl_height, width, height;
489 unsigned slice_elements, slice_bytes, pipe_interleave_bytes, base_align;
490 unsigned num_pipes = rscreen->tiling_info.num_channels;
491
492 if (rscreen->chip_class <= EVERGREEN &&
493 rscreen->info.drm_major == 2 && rscreen->info.drm_minor < 26)
494 return 0;
495
496 /* HW bug on R6xx. */
497 if (rscreen->chip_class == R600 &&
498 (rtex->surface.level[0].npix_x > 7680 ||
499 rtex->surface.level[0].npix_y > 7680))
500 return 0;
501
502 /* HTILE is broken with 1D tiling on old kernels and CIK. */
503 if (rscreen->chip_class >= CIK &&
504 rtex->surface.level[0].mode == RADEON_SURF_MODE_1D &&
505 rscreen->info.drm_major == 2 && rscreen->info.drm_minor < 38)
506 return 0;
507
508 switch (num_pipes) {
509 case 1:
510 cl_width = 32;
511 cl_height = 16;
512 break;
513 case 2:
514 cl_width = 32;
515 cl_height = 32;
516 break;
517 case 4:
518 cl_width = 64;
519 cl_height = 32;
520 break;
521 case 8:
522 cl_width = 64;
523 cl_height = 64;
524 break;
525 case 16:
526 cl_width = 128;
527 cl_height = 64;
528 break;
529 default:
530 assert(0);
531 return 0;
532 }
533
534 width = align(rtex->surface.npix_x, cl_width * 8);
535 height = align(rtex->surface.npix_y, cl_height * 8);
536
537 slice_elements = (width * height) / (8 * 8);
538 slice_bytes = slice_elements * 4;
539
540 pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
541 base_align = num_pipes * pipe_interleave_bytes;
542
543 return (util_max_layer(&rtex->resource.b.b, 0) + 1) *
544 align(slice_bytes, base_align);
545 }
546
547 static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
548 struct r600_texture *rtex)
549 {
550 unsigned htile_size = r600_texture_get_htile_size(rscreen, rtex);
551
552 if (!htile_size)
553 return;
554
555 rtex->htile_buffer = (struct r600_resource*)
556 pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
557 PIPE_USAGE_DEFAULT, htile_size);
558 if (rtex->htile_buffer == NULL) {
559 /* this is not a fatal error as we can still keep rendering
560 * without htile buffer */
561 R600_ERR("Failed to create buffer object for htile buffer.\n");
562 } else {
563 r600_screen_clear_buffer(rscreen, &rtex->htile_buffer->b.b, 0,
564 htile_size, 0, true);
565 }
566 }
567
568 /* Common processing for r600_texture_create and r600_texture_from_handle */
569 static struct r600_texture *
570 r600_texture_create_object(struct pipe_screen *screen,
571 const struct pipe_resource *base,
572 unsigned pitch_in_bytes_override,
573 struct pb_buffer *buf,
574 struct radeon_surf *surface)
575 {
576 struct r600_texture *rtex;
577 struct r600_resource *resource;
578 struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
579
580 rtex = CALLOC_STRUCT(r600_texture);
581 if (rtex == NULL)
582 return NULL;
583
584 resource = &rtex->resource;
585 resource->b.b = *base;
586 resource->b.vtbl = &r600_texture_vtbl;
587 pipe_reference_init(&resource->b.b.reference, 1);
588 resource->b.b.screen = screen;
589 rtex->pitch_override = pitch_in_bytes_override;
590
591 /* don't include stencil-only formats which we don't support for rendering */
592 rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
593
594 rtex->surface = *surface;
595 if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) {
596 FREE(rtex);
597 return NULL;
598 }
599
600 /* Tiled depth textures utilize the non-displayable tile order.
601 * This must be done after r600_setup_surface.
602 * Applies to R600-Cayman. */
603 rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D;
604
605 if (rtex->is_depth) {
606 if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER |
607 R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
608 !(rscreen->debug_flags & DBG_NO_HYPERZ)) {
609
610 r600_texture_allocate_htile(rscreen, rtex);
611 }
612 } else {
613 if (base->nr_samples > 1) {
614 if (!buf) {
615 r600_texture_allocate_fmask(rscreen, rtex);
616 r600_texture_allocate_cmask(rscreen, rtex);
617 rtex->cmask_buffer = &rtex->resource;
618 }
619 if (!rtex->fmask.size || !rtex->cmask.size) {
620 FREE(rtex);
621 return NULL;
622 }
623 }
624 }
625
626 /* Now create the backing buffer. */
627 if (!buf) {
628 if (!r600_init_resource(rscreen, resource, rtex->size,
629 rtex->surface.bo_alignment, TRUE)) {
630 FREE(rtex);
631 return NULL;
632 }
633 } else {
634 resource->buf = buf;
635 resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
636 resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->cs_buf);
637 resource->domains = rscreen->ws->buffer_get_initial_domain(resource->cs_buf);
638 }
639
640 if (rtex->cmask.size) {
641 /* Initialize the cmask to 0xCC (= compressed state). */
642 r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b,
643 rtex->cmask.offset, rtex->cmask.size,
644 0xCCCCCCCC, true);
645 }
646
647 /* Initialize the CMASK base register value. */
648 rtex->cmask.base_address_reg =
649 (rtex->resource.gpu_address + rtex->cmask.offset) >> 8;
650
651 if (rscreen->debug_flags & DBG_VM) {
652 fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
653 rtex->resource.gpu_address,
654 rtex->resource.gpu_address + rtex->resource.buf->size,
655 base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
656 base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
657 }
658
659 if (rscreen->debug_flags & DBG_TEX ||
660 (rtex->resource.b.b.last_level > 0 && rscreen->debug_flags & DBG_TEXMIP)) {
661 printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
662 "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
663 "bpe=%u, nsamples=%u, flags=0x%x, %s\n",
664 rtex->surface.npix_x, rtex->surface.npix_y,
665 rtex->surface.npix_z, rtex->surface.blk_w,
666 rtex->surface.blk_h, rtex->surface.blk_d,
667 rtex->surface.array_size, rtex->surface.last_level,
668 rtex->surface.bpe, rtex->surface.nsamples,
669 rtex->surface.flags, util_format_short_name(base->format));
670 for (int i = 0; i <= rtex->surface.last_level; i++) {
671 printf(" L %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
672 "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
673 "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
674 i, rtex->surface.level[i].offset,
675 rtex->surface.level[i].slice_size,
676 u_minify(rtex->resource.b.b.width0, i),
677 u_minify(rtex->resource.b.b.height0, i),
678 u_minify(rtex->resource.b.b.depth0, i),
679 rtex->surface.level[i].nblk_x,
680 rtex->surface.level[i].nblk_y,
681 rtex->surface.level[i].nblk_z,
682 rtex->surface.level[i].pitch_bytes,
683 rtex->surface.level[i].mode);
684 }
685 if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
686 for (int i = 0; i <= rtex->surface.last_level; i++) {
687 printf(" S %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
688 "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
689 "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
690 i, rtex->surface.stencil_level[i].offset,
691 rtex->surface.stencil_level[i].slice_size,
692 u_minify(rtex->resource.b.b.width0, i),
693 u_minify(rtex->resource.b.b.height0, i),
694 u_minify(rtex->resource.b.b.depth0, i),
695 rtex->surface.stencil_level[i].nblk_x,
696 rtex->surface.stencil_level[i].nblk_y,
697 rtex->surface.stencil_level[i].nblk_z,
698 rtex->surface.stencil_level[i].pitch_bytes,
699 rtex->surface.stencil_level[i].mode);
700 }
701 }
702 }
703 return rtex;
704 }
705
706 static unsigned r600_choose_tiling(struct r600_common_screen *rscreen,
707 const struct pipe_resource *templ)
708 {
709 const struct util_format_description *desc = util_format_description(templ->format);
710 bool force_tiling = templ->flags & R600_RESOURCE_FLAG_FORCE_TILING;
711
712 /* MSAA resources must be 2D tiled. */
713 if (templ->nr_samples > 1)
714 return RADEON_SURF_MODE_2D;
715
716 /* Transfer resources should be linear. */
717 if (templ->flags & R600_RESOURCE_FLAG_TRANSFER)
718 return RADEON_SURF_MODE_LINEAR_ALIGNED;
719
720 /* r600g: force tiling on TEXTURE_2D and TEXTURE_3D compute resources. */
721 if (rscreen->chip_class >= R600 && rscreen->chip_class <= CAYMAN &&
722 (templ->bind & PIPE_BIND_COMPUTE_RESOURCE) &&
723 (templ->target == PIPE_TEXTURE_2D ||
724 templ->target == PIPE_TEXTURE_3D))
725 force_tiling = true;
726
727 /* Handle common candidates for the linear mode.
728 * Compressed textures must always be tiled. */
729 if (!force_tiling && !util_format_is_compressed(templ->format)) {
730 /* Not everything can be linear, so we cannot enforce it
731 * for all textures. */
732 if ((rscreen->debug_flags & DBG_NO_TILING) &&
733 (!util_format_is_depth_or_stencil(templ->format) ||
734 !(templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH)))
735 return RADEON_SURF_MODE_LINEAR_ALIGNED;
736
737 /* Tiling doesn't work with the 422 (SUBSAMPLED) formats on R600+. */
738 if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
739 return RADEON_SURF_MODE_LINEAR_ALIGNED;
740
741 /* Cursors are linear on SI.
742 * (XXX double-check, maybe also use RADEON_SURF_SCANOUT) */
743 if (rscreen->chip_class >= SI &&
744 (templ->bind & PIPE_BIND_CURSOR))
745 return RADEON_SURF_MODE_LINEAR_ALIGNED;
746
747 if (templ->bind & PIPE_BIND_LINEAR)
748 return RADEON_SURF_MODE_LINEAR_ALIGNED;
749
750 /* Textures with a very small height are recommended to be linear. */
751 if (templ->target == PIPE_TEXTURE_1D ||
752 templ->target == PIPE_TEXTURE_1D_ARRAY ||
753 templ->height0 <= 4)
754 return RADEON_SURF_MODE_LINEAR_ALIGNED;
755
756 /* Textures likely to be mapped often. */
757 if (templ->usage == PIPE_USAGE_STAGING ||
758 templ->usage == PIPE_USAGE_STREAM)
759 return RADEON_SURF_MODE_LINEAR_ALIGNED;
760 }
761
762 /* Make small textures 1D tiled. */
763 if (templ->width0 <= 16 || templ->height0 <= 16 ||
764 (rscreen->debug_flags & DBG_NO_2D_TILING))
765 return RADEON_SURF_MODE_1D;
766
767 /* The allocator will switch to 1D if needed. */
768 return RADEON_SURF_MODE_2D;
769 }
770
771 struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
772 const struct pipe_resource *templ)
773 {
774 struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
775 struct radeon_surf surface = {0};
776 int r;
777
778 r = r600_init_surface(rscreen, &surface, templ,
779 r600_choose_tiling(rscreen, templ),
780 templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH);
781 if (r) {
782 return NULL;
783 }
784 r = rscreen->ws->surface_best(rscreen->ws, &surface);
785 if (r) {
786 return NULL;
787 }
788 return (struct pipe_resource *)r600_texture_create_object(screen, templ,
789 0, NULL, &surface);
790 }
791
792 static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
793 const struct pipe_resource *templ,
794 struct winsys_handle *whandle)
795 {
796 struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
797 struct pb_buffer *buf = NULL;
798 unsigned stride = 0;
799 unsigned array_mode;
800 enum radeon_bo_layout micro, macro;
801 struct radeon_surf surface;
802 bool scanout;
803 int r;
804
805 /* Support only 2D textures without mipmaps */
806 if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
807 templ->depth0 != 1 || templ->last_level != 0)
808 return NULL;
809
810 buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
811 if (!buf)
812 return NULL;
813
814 rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
815 &surface.bankw, &surface.bankh,
816 &surface.tile_split,
817 &surface.stencil_tile_split,
818 &surface.mtilea, &scanout);
819
820 if (macro == RADEON_LAYOUT_TILED)
821 array_mode = RADEON_SURF_MODE_2D;
822 else if (micro == RADEON_LAYOUT_TILED)
823 array_mode = RADEON_SURF_MODE_1D;
824 else
825 array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
826
827 r = r600_init_surface(rscreen, &surface, templ, array_mode, false);
828 if (r) {
829 return NULL;
830 }
831
832 if (scanout)
833 surface.flags |= RADEON_SURF_SCANOUT;
834
835 return (struct pipe_resource *)r600_texture_create_object(screen, templ,
836 stride, buf, &surface);
837 }
838
839 bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
840 struct pipe_resource *texture,
841 struct r600_texture **staging)
842 {
843 struct r600_texture *rtex = (struct r600_texture*)texture;
844 struct pipe_resource resource;
845 struct r600_texture **flushed_depth_texture = staging ?
846 staging : &rtex->flushed_depth_texture;
847
848 if (!staging && rtex->flushed_depth_texture)
849 return true; /* it's ready */
850
851 resource.target = texture->target;
852 resource.format = texture->format;
853 resource.width0 = texture->width0;
854 resource.height0 = texture->height0;
855 resource.depth0 = texture->depth0;
856 resource.array_size = texture->array_size;
857 resource.last_level = texture->last_level;
858 resource.nr_samples = texture->nr_samples;
859 resource.usage = staging ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
860 resource.bind = texture->bind & ~PIPE_BIND_DEPTH_STENCIL;
861 resource.flags = texture->flags | R600_RESOURCE_FLAG_FLUSHED_DEPTH;
862
863 if (staging)
864 resource.flags |= R600_RESOURCE_FLAG_TRANSFER;
865
866 *flushed_depth_texture = (struct r600_texture *)ctx->screen->resource_create(ctx->screen, &resource);
867 if (*flushed_depth_texture == NULL) {
868 R600_ERR("failed to create temporary texture to hold flushed depth\n");
869 return false;
870 }
871
872 (*flushed_depth_texture)->is_flushing_texture = TRUE;
873 (*flushed_depth_texture)->non_disp_tiling = false;
874 return true;
875 }
876
877 /**
878 * Initialize the pipe_resource descriptor to be of the same size as the box,
879 * which is supposed to hold a subregion of the texture "orig" at the given
880 * mipmap level.
881 */
882 static void r600_init_temp_resource_from_box(struct pipe_resource *res,
883 struct pipe_resource *orig,
884 const struct pipe_box *box,
885 unsigned level, unsigned flags)
886 {
887 memset(res, 0, sizeof(*res));
888 res->format = orig->format;
889 res->width0 = box->width;
890 res->height0 = box->height;
891 res->depth0 = 1;
892 res->array_size = 1;
893 res->usage = flags & R600_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
894 res->flags = flags;
895
896 /* We must set the correct texture target and dimensions for a 3D box. */
897 if (box->depth > 1 && util_max_layer(orig, level) > 0)
898 res->target = orig->target;
899 else
900 res->target = PIPE_TEXTURE_2D;
901
902 switch (res->target) {
903 case PIPE_TEXTURE_1D_ARRAY:
904 case PIPE_TEXTURE_2D_ARRAY:
905 case PIPE_TEXTURE_CUBE_ARRAY:
906 res->array_size = box->depth;
907 break;
908 case PIPE_TEXTURE_3D:
909 res->depth0 = box->depth;
910 break;
911 default:;
912 }
913 }
914
915 static void *r600_texture_transfer_map(struct pipe_context *ctx,
916 struct pipe_resource *texture,
917 unsigned level,
918 unsigned usage,
919 const struct pipe_box *box,
920 struct pipe_transfer **ptransfer)
921 {
922 struct r600_common_context *rctx = (struct r600_common_context*)ctx;
923 struct r600_texture *rtex = (struct r600_texture*)texture;
924 struct r600_transfer *trans;
925 boolean use_staging_texture = FALSE;
926 struct r600_resource *buf;
927 unsigned offset = 0;
928 char *map;
929
930 /* We cannot map a tiled texture directly because the data is
931 * in a different order, therefore we do detiling using a blit.
932 *
933 * Also, use a temporary in GTT memory for read transfers, as
934 * the CPU is much happier reading out of cached system memory
935 * than uncached VRAM.
936 */
937 if (rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D) {
938 use_staging_texture = TRUE;
939 } else if ((usage & PIPE_TRANSFER_READ) && !(usage & PIPE_TRANSFER_MAP_DIRECTLY) &&
940 (rtex->resource.domains == RADEON_DOMAIN_VRAM)) {
941 /* Untiled buffers in VRAM, which is slow for CPU reads */
942 use_staging_texture = TRUE;
943 } else if (!(usage & PIPE_TRANSFER_READ) &&
944 (r600_rings_is_buffer_referenced(rctx, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
945 !rctx->ws->buffer_wait(rtex->resource.buf, 0, RADEON_USAGE_READWRITE))) {
946 /* Use a staging texture for uploads if the underlying BO is busy. */
947 use_staging_texture = TRUE;
948 }
949
950 if (texture->flags & R600_RESOURCE_FLAG_TRANSFER) {
951 use_staging_texture = FALSE;
952 }
953
954 if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
955 return NULL;
956 }
957
958 trans = CALLOC_STRUCT(r600_transfer);
959 if (trans == NULL)
960 return NULL;
961 trans->transfer.resource = texture;
962 trans->transfer.level = level;
963 trans->transfer.usage = usage;
964 trans->transfer.box = *box;
965
966 if (rtex->is_depth) {
967 struct r600_texture *staging_depth;
968
969 if (rtex->resource.b.b.nr_samples > 1) {
970 /* MSAA depth buffers need to be converted to single sample buffers.
971 *
972 * Mapping MSAA depth buffers can occur if ReadPixels is called
973 * with a multisample GLX visual.
974 *
975 * First downsample the depth buffer to a temporary texture,
976 * then decompress the temporary one to staging.
977 *
978 * Only the region being mapped is transfered.
979 */
980 struct pipe_resource resource;
981
982 r600_init_temp_resource_from_box(&resource, texture, box, level, 0);
983
984 if (!r600_init_flushed_depth_texture(ctx, &resource, &staging_depth)) {
985 R600_ERR("failed to create temporary texture to hold untiled copy\n");
986 FREE(trans);
987 return NULL;
988 }
989
990 if (usage & PIPE_TRANSFER_READ) {
991 struct pipe_resource *temp = ctx->screen->resource_create(ctx->screen, &resource);
992 if (!temp) {
993 R600_ERR("failed to create a temporary depth texture\n");
994 FREE(trans);
995 return NULL;
996 }
997
998 r600_copy_region_with_blit(ctx, temp, 0, 0, 0, 0, texture, level, box);
999 rctx->blit_decompress_depth(ctx, (struct r600_texture*)temp, staging_depth,
1000 0, 0, 0, box->depth, 0, 0);
1001 pipe_resource_reference((struct pipe_resource**)&temp, NULL);
1002 }
1003 }
1004 else {
1005 /* XXX: only readback the rectangle which is being mapped? */
1006 /* XXX: when discard is true, no need to read back from depth texture */
1007 if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
1008 R600_ERR("failed to create temporary texture to hold untiled copy\n");
1009 FREE(trans);
1010 return NULL;
1011 }
1012
1013 rctx->blit_decompress_depth(ctx, rtex, staging_depth,
1014 level, level,
1015 box->z, box->z + box->depth - 1,
1016 0, 0);
1017
1018 offset = r600_texture_get_offset(staging_depth, level, box);
1019 }
1020
1021 trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes;
1022 trans->transfer.layer_stride = staging_depth->surface.level[level].slice_size;
1023 trans->staging = (struct r600_resource*)staging_depth;
1024 } else if (use_staging_texture) {
1025 struct pipe_resource resource;
1026 struct r600_texture *staging;
1027
1028 r600_init_temp_resource_from_box(&resource, texture, box, level,
1029 R600_RESOURCE_FLAG_TRANSFER);
1030 resource.usage = (usage & PIPE_TRANSFER_READ) ?
1031 PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
1032
1033 /* Create the temporary texture. */
1034 staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource);
1035 if (staging == NULL) {
1036 R600_ERR("failed to create temporary texture to hold untiled copy\n");
1037 FREE(trans);
1038 return NULL;
1039 }
1040 trans->staging = &staging->resource;
1041 trans->transfer.stride = staging->surface.level[0].pitch_bytes;
1042 trans->transfer.layer_stride = staging->surface.level[0].slice_size;
1043 if (usage & PIPE_TRANSFER_READ) {
1044 r600_copy_to_staging_texture(ctx, trans);
1045 }
1046 } else {
1047 /* the resource is mapped directly */
1048 trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
1049 trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
1050 offset = r600_texture_get_offset(rtex, level, box);
1051 }
1052
1053 if (trans->staging) {
1054 buf = trans->staging;
1055 if (!rtex->is_depth && !(usage & PIPE_TRANSFER_READ))
1056 usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
1057 } else {
1058 buf = &rtex->resource;
1059 }
1060
1061 if (!(map = r600_buffer_map_sync_with_rings(rctx, buf, usage))) {
1062 pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL);
1063 FREE(trans);
1064 return NULL;
1065 }
1066
1067 *ptransfer = &trans->transfer;
1068 return map + offset;
1069 }
1070
1071 static void r600_texture_transfer_unmap(struct pipe_context *ctx,
1072 struct pipe_transfer* transfer)
1073 {
1074 struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
1075 struct pipe_resource *texture = transfer->resource;
1076 struct r600_texture *rtex = (struct r600_texture*)texture;
1077
1078 if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) {
1079 if (rtex->is_depth && rtex->resource.b.b.nr_samples <= 1) {
1080 ctx->resource_copy_region(ctx, texture, transfer->level,
1081 transfer->box.x, transfer->box.y, transfer->box.z,
1082 &rtransfer->staging->b.b, transfer->level,
1083 &transfer->box);
1084 } else {
1085 r600_copy_from_staging_texture(ctx, rtransfer);
1086 }
1087 }
1088
1089 if (rtransfer->staging)
1090 pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
1091
1092 FREE(transfer);
1093 }
1094
1095 static const struct u_resource_vtbl r600_texture_vtbl =
1096 {
1097 NULL, /* get_handle */
1098 r600_texture_destroy, /* resource_destroy */
1099 r600_texture_transfer_map, /* transfer_map */
1100 u_default_transfer_flush_region, /* transfer_flush_region */
1101 r600_texture_transfer_unmap, /* transfer_unmap */
1102 NULL /* transfer_inline_write */
1103 };
1104
1105 struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
1106 struct pipe_resource *texture,
1107 const struct pipe_surface *templ,
1108 unsigned width, unsigned height)
1109 {
1110 struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
1111
1112 if (surface == NULL)
1113 return NULL;
1114
1115 assert(templ->u.tex.first_layer <= util_max_layer(texture, templ->u.tex.level));
1116 assert(templ->u.tex.last_layer <= util_max_layer(texture, templ->u.tex.level));
1117
1118 pipe_reference_init(&surface->base.reference, 1);
1119 pipe_resource_reference(&surface->base.texture, texture);
1120 surface->base.context = pipe;
1121 surface->base.format = templ->format;
1122 surface->base.width = width;
1123 surface->base.height = height;
1124 surface->base.u = templ->u;
1125 return &surface->base;
1126 }
1127
1128 static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
1129 struct pipe_resource *tex,
1130 const struct pipe_surface *templ)
1131 {
1132 unsigned level = templ->u.tex.level;
1133
1134 return r600_create_surface_custom(pipe, tex, templ,
1135 u_minify(tex->width0, level),
1136 u_minify(tex->height0, level));
1137 }
1138
1139 static void r600_surface_destroy(struct pipe_context *pipe,
1140 struct pipe_surface *surface)
1141 {
1142 struct r600_surface *surf = (struct r600_surface*)surface;
1143 pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL);
1144 pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL);
1145 pipe_resource_reference(&surface->texture, NULL);
1146 FREE(surface);
1147 }
1148
1149 unsigned r600_translate_colorswap(enum pipe_format format)
1150 {
1151 const struct util_format_description *desc = util_format_description(format);
1152
1153 #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == UTIL_FORMAT_SWIZZLE_##swz)
1154
1155 if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
1156 return V_0280A0_SWAP_STD;
1157
1158 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
1159 return ~0U;
1160
1161 switch (desc->nr_channels) {
1162 case 1:
1163 if (HAS_SWIZZLE(0,X))
1164 return V_0280A0_SWAP_STD; /* X___ */
1165 else if (HAS_SWIZZLE(3,X))
1166 return V_0280A0_SWAP_ALT_REV; /* ___X */
1167 break;
1168 case 2:
1169 if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) ||
1170 (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) ||
1171 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y)))
1172 return V_0280A0_SWAP_STD; /* XY__ */
1173 else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) ||
1174 (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) ||
1175 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X)))
1176 return V_0280A0_SWAP_STD_REV; /* YX__ */
1177 else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y))
1178 return V_0280A0_SWAP_ALT; /* X__Y */
1179 else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X))
1180 return V_0280A0_SWAP_ALT_REV; /* Y__X */
1181 break;
1182 case 3:
1183 if (HAS_SWIZZLE(0,X))
1184 return V_0280A0_SWAP_STD; /* XYZ */
1185 else if (HAS_SWIZZLE(0,Z))
1186 return V_0280A0_SWAP_STD_REV; /* ZYX */
1187 break;
1188 case 4:
1189 /* check the middle channels, the 1st and 4th channel can be NONE */
1190 if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z))
1191 return V_0280A0_SWAP_STD; /* XYZW */
1192 else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y))
1193 return V_0280A0_SWAP_STD_REV; /* WZYX */
1194 else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X))
1195 return V_0280A0_SWAP_ALT; /* ZYXW */
1196 else if (HAS_SWIZZLE(1,X) && HAS_SWIZZLE(2,Y))
1197 return V_0280A0_SWAP_ALT_REV; /* WXYZ */
1198 break;
1199 }
1200 return ~0U;
1201 }
1202
1203 static void evergreen_set_clear_color(struct r600_texture *rtex,
1204 enum pipe_format surface_format,
1205 const union pipe_color_union *color)
1206 {
1207 union util_color uc;
1208
1209 memset(&uc, 0, sizeof(uc));
1210
1211 if (util_format_is_pure_uint(surface_format)) {
1212 util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
1213 } else if (util_format_is_pure_sint(surface_format)) {
1214 util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1);
1215 } else {
1216 util_pack_color(color->f, surface_format, &uc);
1217 }
1218
1219 memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
1220 }
1221
1222 void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
1223 struct pipe_framebuffer_state *fb,
1224 struct r600_atom *fb_state,
1225 unsigned *buffers, unsigned *dirty_cbufs,
1226 const union pipe_color_union *color)
1227 {
1228 int i;
1229
1230 if (rctx->current_render_cond)
1231 return;
1232
1233 for (i = 0; i < fb->nr_cbufs; i++) {
1234 struct r600_texture *tex;
1235 unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
1236
1237 if (!fb->cbufs[i])
1238 continue;
1239
1240 /* if this colorbuffer is not being cleared */
1241 if (!(*buffers & clear_bit))
1242 continue;
1243
1244 tex = (struct r600_texture *)fb->cbufs[i]->texture;
1245
1246 /* 128-bit formats are unusupported */
1247 if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
1248 continue;
1249 }
1250
1251 /* the clear is allowed if all layers are bound */
1252 if (fb->cbufs[i]->u.tex.first_layer != 0 ||
1253 fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
1254 continue;
1255 }
1256
1257 /* cannot clear mipmapped textures */
1258 if (fb->cbufs[i]->texture->last_level != 0) {
1259 continue;
1260 }
1261
1262 /* only supported on tiled surfaces */
1263 if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
1264 continue;
1265 }
1266
1267 /* fast color clear with 1D tiling doesn't work on old kernels and CIK */
1268 if (tex->surface.level[0].mode == RADEON_SURF_MODE_1D &&
1269 rctx->chip_class >= CIK &&
1270 rctx->screen->info.drm_major == 2 &&
1271 rctx->screen->info.drm_minor < 38) {
1272 continue;
1273 }
1274
1275 /* ensure CMASK is enabled */
1276 r600_texture_alloc_cmask_separate(rctx->screen, tex);
1277 if (tex->cmask.size == 0) {
1278 continue;
1279 }
1280
1281 /* Do the fast clear. */
1282 evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
1283 rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
1284 tex->cmask.offset, tex->cmask.size, 0, true);
1285
1286 tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
1287 if (dirty_cbufs)
1288 *dirty_cbufs |= 1 << i;
1289 rctx->set_atom_dirty(rctx, fb_state, true);
1290 *buffers &= ~clear_bit;
1291 }
1292 }
1293
1294 void r600_init_screen_texture_functions(struct r600_common_screen *rscreen)
1295 {
1296 rscreen->b.resource_from_handle = r600_texture_from_handle;
1297 rscreen->b.resource_get_handle = r600_texture_get_handle;
1298 }
1299
1300 void r600_init_context_texture_functions(struct r600_common_context *rctx)
1301 {
1302 rctx->b.create_surface = r600_create_surface;
1303 rctx->b.surface_destroy = r600_surface_destroy;
1304 }