1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on the rights to use, copy, modify, merge, publish, distribute, sub
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * license, and/or sell copies of the Software, and to permit persons to whom
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * USE OR OTHER DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Jerome Glisse
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Corbin Simpson
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h>
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format_s3tc.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipebuffer/pb_buffer.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeonsi_pipe.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r600_resource.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sid.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Copy from a full GPU texture to a transfer's staging one. */
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->resource_copy_region(ctx, rtransfer->staging_texture,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				0, 0, 0, 0, texture, transfer->level,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				&transfer->box);
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Copy from a transfer's staging texture to a full GPU one. */
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_box sbox;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sbox.x = sbox.y = sbox.z = 0;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sbox.width = transfer->box.width;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sbox.height = transfer->box.height;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX that might be wrong */
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sbox.depth = 1;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->resource_copy_region(ctx, texture, transfer->level,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  transfer->box.x, transfer->box.y, transfer->box.z,
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  rtransfer->staging_texture,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  0, &sbox);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					unsigned level, unsigned layer)
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rtex->surface.level[level].offset +
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       layer * rtex->surface.level[level].slice_size;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int r600_init_surface(struct radeon_surface *surface,
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     const struct pipe_resource *ptex,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     unsigned array_mode)
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_x = ptex->width0;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_y = ptex->height0;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_z = ptex->depth0;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_w = util_format_get_blockwidth(ptex->format);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_h = util_format_get_blockheight(ptex->format);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_d = 1;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->array_size = 1;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->last_level = ptex->last_level;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->bpe = util_format_get_blocksize(ptex->format);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* align byte per element on dword */
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (surface->bpe == 3) {
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->bpe = 4;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->nsamples = 1;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->flags = 0;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (array_mode) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_009910_ARRAY_1D_TILED_THIN1:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_009910_ARRAY_2D_TILED_THIN1:
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_009910_ARRAY_LINEAR_ALIGNED:
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_009910_ARRAY_LINEAR_GENERAL:
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (ptex->target) {
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_1D:
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_RECT:
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_2D:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_3D:
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_1D_ARRAY:
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->array_size = ptex->array_size;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_2D_ARRAY:
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->array_size = ptex->array_size;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_CUBE:
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_BUFFER:
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return -EINVAL;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ptex->bind & PIPE_BIND_SCANOUT) {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SCANOUT;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_is_depth_and_stencil(ptex->format)) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_ZBUFFER;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SBUFFER;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int r600_setup_surface(struct pipe_screen *screen,
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct r600_resource_texture *rtex,
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      unsigned array_mode,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      unsigned pitch_in_bytes_override)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_is_depth_or_stencil(rtex->real_format)) {
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.flags |= RADEON_SURF_ZBUFFER;
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.flags |= RADEON_SURF_SBUFFER;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return r;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* old ddx on evergreen over estimate alignment for 1d, only 1 level
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * for those
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 */
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Figure out whether u_blitter will fallback to a transfer operation.
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If so, don't use a staging resource.
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean permit_hardware_blit(struct pipe_screen *screen,
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					const struct pipe_resource *res)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned bind;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_is_depth_or_stencil(res->format))
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bind = PIPE_BIND_DEPTH_STENCIL;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bind = PIPE_BIND_RENDER_TARGET;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* hackaround for S3TC */
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_is_compressed(res->format))
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return TRUE;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!screen->is_format_supported(screen,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->format,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->target,
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->nr_samples,
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bind))
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return FALSE;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!screen->is_format_supported(screen,
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->format,
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->target,
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				res->nr_samples,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                PIPE_BIND_SAMPLER_VIEW))
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return FALSE;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (res->usage) {
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_USAGE_STREAM:
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_USAGE_STAGING:
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return FALSE;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return TRUE;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct pipe_resource *ptex,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct winsys_handle *whandle)
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct si_resource *resource = &rtex->resource;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface *surface = &rtex->surface;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rscreen->ws->buffer_set_tiling(resource->buf,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       NULL,
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->level[0].mode >= RADEON_SURF_MODE_1D ?
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->level[0].mode >= RADEON_SURF_MODE_2D ?
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->bankw, surface->bankh,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->tile_split,
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->stencil_tile_split,
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->mtilea,
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->level[0].pitch_bytes);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rscreen->ws->buffer_get_handle(resource->buf,
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      surface->level[0].pitch_bytes, whandle);
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_texture_destroy(struct pipe_screen *screen,
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct pipe_resource *ptex)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct si_resource *resource = &rtex->resource;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->flushed_depth_texture)
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		si_resource_reference((struct si_resource **)&rtex->flushed_depth_texture, NULL);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pb_reference(&resource->buf, NULL);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(rtex);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Needs adjustment for pixelformat:
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned u_box_volume( const struct pipe_box *box )
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return box->width * box->depth * box->height;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_transfer* si_texture_get_transfer(struct pipe_context *ctx,
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						     struct pipe_resource *texture,
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						     unsigned level,
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						     unsigned usage,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						     const struct pipe_box *box)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource resource;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *trans;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean use_staging_texture = FALSE;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* We cannot map a tiled texture directly because the data is
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * in a different order, therefore we do detiling using a blit.
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Also, use a temporary in GTT memory for read transfers, as
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * the CPU is much happier reading out of cached system memory
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * than uncached VRAM.
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->surface.level[level].mode != RADEON_SURF_MODE_LINEAR_ALIGNED &&
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    rtex->surface.level[level].mode != RADEON_SURF_MODE_LINEAR)
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = TRUE;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = TRUE;
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX: Use a staging texture for uploads if the underlying BO
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * is busy.  No interface for checking that currently? so do
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * it eagerly whenever the transfer doesn't require a readback
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * and might block.
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((usage & PIPE_TRANSFER_WRITE) &&
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			!(usage & (PIPE_TRANSFER_READ |
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					PIPE_TRANSFER_DONTBLOCK |
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					PIPE_TRANSFER_UNSYNCHRONIZED)))
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = TRUE;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!permit_hardware_blit(ctx->screen, texture) ||
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(texture->flags & R600_RESOURCE_FLAG_TRANSFER))
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = FALSE;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans = CALLOC_STRUCT(r600_transfer);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (trans == NULL)
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&trans->transfer.resource, texture);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.level = level;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.usage = usage;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.box = *box;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->depth) {
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* XXX: only readback the rectangle which is being mapped?
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*/
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* XXX: when discard is true, no need to read back from depth texture
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*/
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r = r600_texture_depth_flush(ctx, texture, FALSE);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (r < 0) {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			R600_ERR("failed to create temporary texture to hold untiled copy\n");
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe_resource_reference(&trans->transfer.resource, NULL);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(trans);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->transfer.stride = rtex->flushed_depth_texture->surface.level[level].pitch_bytes;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return &trans->transfer;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (use_staging_texture) {
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.target = PIPE_TEXTURE_2D;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.format = texture->format;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.width0 = box->width;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.height0 = box->height;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.depth0 = 1;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.array_size = 1;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.last_level = 0;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.nr_samples = 0;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.usage = PIPE_USAGE_STAGING;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.bind = 0;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* For texture reading, the temporary (detiled) texture is used as
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * a render target when blitting from a tiled texture. */
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_READ) {
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource.bind |= PIPE_BIND_RENDER_TARGET;
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* For texture writing, the temporary texture is used as a sampler
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * when blitting into a tiled texture. */
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_WRITE) {
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Create the temporary texture. */
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (trans->staging_texture == NULL) {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			R600_ERR("failed to create temporary texture to hold untiled copy\n");
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe_resource_reference(&trans->transfer.resource, NULL);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(trans);
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->transfer.stride = ((struct r600_resource_texture *)trans->staging_texture)
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					->surface.level[0].pitch_bytes;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_READ) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_copy_to_staging_texture(ctx, trans);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* Always referenced in the blit. */
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			radeonsi_flush(ctx, NULL, 0);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return &trans->transfer;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->offset = r600_texture_get_offset(rtex, level, box->z);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return &trans->transfer;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void si_texture_transfer_destroy(struct pipe_context *ctx,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct pipe_transfer *transfer)
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging_texture) {
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (transfer->usage & PIPE_TRANSFER_WRITE) {
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_copy_from_staging_texture(ctx, rtransfer);
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_resource_reference(&rtransfer->staging_texture, NULL);
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->depth && !rtex->is_flushing_texture) {
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_blit_push_depth(ctx, rtex);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&transfer->resource, NULL);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(transfer);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void* si_texture_transfer_map(struct pipe_context *ctx,
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     struct pipe_transfer* transfer)
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs_handle *buf;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum pipe_format format = transfer->resource->format;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned offset = 0;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char *map;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging_texture) {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = si_resource(rtransfer->staging_texture)->cs_buf;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rtex->flushed_depth_texture)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			buf = rtex->flushed_depth_texture->resource.cs_buf;
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			buf = si_resource(transfer->resource)->cs_buf;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		offset = rtransfer->offset +
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return map + offset;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void si_texture_transfer_unmap(struct pipe_context *ctx,
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      struct pipe_transfer* transfer)
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context*)ctx;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs_handle *buf;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging_texture) {
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = si_resource(rtransfer->staging_texture)->cs_buf;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rtex->flushed_depth_texture) {
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			buf = rtex->flushed_depth_texture->resource.cs_buf;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else {
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			buf = si_resource(transfer->resource)->cs_buf;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->ws->buffer_unmap(buf);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct u_resource_vtbl r600_texture_vtbl =
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_get_handle,	/* get_handle */
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_destroy,		/* resource_destroy */
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_texture_get_transfer,	/* get_transfer */
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_texture_transfer_destroy,	/* transfer_destroy */
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_texture_transfer_map,	/* transfer_map */
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	u_default_transfer_flush_region,/* transfer_flush_region */
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_texture_transfer_unmap,	/* transfer_unmap */
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	NULL	/* transfer_inline_write */
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct r600_resource_texture *
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgr600_texture_create_object(struct pipe_screen *screen,
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   const struct pipe_resource *base,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   unsigned array_mode,
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   unsigned pitch_in_bytes_override,
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   unsigned max_buffer_size,
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   struct pb_buffer *buf,
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   boolean alloc_bo,
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   struct radeon_surface *surface)
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct si_resource *resource;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex = CALLOC_STRUCT(r600_resource_texture);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex == NULL)
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource = &rtex->resource;
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.b = *base;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.vtbl = &r600_texture_vtbl;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_reference_init(&resource->b.b.reference, 1);
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.b.screen = screen;
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->pitch_override = pitch_in_bytes_override;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->real_format = base->format;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* only mark depth textures the HW can hit as depth textures */
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->depth = 1;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->surface = *surface;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		FREE(rtex);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Now create the backing buffer. */
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!buf && alloc_bo) {
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned base_align = rtex->surface.bo_alignment;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned size = rtex->surface.bo_size;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		base_align = rtex->surface.bo_alignment;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!si_init_resource(rscreen, resource, size, base_align, base->bind, base->usage)) {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(rtex);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (buf) {
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->buf = buf;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rtex;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource *si_texture_create(struct pipe_screen *screen,
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					const struct pipe_resource *templ)
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface surface;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned array_mode = 0;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    !(templ->bind & PIPE_BIND_SCANOUT)) {
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (permit_hardware_blit(screen, templ)) {
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			array_mode = V_009910_ARRAY_2D_TILED_THIN1;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_init_surface(&surface, templ, array_mode);
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = rscreen->ws->surface_best(rscreen->ws, &surface);
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								  0, 0, NULL, TRUE, &surface);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						struct pipe_resource *texture,
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						const struct pipe_surface *surf_tmpl)
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned level = surf_tmpl->u.tex.level;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (surface == NULL)
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX no offset */
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*	offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_reference_init(&surface->base.reference, 1);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&surface->base.texture, texture);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.context = pipe;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.format = surf_tmpl->format;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.width = rtex->surface.level[level].npix_x;
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.height = rtex->surface.level[level].npix_y;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.usage = surf_tmpl->usage;
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.texture = texture;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.u.tex.level = level;
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return &surface->base;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_surface_destroy(struct pipe_context *pipe,
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct pipe_surface *surface)
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&surface->texture, NULL);
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(surface);
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     const struct pipe_resource *templ,
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     struct winsys_handle *whandle)
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pb_buffer *buf = NULL;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned stride = 0;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned array_mode = 0;
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum radeon_bo_layout micro, macro;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface surface;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Support only 2D textures without mipmaps */
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      templ->depth0 != 1 || templ->last_level != 0)
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!buf)
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.bankw, &surface.bankh,
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.tile_split,
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.stencil_tile_split,
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.mtilea);
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (macro == RADEON_LAYOUT_TILED)
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = V_009910_ARRAY_2D_TILED_THIN1;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else if (micro == RADEON_LAYOUT_TILED)
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = V_009910_ARRAY_1D_TILED_THIN1;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = 0;
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_init_surface(&surface, templ, array_mode);
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								  stride, 0, buf, FALSE, &surface);
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint r600_texture_depth_flush(struct pipe_context *ctx,
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct pipe_resource *texture, boolean just_create)
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource resource;
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->flushed_depth_texture)
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out;
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.target = texture->target;
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.format = texture->format;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.width0 = texture->width0;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.height0 = texture->height0;
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.depth0 = texture->depth0;
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.array_size = texture->array_size;
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.last_level = texture->last_level;
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.nr_samples = texture->nr_samples;
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.usage = PIPE_USAGE_DYNAMIC;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL;
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource);
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->flushed_depth_texture == NULL) {
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		R600_ERR("failed to create temporary texture to hold untiled copy\n");
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return -ENOMEM;
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout:
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (just_create)
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return 0;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX: only do this if the depth texture has actually changed:
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	si_blit_uncompress_depth(ctx, rtex);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid si_init_surface_functions(struct r600_context *r600)
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600->context.create_surface = r600_create_surface;
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600->context.surface_destroy = r600_surface_destroy;
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
670