r600_texture.c revision 2a311b18fce9ea6538b0997ad23d86a061fb273c
1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/*
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Permission is hereby granted, free of charge, to any person obtaining a
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * copy of this software and associated documentation files (the "Software"),
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * to deal in the Software without restriction, including without limitation
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * on the rights to use, copy, modify, merge, publish, distribute, sub
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * license, and/or sell copies of the Software, and to permit persons to whom
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the Software is furnished to do so, subject to the following conditions:
10a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * The above copyright notice and this permission notice (including the next
12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * paragraph) shall be included in all copies or substantial portions of the
13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Software.
14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * USE OR OTHER DEALINGS IN THE SOFTWARE.
22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Authors:
24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *      Jerome Glisse
25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *      Corbin Simpson
26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <errno.h>
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "pipe/p_screen.h"
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_format.h"
30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_format_s3tc.h"
31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_math.h"
32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_inlines.h"
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_memory.h"
34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "pipebuffer/pb_buffer.h"
35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeonsi_pipe.h"
36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "r600_resource.h"
37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "sid.h"
38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Copy from a full GPU texture to a transfer's staging one. */
40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource *texture = transfer->resource;
44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->resource_copy_region(ctx, rtransfer->staging_texture,
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				0, 0, 0, 0, texture, transfer->level,
47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				&transfer->box);
48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Copy from a transfer's staging texture to a full GPU one. */
52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource *texture = transfer->resource;
56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_box sbox;
57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.x = sbox.y = sbox.z = 0;
59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.width = transfer->box.width;
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.height = transfer->box.height;
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX that might be wrong */
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.depth = 1;
63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->resource_copy_region(ctx, texture, transfer->level,
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				  transfer->box.x, transfer->box.y, transfer->box.z,
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				  rtransfer->staging_texture,
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				  0, &sbox);
67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardunsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					unsigned level, unsigned layer)
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned offset = rtex->offset[level];
73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
742a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	switch (rtex->resource.b.b.target) {
75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_3D:
76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_CUBE:
77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return offset + layer * rtex->layer_size[level];
79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_block_alignment(struct pipe_screen *screen,
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					 enum pipe_format format,
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					 unsigned array_mode)
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen* rscreen = (struct r600_screen *)screen;
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned pixsize = util_format_get_blocksize(format);
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int p_align;
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch(array_mode) {
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_1D_TILED_THIN1:
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		p_align = MAX2(8,
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       ((rscreen->tiling_info.group_bytes / 8 / pixsize)));
95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_2D_TILED_THIN1:
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		p_align = MAX2(rscreen->tiling_info.num_banks,
98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       (((rscreen->tiling_info.group_bytes / 8 / pixsize)) *
99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				rscreen->tiling_info.num_banks)) * 8;
100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_ALIGNED:
102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize);
103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_GENERAL:
105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		p_align = rscreen->tiling_info.group_bytes / pixsize;
108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return p_align;
111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
113a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_height_alignment(struct pipe_screen *screen,
114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					  unsigned array_mode)
115a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
116a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen* rscreen = (struct r600_screen *)screen;
117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int h_align;
118a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (array_mode) {
120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_2D_TILED_THIN1:
122a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		h_align = rscreen->tiling_info.num_channels * 8;
123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_1D_TILED_THIN1:
125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_ALIGNED:
126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		h_align = 8;
127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_GENERAL:
129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		h_align = 1;
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return h_align;
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_base_alignment(struct pipe_screen *screen,
138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					enum pipe_format format,
139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					unsigned array_mode)
140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen* rscreen = (struct r600_screen *)screen;
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned pixsize = util_format_get_blocksize(format);
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int p_align = r600_get_block_alignment(screen, format, array_mode);
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int h_align = r600_get_height_alignment(screen, array_mode);
145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int b_align;
146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (array_mode) {
148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_2D_TILED_THIN1:
150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels * 8 * 8 * pixsize,
151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       p_align * pixsize * h_align);
152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_1D_TILED_THIN1:
154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_ALIGNED:
155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_038000_ARRAY_LINEAR_GENERAL:
156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		b_align = rscreen->tiling_info.group_bytes;
159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return b_align;
162a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned mip_minify(unsigned size, unsigned level)
165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned val;
167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	val = u_minify(size, level);
168a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (level > 0)
169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		val = util_next_power_of_two(val);
170a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return val;
171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_texture_get_nblocksx(struct pipe_screen *screen,
174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					  struct r600_resource_texture *rtex,
175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					  unsigned level)
176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
1772a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	struct pipe_resource *ptex = &rtex->resource.b.b;
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned nblocksx, block_align, width;
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned blocksize = util_format_get_blocksize(rtex->real_format);
180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->pitch_override)
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return rtex->pitch_override / blocksize;
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	width = mip_minify(ptex->width0, level);
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	nblocksx = util_format_get_nblocksx(rtex->real_format, width);
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	block_align = r600_get_block_alignment(screen, rtex->real_format,
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					      rtex->array_mode[level]);
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	nblocksx = align(nblocksx, block_align);
190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return nblocksx;
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_texture_get_nblocksy(struct pipe_screen *screen,
194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					  struct r600_resource_texture *rtex,
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					  unsigned level)
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
1972a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	struct pipe_resource *ptex = &rtex->resource.b.b;
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned height, tile_height;
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	height = mip_minify(ptex->height0, level);
201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	height = util_format_get_nblocksy(rtex->real_format, height);
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tile_height = r600_get_height_alignment(screen,
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						rtex->array_mode[level]);
204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX Hack around an alignment issue. Less tests fail with this.
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * The thing is depth-stencil buffers should be tiled, i.e.
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * the alignment should be >=8. If I make them tiled, stencil starts
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * working because it no longer overlaps with the depth buffer
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * in memory, but texturing like drawpix-stencil breaks. */
211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_depth_or_stencil(rtex->real_format) && tile_height < 8)
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		tile_height = 8;
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	height = align(height, tile_height);
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return height;
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_texture_set_array_mode(struct pipe_screen *screen,
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					struct r600_resource_texture *rtex,
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					unsigned level, unsigned array_mode)
221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
2222a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	struct pipe_resource *ptex = &rtex->resource.b.b;
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (array_mode) {
225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_0280A0_ARRAY_LINEAR_GENERAL:
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_0280A0_ARRAY_LINEAR_ALIGNED:
228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_0280A0_ARRAY_1D_TILED_THIN1:
229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->array_mode[level] = array_mode;
232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case V_0280A0_ARRAY_2D_TILED_THIN1:
235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	{
236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned w, h, tile_height, tile_width;
237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
238a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		tile_height = r600_get_height_alignment(screen, array_mode);
239a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		tile_width = r600_get_block_alignment(screen, rtex->real_format, array_mode);
240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
241a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		w = mip_minify(ptex->width0, level);
242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		h = mip_minify(ptex->height0, level);
243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (w <= tile_width || h <= tile_height)
244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->array_mode[level] = V_0280A0_ARRAY_1D_TILED_THIN1;
245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else
246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->array_mode[level] = array_mode;
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	break;
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_setup_miptree(struct pipe_screen *screen,
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       struct r600_resource_texture *rtex,
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       unsigned array_mode)
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
2572a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	struct pipe_resource *ptex = &rtex->resource.b.b;
258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum chip_class chipc = ((struct r600_screen*)screen)->chip_class;
259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned size, layer_size, i, offset;
260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned nblocksx, nblocksy;
261a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	for (i = 0, offset = 0; i <= ptex->last_level; i++) {
263a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned blocksize = util_format_get_blocksize(rtex->real_format);
264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned base_align = r600_get_base_alignment(screen, rtex->real_format, array_mode);
265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		r600_texture_set_array_mode(screen, rtex, i, array_mode);
267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		nblocksx = r600_texture_get_nblocksx(screen, rtex, i);
269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		nblocksy = r600_texture_get_nblocksy(screen, rtex, i);
270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (chipc >= CAYMAN /*&& array_mode == V_038000_ARRAY_LINEAR_GENERAL*/)
272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			layer_size = align(nblocksx, 64) * nblocksy * blocksize;
273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else
274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			layer_size = nblocksx * nblocksy * blocksize;
275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (ptex->target == PIPE_TEXTURE_CUBE) {
277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			if (chipc >= CAYMAN)
278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				size = layer_size * 8;
279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else if (ptex->target == PIPE_TEXTURE_3D)
281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			size = layer_size * u_minify(ptex->depth0, i);
282a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else
283a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			size = layer_size * ptex->array_size;
284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* align base image and start of miptree */
286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if ((i == 0) || (i == 1))
287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			offset = align(offset, base_align);
288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->offset[i] = offset;
289a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->layer_size[i] = layer_size;
290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */
291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->pitch_in_bytes[i] = nblocksx * blocksize;
292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		offset += size;
294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->size = offset;
296a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Figure out whether u_blitter will fallback to a transfer operation.
299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * If so, don't use a staging resource.
300a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
301a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean permit_hardware_blit(struct pipe_screen *screen,
302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					const struct pipe_resource *res)
303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned bind;
305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
306a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_depth_or_stencil(res->format))
307a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		bind = PIPE_BIND_DEPTH_STENCIL;
308a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else
309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		bind = PIPE_BIND_RENDER_TARGET;
310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* hackaround for S3TC */
312a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_compressed(res->format))
313a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return TRUE;
314a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
315a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!screen->is_format_supported(screen,
316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->format,
317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->target,
318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->nr_samples,
319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                                bind))
320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!screen->is_format_supported(screen,
323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->format,
324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->target,
325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->nr_samples,
326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                                PIPE_BIND_SAMPLER_VIEW))
327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (res->usage) {
330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_USAGE_STREAM:
331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_USAGE_STAGING:
332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
333a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return TRUE;
336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
338a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					struct pipe_resource *ptex,
341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					struct winsys_handle *whandle)
342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource *resource = &rtex->resource;
345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return rscreen->ws->buffer_get_handle(resource->buf,
348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					      rtex->pitch_in_bytes[0], whandle);
349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_texture_destroy(struct pipe_screen *screen,
352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 struct pipe_resource *ptex)
353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource *resource = &rtex->resource;
356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture)
358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->stencil)
361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		pipe_resource_reference((struct pipe_resource **)&rtex->stencil, NULL);
362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pb_reference(&resource->buf, NULL);
364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	FREE(rtex);
365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic const struct u_resource_vtbl r600_texture_vtbl =
368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_get_handle,	/* get_handle */
370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_destroy,		/* resource_destroy */
371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_get_transfer,	/* get_transfer */
372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_transfer_destroy,	/* transfer_destroy */
373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_transfer_map,	/* transfer_map */
374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	u_default_transfer_flush_region,/* transfer_flush_region */
375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_transfer_unmap,	/* transfer_unmap */
376a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	u_default_transfer_inline_write	/* transfer_inline_write */
377a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct r600_resource_texture *
380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardr600_texture_create_object(struct pipe_screen *screen,
381a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   const struct pipe_resource *base,
382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned array_mode,
383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned pitch_in_bytes_override,
384a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned max_buffer_size,
385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   struct pb_buffer *buf,
386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   boolean alloc_bo)
387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
388a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex;
389a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource *resource;
390a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
391a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
392a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex = CALLOC_STRUCT(r600_resource_texture);
393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex == NULL)
394a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource = &rtex->resource;
3972a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.b = *base;
3982a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.vtbl = &r600_texture_vtbl;
3992a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	pipe_reference_init(&resource->b.b.reference, 1);
4002a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.b.screen = screen;
401a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->pitch_override = pitch_in_bytes_override;
402a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->real_format = base->format;
403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
404a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* We must split depth and stencil into two separate buffers on Evergreen. */
405a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!(base->flags & R600_RESOURCE_FLAG_TRANSFER) &&
406a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	    ((struct r600_screen*)screen)->chip_class >= CAYMAN &&
407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	    util_format_is_depth_and_stencil(base->format)) {
408a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct pipe_resource stencil;
409a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned stencil_pitch_override = 0;
410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		switch (base->format) {
412a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		case PIPE_FORMAT_Z24_UNORM_S8_UINT:
413a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->real_format = PIPE_FORMAT_Z24X8_UNORM;
414a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			break;
415a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		case PIPE_FORMAT_S8_UINT_Z24_UNORM:
416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->real_format = PIPE_FORMAT_X8Z24_UNORM;
417a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			break;
418a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
419a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->real_format = PIPE_FORMAT_Z32_FLOAT;
420a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			break;
421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		default:
422a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			assert(0);
423a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(rtex);
424a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
426a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
427a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* Divide the pitch in bytes by 4 for stencil, because it has a smaller pixel size. */
428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (pitch_in_bytes_override) {
429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			assert(base->format == PIPE_FORMAT_Z24_UNORM_S8_UINT ||
430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			       base->format == PIPE_FORMAT_S8_UINT_Z24_UNORM);
431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			stencil_pitch_override = pitch_in_bytes_override / 4;
432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
434a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* Allocate the stencil buffer. */
435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		stencil = *base;
436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		stencil.format = PIPE_FORMAT_S8_UINT;
437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->stencil = r600_texture_create_object(screen, &stencil, array_mode,
438a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							   stencil_pitch_override,
439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							   max_buffer_size, NULL, FALSE);
440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (!rtex->stencil) {
441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(rtex);
442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
443a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* Proceed in creating the depth buffer. */
445a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
447a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* only mark depth textures the HW can hit as depth textures */
448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
449a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->depth = 1;
450a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
451a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_setup_miptree(screen, rtex, array_mode);
452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* If we initialized separate stencil for Evergreen. place it after depth. */
454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->stencil) {
455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned stencil_align, stencil_offset;
456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		stencil_align = r600_get_base_alignment(screen, rtex->stencil->real_format, array_mode);
458a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		stencil_offset = align(rtex->size, stencil_align);
459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
4602a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák		for (unsigned i = 0; i <= rtex->stencil->resource.b.b.last_level; i++)
461a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rtex->stencil->offset[i] += stencil_offset;
462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->size = stencil_offset + rtex->stencil->size;
464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Now create the backing buffer. */
467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!buf && alloc_bo) {
4682a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák		struct pipe_resource *ptex = &rtex->resource.b.b;
469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			pipe_resource_reference((struct pipe_resource**)&rtex->stencil, NULL);
473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(rtex);
474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else if (buf) {
477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->buf = buf;
478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
481a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
482a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->stencil) {
483a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf);
484a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->stencil->resource.cs_buf = rtex->resource.cs_buf;
485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->stencil->resource.domains = rtex->resource.domains;
486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
487a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return rtex;
488a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
489a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
490a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardDEBUG_GET_ONCE_BOOL_OPTION(tiling_enabled, "R600_TILING", FALSE);
491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_resource *r600_texture_create(struct pipe_screen *screen,
493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						const struct pipe_resource *templ)
494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
495a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned array_mode = 0;
497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
498a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	    !(templ->bind & PIPE_BIND_SCANOUT)) {
500a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (util_format_is_compressed(templ->format)) {
502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			array_mode = V_038000_ARRAY_1D_TILED_THIN1;
503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
504a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else if (debug_get_option_tiling_enabled() &&
505a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			 rscreen->info.drm_minor >= 9 &&
506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			 permit_hardware_blit(screen, templ)) {
507a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
508a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
511a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard								  0, 0, NULL, TRUE);
514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						struct pipe_resource *texture,
518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						const struct pipe_surface *surf_tmpl)
519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
520a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
521a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
522a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned level = surf_tmpl->u.tex.level;
523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
524a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
525a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (surface == NULL)
526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
527a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX no offset */
528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/*	offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
529a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_reference_init(&surface->base.reference, 1);
530a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&surface->base.texture, texture);
531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.context = pipe;
532a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.format = surf_tmpl->format;
533a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.width = mip_minify(texture->width0, level);
534a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.height = mip_minify(texture->height0, level);
535a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.usage = surf_tmpl->usage;
536a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.texture = texture;
537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
538a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
539a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.level = level;
540a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
541a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->aligned_height = r600_texture_get_nblocksy(pipe->screen,
542a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							    rtex, level);
543a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return &surface->base;
544a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
545a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
546a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_surface_destroy(struct pipe_context *pipe,
547a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 struct pipe_surface *surface)
548a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
549a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&surface->texture, NULL);
550a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	FREE(surface);
551a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
552a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
553a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
554a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					       const struct pipe_resource *templ,
555a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					       struct winsys_handle *whandle)
556a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
557a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
558a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pb_buffer *buf = NULL;
559a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned stride = 0;
560a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned array_mode = 0;
561a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum radeon_bo_layout micro, macro;
562a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
563a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Support only 2D textures without mipmaps */
564a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
565a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	      templ->depth0 != 1 || templ->last_level != 0)
566a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
567a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
568a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
569a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!buf)
570a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
571a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
572a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rscreen->ws->buffer_get_tiling(buf, &micro, &macro, NULL, NULL, NULL, NULL, NULL);
573a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
574a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
575a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (macro == RADEON_LAYOUT_TILED)
576a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
577a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else if (micro == RADEON_LAYOUT_TILED)
578a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
579a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else
580a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
581a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		array_mode = 0;
582a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
583a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
584a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard								  stride, 0, buf, FALSE);
585a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
586a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
587a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardint r600_texture_depth_flush(struct pipe_context *ctx,
588a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			     struct pipe_resource *texture, boolean just_create)
589a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
590a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
591a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource resource;
592a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
593a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture)
594a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		goto out;
595a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
596a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.target = texture->target;
597a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.format = texture->format;
598a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.width0 = texture->width0;
599a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.height0 = texture->height0;
600a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.depth0 = texture->depth0;
601a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.array_size = texture->array_size;
602a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.last_level = texture->last_level;
603a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.nr_samples = texture->nr_samples;
604a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.usage = PIPE_USAGE_DYNAMIC;
605a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL;
606a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags;
607a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
608a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource);
609a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture == NULL) {
610a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		R600_ERR("failed to create temporary texture to hold untiled copy\n");
611a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return -ENOMEM;
612a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
613a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
614a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE;
615a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardout:
616a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (just_create)
617a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return 0;
618a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
619a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: only do this if the depth texture has actually changed:
620a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
621a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blit_uncompress_depth(ctx, rtex);
622a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return 0;
623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
624a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
625a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Needs adjustment for pixelformat:
626a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
627a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic INLINE unsigned u_box_volume( const struct pipe_box *box )
628a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
629a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return box->width * box->depth * box->height;
630a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
632a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
633a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						struct pipe_resource *texture,
634a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						unsigned level,
635a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						unsigned usage,
636a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						const struct pipe_box *box)
637a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource resource;
640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_transfer *trans;
641a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int r;
642a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	boolean use_staging_texture = FALSE;
643a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
644a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0
645a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* We cannot map a tiled texture directly because the data is
646a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * in a different order, therefore we do detiling using a blit.
647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *
648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * Also, use a temporary in GTT memory for read transfers, as
649a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * the CPU is much happier reading out of cached system memory
650a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * than uncached VRAM.
651a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
652a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (R600_TEX_IS_TILED(rtex, level))
653a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		use_staging_texture = TRUE;
654a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif
655a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
656a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
657a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		use_staging_texture = TRUE;
658a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
659a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: Use a staging texture for uploads if the underlying BO
660a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * is busy.  No interface for checking that currently? so do
661a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * it eagerly whenever the transfer doesn't require a readback
662a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * and might block.
663a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
664a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if ((usage & PIPE_TRANSFER_WRITE) &&
665a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			!(usage & (PIPE_TRANSFER_READ |
666a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					PIPE_TRANSFER_DONTBLOCK |
667a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					PIPE_TRANSFER_UNSYNCHRONIZED)))
668a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		use_staging_texture = TRUE;
669a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
670a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!permit_hardware_blit(ctx->screen, texture) ||
671a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		(texture->flags & R600_RESOURCE_FLAG_TRANSFER))
672a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		use_staging_texture = FALSE;
673a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
674a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
675a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
676a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
677a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans = CALLOC_STRUCT(r600_transfer);
678a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (trans == NULL)
679a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
680a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&trans->transfer.resource, texture);
681a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->transfer.level = level;
682a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->transfer.usage = usage;
683a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->transfer.box = *box;
684a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->depth) {
685a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* XXX: only readback the rectangle which is being mapped?
686a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		*/
687a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* XXX: when discard is true, no need to read back from depth texture
688a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		*/
689a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		r = r600_texture_depth_flush(ctx, texture, FALSE);
690a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (r < 0) {
691a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			R600_ERR("failed to create temporary texture to hold untiled copy\n");
692a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			pipe_resource_reference(&trans->transfer.resource, NULL);
693a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(trans);
694a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
695a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
696a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level];
697a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
698a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return &trans->transfer;
699a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else if (use_staging_texture) {
700a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.target = PIPE_TEXTURE_2D;
701a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.format = texture->format;
702a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.width0 = box->width;
703a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.height0 = box->height;
704a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.depth0 = 1;
705a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.array_size = 1;
706a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.last_level = 0;
707a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.nr_samples = 0;
708a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.usage = PIPE_USAGE_STAGING;
709a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.bind = 0;
710a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
711a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* For texture reading, the temporary (detiled) texture is used as
712a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		 * a render target when blitting from a tiled texture. */
713a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (usage & PIPE_TRANSFER_READ) {
714a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			resource.bind |= PIPE_BIND_RENDER_TARGET;
715a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
716a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* For texture writing, the temporary texture is used as a sampler
717a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		 * when blitting into a tiled texture. */
718a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (usage & PIPE_TRANSFER_WRITE) {
719a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
720a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
721a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* Create the temporary texture. */
722a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
723a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (trans->staging_texture == NULL) {
724a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			R600_ERR("failed to create temporary texture to hold untiled copy\n");
725a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			pipe_resource_reference(&trans->transfer.resource, NULL);
726a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(trans);
727a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
728a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
729a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
730a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		trans->transfer.stride =
731a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
732a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (usage & PIPE_TRANSFER_READ) {
733a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			r600_copy_to_staging_texture(ctx, trans);
734a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			/* Always referenced in the blit. */
735a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			radeonsi_flush(ctx, NULL, 0);
736a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
737a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return &trans->transfer;
738a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
739a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->transfer.stride = rtex->pitch_in_bytes[level];
740a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->transfer.layer_stride = rtex->layer_size[level];
741a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	trans->offset = r600_texture_get_offset(rtex, level, box->z);
742a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return &trans->transfer;
743a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
744a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
745a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_texture_transfer_destroy(struct pipe_context *ctx,
746a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				   struct pipe_transfer *transfer)
747a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
748a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
749a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource *texture = transfer->resource;
750a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
751a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
752a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtransfer->staging_texture) {
753a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (transfer->usage & PIPE_TRANSFER_WRITE) {
754a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			r600_copy_from_staging_texture(ctx, rtransfer);
755a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
756a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		pipe_resource_reference(&rtransfer->staging_texture, NULL);
757a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
758a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
759a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->depth && !rtex->is_flushing_texture) {
760a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
761a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			r600_blit_push_depth(ctx, rtex);
762a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
763a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
764a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&transfer->resource, NULL);
765a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	FREE(transfer);
766a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
767a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
768a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid* r600_texture_transfer_map(struct pipe_context *ctx,
769a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				struct pipe_transfer* transfer)
770a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
771a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
772a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
773a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pb_buffer *buf;
774a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum pipe_format format = transfer->resource->format;
775a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned offset = 0;
776a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	char *map;
777a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
778a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtransfer->staging_texture) {
779a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		buf = ((struct r600_resource *)rtransfer->staging_texture)->buf;
780a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else {
781a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
782a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
783a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (rtex->flushed_depth_texture)
784a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf;
785a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		else
786a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			buf = ((struct r600_resource *)transfer->resource)->buf;
787a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
788a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		offset = rtransfer->offset +
789a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
790a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
791a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
792a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
793a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
794a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
795a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
796a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
797a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return map + offset;
798a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
799a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
800a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_texture_transfer_unmap(struct pipe_context *ctx,
801a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 struct pipe_transfer* transfer)
802a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
803a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
804a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context*)ctx;
805a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pb_buffer *buf;
806a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
807a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtransfer->staging_texture) {
808a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		buf = ((struct r600_resource *)rtransfer->staging_texture)->buf;
809a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else {
810a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
811a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
812a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (rtex->flushed_depth_texture) {
813a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf;
814a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		} else {
815a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			buf = ((struct r600_resource *)transfer->resource)->buf;
816a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
817a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
818a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rctx->ws->buffer_unmap(buf);
819a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
820a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
821a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_init_surface_functions(struct r600_context *r600)
822a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
823a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600->context.create_surface = r600_create_surface;
824a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600->context.surface_destroy = r600_surface_destroy;
825a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
826