Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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