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
691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					unsigned level, unsigned layer)
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
729aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	return rtex->surface.level[level].offset +
739aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	       layer * rtex->surface.level[level].slice_size;
74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
7688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzerstatic int r600_init_surface(struct radeon_surface *surface,
7788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			     const struct pipe_resource *ptex,
7888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			     unsigned array_mode)
7988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer{
8088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->npix_x = ptex->width0;
8188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->npix_y = ptex->height0;
8288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->npix_z = ptex->depth0;
8388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->blk_w = util_format_get_blockwidth(ptex->format);
8488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->blk_h = util_format_get_blockheight(ptex->format);
8588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->blk_d = 1;
8688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->array_size = 1;
8788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->last_level = ptex->last_level;
8888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->bpe = util_format_get_blocksize(ptex->format);
8988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	/* align byte per element on dword */
9088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (surface->bpe == 3) {
9188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->bpe = 4;
9288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
9388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->nsamples = 1;
9488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	surface->flags = 0;
9588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	switch (array_mode) {
9688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case V_009910_ARRAY_1D_TILED_THIN1:
9788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
9888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
9988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case V_009910_ARRAY_2D_TILED_THIN1:
10088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
10188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
10288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case V_009910_ARRAY_LINEAR_ALIGNED:
10388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
10488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
10588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case V_009910_ARRAY_LINEAR_GENERAL:
10688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	default:
10788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
10888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
10988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
11088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	switch (ptex->target) {
11188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_1D:
11288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
11388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
11488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_RECT:
11588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_2D:
11688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
11788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
11888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_3D:
11988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
12088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
12188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_1D_ARRAY:
12288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
12388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->array_size = ptex->array_size;
12488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
12588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_2D_ARRAY:
12688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
12788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->array_size = ptex->array_size;
12888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
12988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_TEXTURE_CUBE:
13088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
13188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		break;
13288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	case PIPE_BUFFER:
13388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	default:
13488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return -EINVAL;
13588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
13688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (ptex->bind & PIPE_BIND_SCANOUT) {
13788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SCANOUT;
13888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
13988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (util_format_is_depth_and_stencil(ptex->format)) {
14088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_ZBUFFER;
14188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		surface->flags |= RADEON_SURF_SBUFFER;
14288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
14388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
14488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	return 0;
14588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer}
14688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
14788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzerstatic int r600_setup_surface(struct pipe_screen *screen,
14888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			      struct r600_resource_texture *rtex,
14988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			      unsigned array_mode,
15088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			      unsigned pitch_in_bytes_override)
15188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer{
15288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct r600_screen *rscreen = (struct r600_screen*)screen;
15388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	int r;
15488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
15588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (util_format_is_depth_or_stencil(rtex->real_format)) {
15688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		rtex->surface.flags |= RADEON_SURF_ZBUFFER;
15788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		rtex->surface.flags |= RADEON_SURF_SBUFFER;
15888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
15988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
16088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
16188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (r) {
16288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return r;
16388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
16488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
16588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		/* old ddx on evergreen over estimate alignment for 1d, only 1 level
16688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		 * for those
16788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		 */
16888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
16988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
17088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
17188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
17288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
17388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		}
17488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
17588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	return 0;
17688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer}
17788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Figure out whether u_blitter will fallback to a transfer operation.
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * If so, don't use a staging resource.
180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean permit_hardware_blit(struct pipe_screen *screen,
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					const struct pipe_resource *res)
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned bind;
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_depth_or_stencil(res->format))
187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		bind = PIPE_BIND_DEPTH_STENCIL;
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		bind = PIPE_BIND_RENDER_TARGET;
190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* hackaround for S3TC */
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_compressed(res->format))
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return TRUE;
19488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!screen->is_format_supported(screen,
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->format,
197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->target,
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->nr_samples,
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                                bind))
200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!screen->is_format_supported(screen,
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->format,
204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->target,
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				res->nr_samples,
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                                PIPE_BIND_SAMPLER_VIEW))
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (res->usage) {
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_USAGE_STREAM:
211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_USAGE_STAGING:
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return FALSE;
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return TRUE;
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					struct pipe_resource *ptex,
221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					struct winsys_handle *whandle)
222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
224fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König	struct si_resource *resource = &rtex->resource;
22588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct radeon_surface *surface = &rtex->surface;
226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
22888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rscreen->ws->buffer_set_tiling(resource->buf,
2297446a0407d4e61a826385c11ed6c401837baf095Michel Dänzer				       NULL,
23088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->level[0].mode >= RADEON_SURF_MODE_1D ?
23188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
23288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->level[0].mode >= RADEON_SURF_MODE_2D ?
23388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
23488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->bankw, surface->bankh,
23588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->tile_split,
23688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->stencil_tile_split,
23788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       surface->mtilea,
2389aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König				       surface->level[0].pitch_bytes);
23988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return rscreen->ws->buffer_get_handle(resource->buf,
2419aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König					      surface->level[0].pitch_bytes, whandle);
242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_texture_destroy(struct pipe_screen *screen,
245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 struct pipe_resource *ptex)
246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
248fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König	struct si_resource *resource = &rtex->resource;
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture)
2519aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		si_resource_reference((struct si_resource **)&rtex->flushed_depth_texture, NULL);
252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pb_reference(&resource->buf, NULL);
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	FREE(rtex);
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
2571b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer/* Needs adjustment for pixelformat:
2581b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer */
2591b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic INLINE unsigned u_box_volume( const struct pipe_box *box )
2601b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer{
2611b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	return box->width * box->depth * box->height;
2621b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer};
2631b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
2641b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic struct pipe_transfer* si_texture_get_transfer(struct pipe_context *ctx,
2651b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer						     struct pipe_resource *texture,
2661b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer						     unsigned level,
2671b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer						     unsigned usage,
2681b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer						     const struct pipe_box *box)
2691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer{
2701b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
2711b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct pipe_resource resource;
2721b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_transfer *trans;
2731b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	int r;
2741b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	boolean use_staging_texture = FALSE;
2751b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
2761b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	/* We cannot map a tiled texture directly because the data is
2771b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * in a different order, therefore we do detiling using a blit.
2781b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 *
2791b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * Also, use a temporary in GTT memory for read transfers, as
2801b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * the CPU is much happier reading out of cached system memory
2811b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * than uncached VRAM.
2821b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 */
2839aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	if (rtex->surface.level[level].mode != RADEON_SURF_MODE_LINEAR_ALIGNED &&
2849aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	    rtex->surface.level[level].mode != RADEON_SURF_MODE_LINEAR)
2851b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		use_staging_texture = TRUE;
2861b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
2871b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
2881b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		use_staging_texture = TRUE;
2891b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
2901b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	/* XXX: Use a staging texture for uploads if the underlying BO
2911b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * is busy.  No interface for checking that currently? so do
2921b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * it eagerly whenever the transfer doesn't require a readback
2931b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 * and might block.
2941b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	 */
2951b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if ((usage & PIPE_TRANSFER_WRITE) &&
2961b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			!(usage & (PIPE_TRANSFER_READ |
2971b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					PIPE_TRANSFER_DONTBLOCK |
2981b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					PIPE_TRANSFER_UNSYNCHRONIZED)))
2991b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		use_staging_texture = TRUE;
3001b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3011b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (!permit_hardware_blit(ctx->screen, texture) ||
3021b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		(texture->flags & R600_RESOURCE_FLAG_TRANSFER))
3031b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		use_staging_texture = FALSE;
3041b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3051b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
3061b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		return NULL;
3071b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3081b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	trans = CALLOC_STRUCT(r600_transfer);
3091b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (trans == NULL)
3101b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		return NULL;
3111b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	pipe_resource_reference(&trans->transfer.resource, texture);
3121b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	trans->transfer.level = level;
3131b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	trans->transfer.usage = usage;
3141b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	trans->transfer.box = *box;
3151b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (rtex->depth) {
3161b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		/* XXX: only readback the rectangle which is being mapped?
3171b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		*/
3181b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		/* XXX: when discard is true, no need to read back from depth texture
3191b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		*/
3201b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		r = r600_texture_depth_flush(ctx, texture, FALSE);
3211b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (r < 0) {
3221b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			R600_ERR("failed to create temporary texture to hold untiled copy\n");
3231b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			pipe_resource_reference(&trans->transfer.resource, NULL);
3241b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			FREE(trans);
3251b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			return NULL;
3261b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3279aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		trans->transfer.stride = rtex->flushed_depth_texture->surface.level[level].pitch_bytes;
3281b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
3291b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		return &trans->transfer;
3301b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	} else if (use_staging_texture) {
3311b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.target = PIPE_TEXTURE_2D;
3321b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.format = texture->format;
3331b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.width0 = box->width;
3341b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.height0 = box->height;
3351b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.depth0 = 1;
3361b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.array_size = 1;
3371b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.last_level = 0;
3381b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.nr_samples = 0;
3391b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.usage = PIPE_USAGE_STAGING;
3401b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.bind = 0;
3411b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
3421b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		/* For texture reading, the temporary (detiled) texture is used as
3431b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		 * a render target when blitting from a tiled texture. */
3441b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (usage & PIPE_TRANSFER_READ) {
3451b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			resource.bind |= PIPE_BIND_RENDER_TARGET;
3461b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3471b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		/* For texture writing, the temporary texture is used as a sampler
3481b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		 * when blitting into a tiled texture. */
3491b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (usage & PIPE_TRANSFER_WRITE) {
3501b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
3511b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3521b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		/* Create the temporary texture. */
3531b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
3541b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (trans->staging_texture == NULL) {
3551b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			R600_ERR("failed to create temporary texture to hold untiled copy\n");
3561b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			pipe_resource_reference(&trans->transfer.resource, NULL);
3571b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			FREE(trans);
3581b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			return NULL;
3591b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3601b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3619aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		trans->transfer.stride = ((struct r600_resource_texture *)trans->staging_texture)
3629aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König					->surface.level[0].pitch_bytes;
3631b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (usage & PIPE_TRANSFER_READ) {
3641b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			r600_copy_to_staging_texture(ctx, trans);
3651b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			/* Always referenced in the blit. */
3661b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			radeonsi_flush(ctx, NULL, 0);
3671b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3681b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		return &trans->transfer;
3691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
3709aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
3719aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
3721b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	trans->offset = r600_texture_get_offset(rtex, level, box->z);
3731b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	return &trans->transfer;
3741b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer}
3751b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3761b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic void si_texture_transfer_destroy(struct pipe_context *ctx,
3771b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					struct pipe_transfer *transfer)
3781b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer{
3791b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
3801b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct pipe_resource *texture = transfer->resource;
3811b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
3821b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3831b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (rtransfer->staging_texture) {
3841b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (transfer->usage & PIPE_TRANSFER_WRITE) {
3851b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			r600_copy_from_staging_texture(ctx, rtransfer);
3861b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
3871b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		pipe_resource_reference(&rtransfer->staging_texture, NULL);
3881b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
3891b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3901b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (rtex->depth && !rtex->is_flushing_texture) {
3911b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
3921b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			r600_blit_push_depth(ctx, rtex);
3931b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
3941b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3951b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	pipe_resource_reference(&transfer->resource, NULL);
3961b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	FREE(transfer);
3971b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer}
3981b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
3991b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic void* si_texture_transfer_map(struct pipe_context *ctx,
4001b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer				     struct pipe_transfer* transfer)
4011b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer{
4021b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_context *rctx = (struct r600_context *)ctx;
4031b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
4041b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct radeon_winsys_cs_handle *buf;
4051b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	enum pipe_format format = transfer->resource->format;
4061b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	unsigned offset = 0;
4071b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	char *map;
4081b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4091b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (rtransfer->staging_texture) {
4101b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		buf = si_resource(rtransfer->staging_texture)->cs_buf;
4111b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	} else {
4121b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
4131b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4141b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (rtex->flushed_depth_texture)
4159aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König			buf = rtex->flushed_depth_texture->resource.cs_buf;
4161b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		else
4171b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			buf = si_resource(transfer->resource)->cs_buf;
4181b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4191b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		offset = rtransfer->offset +
4201b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
4211b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
4221b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
4231b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4241b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
4251b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		return NULL;
4261b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
4271b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4281b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	return map + offset;
4291b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer}
4301b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4311b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstatic void si_texture_transfer_unmap(struct pipe_context *ctx,
4321b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer				      struct pipe_transfer* transfer)
4331b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer{
4341b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
4351b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct r600_context *rctx = (struct r600_context*)ctx;
4361b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	struct radeon_winsys_cs_handle *buf;
4371b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4381b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	if (rtransfer->staging_texture) {
4391b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		buf = si_resource(rtransfer->staging_texture)->cs_buf;
4401b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	} else {
4411b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
4421b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
4431b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		if (rtex->flushed_depth_texture) {
4449aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König			buf = rtex->flushed_depth_texture->resource.cs_buf;
4451b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		} else {
4461b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer			buf = si_resource(transfer->resource)->cs_buf;
4471b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		}
4481b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	}
4491b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	rctx->ws->buffer_unmap(buf);
4501b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer}
4511b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer
452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic const struct u_resource_vtbl r600_texture_vtbl =
453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_get_handle,	/* get_handle */
455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_texture_destroy,		/* resource_destroy */
4561b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	si_texture_get_transfer,	/* get_transfer */
4571b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	si_texture_transfer_destroy,	/* transfer_destroy */
4581b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	si_texture_transfer_map,	/* transfer_map */
459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	u_default_transfer_flush_region,/* transfer_flush_region */
4601b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	si_texture_transfer_unmap,	/* transfer_unmap */
4612ed1cdb2a56257c97f8f64cdefd5f28fb64773b8Marek Olšák	NULL	/* transfer_inline_write */
462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct r600_resource_texture *
465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardr600_texture_create_object(struct pipe_screen *screen,
466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   const struct pipe_resource *base,
467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned array_mode,
468a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned pitch_in_bytes_override,
469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   unsigned max_buffer_size,
470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   struct pb_buffer *buf,
47188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			   boolean alloc_bo,
47288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			   struct radeon_surface *surface)
473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex;
475fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König	struct si_resource *resource;
476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
47788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	int r;
478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex = CALLOC_STRUCT(r600_resource_texture);
480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex == NULL)
481a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
482a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
483a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource = &rtex->resource;
4842a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.b = *base;
4852a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.vtbl = &r600_texture_vtbl;
4862a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	pipe_reference_init(&resource->b.b.reference, 1);
4872a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	resource->b.b.screen = screen;
488a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->pitch_override = pitch_in_bytes_override;
489a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->real_format = base->format;
490a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* only mark depth textures the HW can hit as depth textures */
492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rtex->depth = 1;
494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
49588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface = *surface;
49688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
49788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (r) {
49888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		FREE(rtex);
49988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return NULL;
50088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Now create the backing buffer. */
503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!buf && alloc_bo) {
5049aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		unsigned base_align = rtex->surface.bo_alignment;
5059aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		unsigned size = rtex->surface.bo_size;
506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
50788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		base_align = rtex->surface.bo_alignment;
5089aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König		if (!si_init_resource(rscreen, resource, size, base_align, base->bind, base->usage)) {
509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			FREE(rtex);
510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return NULL;
511a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else if (buf) {
513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->buf = buf;
514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return rtex;
519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
520a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
5211b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstruct pipe_resource *si_texture_create(struct pipe_screen *screen,
5221b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					const struct pipe_resource *templ)
523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
524a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
52588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct radeon_surface surface;
526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned array_mode = 0;
52788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	int r;
528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
5299b7dc5e81cfebeb6a61f3fee704bfec3fa6d6e77Christian König#if 0
530a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	    !(templ->bind & PIPE_BIND_SCANOUT)) {
53288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		if (permit_hardware_blit(screen, templ)) {
53388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer			array_mode = V_009910_ARRAY_2D_TILED_THIN1;
534a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
535a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
5369b7dc5e81cfebeb6a61f3fee704bfec3fa6d6e77Christian König#endif
537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
53888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	r = r600_init_surface(&surface, templ, array_mode);
53988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (r) {
54088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return NULL;
54188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
54288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	r = rscreen->ws->surface_best(rscreen->ws, &surface);
54388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (r) {
54488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return NULL;
54588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
546a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
54788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer								  0, 0, NULL, TRUE, &surface);
548a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
549a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
550a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
551a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						struct pipe_resource *texture,
552a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						const struct pipe_surface *surf_tmpl)
553a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
554a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
555a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
556a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned level = surf_tmpl->u.tex.level;
557a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
558a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
559a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (surface == NULL)
560a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
561a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX no offset */
562a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/*	offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
563a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_reference_init(&surface->base.reference, 1);
564a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&surface->base.texture, texture);
565a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.context = pipe;
566a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.format = surf_tmpl->format;
5679aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	surface->base.width = rtex->surface.level[level].npix_x;
5689aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König	surface->base.height = rtex->surface.level[level].npix_y;
569a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.usage = surf_tmpl->usage;
570a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.texture = texture;
571a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
572a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
573a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	surface->base.u.tex.level = level;
574a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
575a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return &surface->base;
576a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
577a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
578a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_surface_destroy(struct pipe_context *pipe,
579a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 struct pipe_surface *surface)
580a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
581a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	pipe_resource_reference(&surface->texture, NULL);
582a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	FREE(surface);
583a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
584a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
5851b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerstruct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
5861b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					     const struct pipe_resource *templ,
5871b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer					     struct winsys_handle *whandle)
588a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
589a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_screen *rscreen = (struct r600_screen*)screen;
590a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pb_buffer *buf = NULL;
591a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned stride = 0;
592a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned array_mode = 0;
593a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum radeon_bo_layout micro, macro;
59488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct radeon_surface surface;
59588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	int r;
596a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
597a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Support only 2D textures without mipmaps */
598a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
599a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	      templ->depth0 != 1 || templ->last_level != 0)
600a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
601a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
602a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
603a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!buf)
604a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return NULL;
605a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
60688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
60788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       &surface.bankw, &surface.bankh,
60888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       &surface.tile_split,
60988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       &surface.stencil_tile_split,
61088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer				       &surface.mtilea);
611a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
612a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (macro == RADEON_LAYOUT_TILED)
61388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		array_mode = V_009910_ARRAY_2D_TILED_THIN1;
614a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else if (micro == RADEON_LAYOUT_TILED)
61588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		array_mode = V_009910_ARRAY_1D_TILED_THIN1;
616a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else
617a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		array_mode = 0;
618a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
61988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	r = r600_init_surface(&surface, templ, array_mode);
62088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	if (r) {
62188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		return NULL;
62288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	}
623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
62488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer								  stride, 0, buf, FALSE, &surface);
625a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
626a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
627a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardint r600_texture_depth_flush(struct pipe_context *ctx,
628a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			     struct pipe_resource *texture, boolean just_create)
629a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
630a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_resource resource;
632a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
633a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture)
634a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		goto out;
635a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
636a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.target = texture->target;
637a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.format = texture->format;
638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.width0 = texture->width0;
639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.height0 = texture->height0;
640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.depth0 = texture->depth0;
641a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.array_size = texture->array_size;
642a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.last_level = texture->last_level;
643a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.nr_samples = texture->nr_samples;
644a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.usage = PIPE_USAGE_DYNAMIC;
645a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL;
646a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags;
647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource);
649a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rtex->flushed_depth_texture == NULL) {
650a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		R600_ERR("failed to create temporary texture to hold untiled copy\n");
651a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return -ENOMEM;
652a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
653a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
654a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE;
655a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardout:
656a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (just_create)
657a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return 0;
658a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
659a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: only do this if the depth texture has actually changed:
660a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
6611b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer	si_blit_uncompress_depth(ctx, rtex);
662a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return 0;
663a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
664a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
6651b11395a36a44a902cfb3e1783758544662df73fMichel Dänzervoid si_init_surface_functions(struct r600_context *r600)
666a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
667a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600->context.create_surface = r600_create_surface;
668a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600->context.surface_destroy = r600_surface_destroy;
669a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
670