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 "r600_formats.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r600d.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format_s3tc.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Copy from a full GPU texture to a transfer's staging one. */
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->resource_copy_region(ctx, &rtransfer->staging->b.b,
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				0, 0, 0, 0, texture, transfer->level,
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				&transfer->box);
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Copy from a transfer's staging texture to a full GPU one. */
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_box sbox;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	u_box_origin_2d(transfer->box.width, transfer->box.height, &sbox);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->resource_copy_region(ctx, texture, transfer->level,
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  transfer->box.x, transfer->box.y, transfer->box.z,
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  &rtransfer->staging->b.b,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  0, &sbox);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned r600_texture_get_offset(struct r600_texture *rtex,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					unsigned level, unsigned layer)
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rtex->surface.level[level].offset +
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       layer * rtex->surface.level[level].slice_size;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int r600_init_surface(struct r600_screen *rscreen,
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct radeon_surface *surface,
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     const struct pipe_resource *ptex,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     unsigned array_mode,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     bool is_transfer, bool is_flushed_depth)
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct util_format_description *desc =
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		util_format_description(ptex->format);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool is_depth, is_stencil;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	is_depth = util_format_has_depth(desc);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	is_stencil = util_format_has_stencil(desc);
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_x = ptex->width0;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_y = ptex->height0;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->npix_z = ptex->depth0;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_w = util_format_get_blockwidth(ptex->format);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_h = util_format_get_blockheight(ptex->format);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->blk_d = 1;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->array_size = 1;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->last_level = ptex->last_level;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rscreen->chip_class >= EVERGREEN &&
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    !is_transfer && !is_flushed_depth &&
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->bpe = 4; /* stencil is allocated separately on evergreen */
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->bpe = util_format_get_blocksize(ptex->format);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* align byte per element on dword */
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (surface->bpe == 3) {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			surface->bpe = 4;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->flags = 0;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (array_mode) {
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_038000_ARRAY_1D_TILED_THIN1:
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_038000_ARRAY_2D_TILED_THIN1:
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_038000_ARRAY_LINEAR_ALIGNED:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case V_038000_ARRAY_LINEAR_GENERAL:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (ptex->target) {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_1D:
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_RECT:
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_2D:
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_3D:
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_1D_ARRAY:
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->array_size = ptex->array_size;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_2D_ARRAY:
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->array_size = ptex->array_size;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_TEXTURE_CUBE:
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case PIPE_BUFFER:
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return -EINVAL;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ptex->bind & PIPE_BIND_SCANOUT) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_SCANOUT;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!is_transfer && !is_flushed_depth && is_depth) {
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		surface->flags |= RADEON_SURF_ZBUFFER;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (is_stencil) {
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			surface->flags |= RADEON_SURF_SBUFFER;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int r600_setup_surface(struct pipe_screen *screen,
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct r600_texture *rtex,
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      unsigned pitch_in_bytes_override)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *ptex = &rtex->resource.b.b;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return r;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->size = rtex->surface.bo_size;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* old ddx on evergreen over estimate alignment for 1d, only 1 level
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * for those
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 */
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i <= ptex->last_level; i++) {
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (rtex->surface.level[i].mode) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case RADEON_SURF_MODE_LINEAR_ALIGNED:
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case RADEON_SURF_MODE_1D:
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case RADEON_SURF_MODE_2D:
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case RADEON_SURF_MODE_LINEAR:
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rtex->array_mode[i] = 0;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct pipe_resource *ptex,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct winsys_handle *whandle)
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)ptex;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource *resource = &rtex->resource;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface *surface = &rtex->surface;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rscreen->ws->buffer_set_tiling(resource->buf,
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       NULL,
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->level[0].mode >= RADEON_SURF_MODE_1D ?
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->level[0].mode >= RADEON_SURF_MODE_2D ?
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->bankw, surface->bankh,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->tile_split,
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->stencil_tile_split,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       surface->mtilea,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       rtex->surface.level[0].pitch_bytes);
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rscreen->ws->buffer_get_handle(resource->buf,
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      rtex->surface.level[0].pitch_bytes, whandle);
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_texture_destroy(struct pipe_screen *screen,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct pipe_resource *ptex)
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)ptex;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource *resource = &rtex->resource;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->flushed_depth_texture)
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pb_reference(&resource->buf, NULL);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(rtex);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct u_resource_vtbl r600_texture_vtbl =
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_get_handle,	/* get_handle */
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_destroy,		/* resource_destroy */
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_get_transfer,	/* get_transfer */
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_transfer_destroy,	/* transfer_destroy */
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_transfer_map,	/* transfer_map */
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	NULL,				/* transfer_flush_region */
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_transfer_unmap,	/* transfer_unmap */
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	NULL				/* transfer_inline_write */
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* The number of samples can be specified independently of the texture. */
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_texture_get_fmask_info(struct r600_screen *rscreen,
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct r600_texture *rtex,
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 unsigned nr_samples,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct r600_fmask_info *out)
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* FMASK is allocated pretty much like an ordinary texture.
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Here we use bpe in the units of bits, not bytes. */
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface fmask = rtex->surface;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (nr_samples) {
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case 2:
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* This should be 8,1, but we should set nsamples > 1
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * for the allocator to treat it as a multisample surface.
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * Let's set 4,2 then. */
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case 4:
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.bpe = 4;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.nsamples = 2;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case 8:
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.bpe = 8;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.nsamples = 4;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case 16:
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.bpe = 16;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.nsamples = 4;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		R600_ERR("Invalid sample count for FMASK allocation.\n");
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* R600-R700 errata? Anyway, this fixes colorbuffer corruption. */
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rscreen->chip_class <= R700) {
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.bpe *= 2;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rscreen->chip_class >= EVERGREEN) {
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fmask.bankh = nr_samples <= 4 ? 4 : 1;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rscreen->ws->surface_init(rscreen->ws, &fmask)) {
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		R600_ERR("Got error in surface_init while allocating FMASK.\n");
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->bank_height = fmask.bankh;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->alignment = MAX2(256, fmask.bo_alignment);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->size = (fmask.bo_size + 7) / 8;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_texture_allocate_fmask(struct r600_screen *rscreen,
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct r600_texture *rtex)
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_fmask_info fmask;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_get_fmask_info(rscreen, rtex,
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    rtex->resource.b.b.nr_samples, &fmask);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Reserve space for FMASK while converting bits back to bytes. */
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->fmask_bank_height = fmask.bank_height;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->fmask_offset = align(rtex->size, fmask.alignment);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->fmask_size = fmask.size;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->size = rtex->fmask_offset + rtex->fmask_size;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	printf("FMASK width=%u, height=%i, bits=%u, size=%u\n",
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       fmask.npix_x, fmask.npix_y, fmask.bpe * fmask.nsamples, rtex->fmask_size);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_texture_get_cmask_info(struct r600_screen *rscreen,
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct r600_texture *rtex,
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct r600_cmask_info *out)
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned cmask_tile_width = 8;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned cmask_tile_height = 8;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned cmask_tile_elements = cmask_tile_width * cmask_tile_height;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned element_bits = 4;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned cmask_cache_bits = 1024;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_pipes = rscreen->tiling_info.num_channels;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned elements_per_macro_tile = (cmask_cache_bits / element_bits) * num_pipes;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned pixels_per_macro_tile = elements_per_macro_tile * cmask_tile_elements;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned sqrt_pixels_per_macro_tile = sqrt(pixels_per_macro_tile);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned macro_tile_width = util_next_power_of_two(sqrt_pixels_per_macro_tile);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned macro_tile_height = pixels_per_macro_tile / macro_tile_width;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned pitch_elements = align(rtex->surface.npix_x, macro_tile_width);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned height = align(rtex->surface.npix_y, macro_tile_height);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned base_align = num_pipes * pipe_interleave_bytes;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned slice_bytes =
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		((pitch_elements * height * element_bits + 7) / 8) / cmask_tile_elements;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(macro_tile_width % 128 == 0);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(macro_tile_height % 128 == 0);
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->alignment = MAX2(256, base_align);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	out->size = rtex->surface.array_size * align(slice_bytes, base_align);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_texture_allocate_cmask(struct r600_screen *rscreen,
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					struct r600_texture *rtex)
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_cmask_info cmask;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600_texture_get_cmask_info(rscreen, rtex, &cmask);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->cmask_slice_tile_max = cmask.slice_tile_max;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->cmask_offset = align(rtex->size, cmask.alignment);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->cmask_size = cmask.size;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->size = rtex->cmask_offset + rtex->cmask_size;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	printf("CMASK: macro tile width = %u, macro tile height = %u, "
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       "pitch elements = %u, height = %u, slice tile max = %u\n",
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       macro_tile_width, macro_tile_height, pitch_elements, height,
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       rtex->cmask_slice_tile_max);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct r600_texture *
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgr600_texture_create_object(struct pipe_screen *screen,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   const struct pipe_resource *base,
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   unsigned pitch_in_bytes_override,
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   struct pb_buffer *buf,
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   boolean alloc_bo,
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   struct radeon_surface *surface)
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_resource *resource;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex = CALLOC_STRUCT(r600_texture);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex == NULL)
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource = &rtex->resource;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.b = *base;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.vtbl = &r600_texture_vtbl;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_reference_init(&resource->b.b.reference, 1);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource->b.b.screen = screen;
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->pitch_override = pitch_in_bytes_override;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* don't include stencil-only formats which we don't support for rendering */
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rtex->surface = *surface;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_setup_surface(screen, rtex,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       pitch_in_bytes_override);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		FREE(rtex);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (base->nr_samples > 1 && !rtex->is_depth && alloc_bo) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_texture_allocate_cmask(rscreen, rtex);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_texture_allocate_fmask(rscreen, rtex);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!rtex->is_depth && base->nr_samples > 1 &&
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (!rtex->fmask_size || !rtex->cmask_size)) {
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		FREE(rtex);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Now create the backing buffer. */
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!buf && alloc_bo) {
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned base_align = rtex->surface.bo_alignment;
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned usage = R600_TEX_IS_TILED(rtex, 0) ? PIPE_USAGE_STATIC : base->usage;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, usage)) {
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(rtex);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (buf) {
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->buf = buf;
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->cmask_size) {
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Initialize the cmask to 0xCC (= compressed state). */
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		char *ptr = rscreen->ws->buffer_map(resource->cs_buf, NULL, PIPE_TRANSFER_WRITE);
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(ptr + rtex->cmask_offset, 0xCC, rtex->cmask_size);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rscreen->ws->buffer_unmap(resource->cs_buf);
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return rtex;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource *r600_texture_create(struct pipe_screen *screen,
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						const struct pipe_resource *templ)
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface surface;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned array_mode = 0;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER)) {
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else if (!(templ->bind & PIPE_BIND_SCANOUT) &&
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    templ->usage != PIPE_USAGE_STAGING &&
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    templ->usage != PIPE_USAGE_STREAM) {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else if (util_format_is_compressed(templ->format)) {
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			array_mode = V_038000_ARRAY_1D_TILED_THIN1;
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX tiling is broken for the 422 formats */
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (util_format_description(templ->format)->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_init_surface(rscreen, &surface, templ, array_mode,
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      templ->flags & R600_RESOURCE_FLAG_TRANSFER,
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = rscreen->ws->surface_best(rscreen->ws, &surface);
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (struct pipe_resource *)r600_texture_create_object(screen, templ,
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								  0, NULL, TRUE, &surface);
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						struct pipe_resource *texture,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						const struct pipe_surface *templ)
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)texture;
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned level = templ->u.tex.level;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	assert(templ->u.tex.first_layer == templ->u.tex.last_layer);
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (surface == NULL)
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_reference_init(&surface->base.reference, 1);
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&surface->base.texture, texture);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.context = pipe;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.format = templ->format;
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.width = rtex->surface.level[level].npix_x;
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.height = rtex->surface.level[level].npix_y;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.usage = templ->usage;
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	surface->base.u = templ->u;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return &surface->base;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void r600_surface_destroy(struct pipe_context *pipe,
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct pipe_surface *surface)
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_surface *surf = (struct r600_surface*)surface;
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL);
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&surface->texture, NULL);
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(surface);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       const struct pipe_resource *templ,
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct winsys_handle *whandle)
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_screen *rscreen = (struct r600_screen*)screen;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pb_buffer *buf = NULL;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned stride = 0;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned array_mode = 0;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum radeon_bo_layout micro, macro;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_surface surface;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int r;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Support only 2D textures without mipmaps */
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      templ->depth0 != 1 || templ->last_level != 0)
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!buf)
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.bankw, &surface.bankh,
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.tile_split,
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.stencil_tile_split,
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       &surface.mtilea);
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (macro == RADEON_LAYOUT_TILED)
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else if (micro == RADEON_LAYOUT_TILED)
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		array_mode = 0;
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r = r600_init_surface(rscreen, &surface, templ, array_mode, false, false);
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r) {
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return (struct pipe_resource *)r600_texture_create_object(screen, templ,
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								  stride, buf, FALSE, &surface);
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool r600_init_flushed_depth_texture(struct pipe_context *ctx,
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     struct pipe_resource *texture,
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     struct r600_texture **staging)
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)texture;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource resource;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture **flushed_depth_texture = staging ?
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			staging : &rtex->flushed_depth_texture;
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!staging && rtex->flushed_depth_texture)
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return true; /* it's ready */
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.target = texture->target;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.format = texture->format;
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.width0 = texture->width0;
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.height0 = texture->height0;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.depth0 = texture->depth0;
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.array_size = texture->array_size;
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.last_level = texture->last_level;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.nr_samples = texture->nr_samples;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.usage = staging ? PIPE_USAGE_STAGING : PIPE_USAGE_STATIC;
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.bind = texture->bind & ~PIPE_BIND_DEPTH_STENCIL;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	resource.flags = texture->flags | R600_RESOURCE_FLAG_FLUSHED_DEPTH;
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (staging)
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.flags |= R600_RESOURCE_FLAG_TRANSFER;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*flushed_depth_texture = (struct r600_texture *)ctx->screen->resource_create(ctx->screen, &resource);
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (*flushed_depth_texture == NULL) {
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		R600_ERR("failed to create temporary texture to hold flushed depth\n");
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return false;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	(*flushed_depth_texture)->is_flushing_texture = TRUE;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return true;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						struct pipe_resource *texture,
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						unsigned level,
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						unsigned usage,
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						const struct pipe_box *box)
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context*)ctx;
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)texture;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource resource;
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *trans;
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean use_staging_texture = FALSE;
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* We cannot map a tiled texture directly because the data is
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * in a different order, therefore we do detiling using a blit.
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Also, use a temporary in GTT memory for read transfers, as
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * the CPU is much happier reading out of cached system memory
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * than uncached VRAM.
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (R600_TEX_IS_TILED(rtex, level)) {
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = TRUE;
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Use a staging texture for uploads if the underlying BO is busy. */
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(usage & PIPE_TRANSFER_READ) &&
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (rctx->ws->cs_is_buffer_referenced(rctx->cs, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) {
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = TRUE;
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (texture->flags & R600_RESOURCE_FLAG_TRANSFER) {
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		use_staging_texture = FALSE;
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans = CALLOC_STRUCT(r600_transfer);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (trans == NULL)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&trans->transfer.resource, texture);
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.level = level;
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.usage = usage;
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.box = *box;
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->is_depth) {
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* XXX: only readback the rectangle which is being mapped?
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*/
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* XXX: when discard is true, no need to read back from depth texture
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*/
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct r600_texture *staging_depth;
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			R600_ERR("failed to create temporary texture to hold untiled copy\n");
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe_resource_reference(&trans->transfer.resource, NULL);
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(trans);
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		r600_blit_decompress_depth(ctx, rtex, staging_depth,
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   level, level,
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   box->z, box->z + box->depth - 1,
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   0, 0);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes;
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->offset = r600_texture_get_offset(staging_depth, level, box->z);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->staging = (struct r600_resource*)staging_depth;
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return &trans->transfer;
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (use_staging_texture) {
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.target = PIPE_TEXTURE_2D;
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.format = texture->format;
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.width0 = box->width;
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.height0 = box->height;
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.depth0 = 1;
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.array_size = 1;
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.last_level = 0;
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.nr_samples = 0;
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.usage = PIPE_USAGE_STAGING;
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.bind = 0;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* For texture reading, the temporary (detiled) texture is used as
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * a render target when blitting from a tiled texture. */
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_READ) {
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource.bind |= PIPE_BIND_RENDER_TARGET;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* For texture writing, the temporary texture is used as a sampler
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * when blitting into a tiled texture. */
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_WRITE) {
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Create the temporary texture. */
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->staging = (struct r600_resource*)ctx->screen->resource_create(ctx->screen, &resource);
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (trans->staging == NULL) {
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			R600_ERR("failed to create temporary texture to hold untiled copy\n");
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe_resource_reference(&trans->transfer.resource, NULL);
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			FREE(trans);
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return NULL;
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		trans->transfer.stride =
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			((struct r600_texture *)trans->staging)->surface.level[0].pitch_bytes;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (usage & PIPE_TRANSFER_READ) {
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_copy_to_staging_texture(ctx, trans);
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* Always referenced in the blit. */
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_flush(ctx, NULL, 0);
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return &trans->transfer;
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	trans->offset = r600_texture_get_offset(rtex, level, box->z);
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return &trans->transfer;
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_texture_transfer_destroy(struct pipe_context *ctx,
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   struct pipe_transfer *transfer)
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_resource *texture = transfer->resource;
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex = (struct r600_texture*)texture;
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) {
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rtex->is_depth) {
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->resource_copy_region(ctx, texture, transfer->level,
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  transfer->box.x, transfer->box.y, transfer->box.z,
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  &rtransfer->staging->b.b, transfer->level,
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  &transfer->box);
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else {
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_copy_from_staging_texture(ctx, rtransfer);
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging)
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_resource_reference(&transfer->resource, NULL);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FREE(transfer);
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid* r600_texture_transfer_map(struct pipe_context *ctx,
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct pipe_transfer* transfer)
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context *)ctx;
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs_handle *buf;
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_texture *rtex =
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			(struct r600_texture*)transfer->resource;
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum pipe_format format = transfer->resource->format;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned offset = 0;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	char *map;
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) {
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return r600_compute_global_transfer_map(ctx, transfer);
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging) {
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = ((struct r600_resource *)transfer->resource)->cs_buf;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtex->is_depth || !rtransfer->staging)
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		offset = rtransfer->offset +
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return NULL;
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return map + offset;
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_texture_transfer_unmap(struct pipe_context *ctx,
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct pipe_transfer* transfer)
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct r600_context *rctx = (struct r600_context*)ctx;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_winsys_cs_handle *buf;
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) {
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return r600_compute_global_transfer_unmap(ctx, transfer);
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (rtransfer->staging) {
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		buf = ((struct r600_resource *)transfer->resource)->cs_buf;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rctx->ws->buffer_unmap(buf);
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r600_init_surface_functions(struct r600_context *r600)
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600->context.create_surface = r600_create_surface;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	r600->context.surface_destroy = r600_surface_destroy;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned char *swizzle_view)
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned char swizzle[4];
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned result = 0;
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const uint32_t swizzle_shift[4] = {
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		16, 19, 22, 25,
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const uint32_t swizzle_bit[4] = {
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		0, 1, 2, 3,
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swizzle_view) {
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memcpy(swizzle, swizzle_format, 4);
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Get swizzle. */
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < 4; i++) {
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (swizzle[i]) {
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case UTIL_FORMAT_SWIZZLE_Y:
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= swizzle_bit[1] << swizzle_shift[i];
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case UTIL_FORMAT_SWIZZLE_Z:
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= swizzle_bit[2] << swizzle_shift[i];
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case UTIL_FORMAT_SWIZZLE_W:
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= swizzle_bit[3] << swizzle_shift[i];
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case UTIL_FORMAT_SWIZZLE_0:
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case UTIL_FORMAT_SWIZZLE_1:
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default: /* UTIL_FORMAT_SWIZZLE_X */
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result |= swizzle_bit[0] << swizzle_shift[i];
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return result;
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* texture format translate */
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguint32_t r600_translate_texformat(struct pipe_screen *screen,
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  enum pipe_format format,
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  const unsigned char *swizzle_view,
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  uint32_t *word4_p, uint32_t *yuv_format_p)
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint32_t result = 0, word4 = 0, yuv_format = 0;
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct util_format_description *desc;
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean uniform = TRUE;
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static int r600_enable_s3tc = -1;
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool is_srgb_valid = FALSE;
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int i;
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const uint32_t sign_bit[4] = {
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	desc = util_format_description(format);
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Colorspace (return non-RGB formats directly). */
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (desc->colorspace) {
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* Depth stencil formats */
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_COLORSPACE_ZS:
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (format) {
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_Z16_UNORM:
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_16;
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_X24S8_UINT:
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_Z24X8_UNORM:
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_Z24_UNORM_S8_UINT:
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_8_24;
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_S8X24_UINT:
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_X8Z24_UNORM:
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_S8_UINT_Z24_UNORM:
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_24_8;
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_S8_UINT:
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_8;
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_Z32_FLOAT:
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_32_FLOAT;
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_X32_S8X24_UINT:
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_X24_8_32_FLOAT;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_COLORSPACE_YUV:
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		yuv_format |= (1 << 30);
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (format) {
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_UYVY:
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_YUYV:
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_unknown; /* XXX */
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_COLORSPACE_SRGB:
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		word4 |= S_038010_FORCE_DEGAMMA(1);
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (r600_enable_s3tc == -1) {
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct r600_screen *rscreen = (struct r600_screen *)screen;
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (rscreen->info.drm_minor >= 9)
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_enable_s3tc = 1;
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			r600_enable_s3tc = debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!r600_enable_s3tc)
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (format) {
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_RGTC1_SNORM:
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_LATC1_SNORM:
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= sign_bit[0];
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_RGTC1_UNORM:
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_LATC1_UNORM:
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BC4;
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_RGTC2_SNORM:
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_LATC2_SNORM:
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= sign_bit[0] | sign_bit[1];
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_RGTC2_UNORM:
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_LATC2_UNORM:
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BC5;
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!r600_enable_s3tc)
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!util_format_s3tc_enabled) {
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (format) {
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT1_RGB:
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT1_RGBA:
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT1_SRGB:
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT1_SRGBA:
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BC1;
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			is_srgb_valid = TRUE;
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT3_RGBA:
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT3_SRGBA:
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BC2;
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			is_srgb_valid = TRUE;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT5_RGBA:
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_DXT5_SRGBA:
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BC3;
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			is_srgb_valid = TRUE;
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (format) {
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_R8G8_B8G8_UNORM:
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_G8R8_B8R8_UNORM:
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_GB_GR;
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_G8R8_G8B8_UNORM:
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case PIPE_FORMAT_R8G8_R8B8_UNORM:
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			result = FMT_BG_RG;
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_word4;
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		result = FMT_5_9_9_9_SHAREDEXP;
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_word4;
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		result = FMT_10_11_11_FLOAT;
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_word4;
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < desc->nr_channels; i++) {
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= sign_bit[i];
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* R8G8Bx_SNORM - XXX CxV8U8 */
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* See whether the components are of the same size. */
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 1; i < desc->nr_channels; i++) {
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		uniform = uniform && desc->channel[0].size == desc->channel[i].size;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Non-uniform formats. */
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!uniform) {
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    desc->channel[0].pure_integer)
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch(desc->nr_channels) {
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 3:
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (desc->channel[0].size == 5 &&
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[1].size == 6 &&
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[2].size == 5) {
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_5_6_5;
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 4:
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (desc->channel[0].size == 5 &&
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[1].size == 5 &&
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[2].size == 5 &&
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[3].size == 1) {
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_1_5_5_5;
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (desc->channel[0].size == 10 &&
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[1].size == 10 &&
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[2].size == 10 &&
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    desc->channel[3].size == 2) {
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_2_10_10_10;
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_unknown;
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Find the first non-VOID channel. */
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < 4; i++) {
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (i == 4)
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_unknown;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* uniform formats */
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (desc->channel[i].type) {
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_TYPE_UNSIGNED:
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_TYPE_SIGNED:
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!desc->channel[i].normalized &&
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    desc->channel[i].pure_integer)
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (desc->channel[i].size) {
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 4:
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_4_4;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_4_4_4_4;
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 8:
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 1:
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_8;
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_8_8;
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_8_8_8_8;
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				is_srgb_valid = TRUE;
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 16:
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 1:
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16;
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16_16;
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16_16_16_16;
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 32:
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 1:
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32_32;
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32_32_32_32;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_unknown;
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case UTIL_FORMAT_TYPE_FLOAT:
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (desc->channel[i].size) {
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 16:
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 1:
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16_FLOAT;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16_16_FLOAT;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_16_16_16_16_FLOAT;
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			goto out_unknown;
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 32:
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch (desc->nr_channels) {
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 1:
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32_FLOAT;
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 2:
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32_32_FLOAT;
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case 4:
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				result = FMT_32_32_32_32_FLOAT;
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				goto out_word4;
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		goto out_unknown;
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout_word4:
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid)
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return ~0;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (word4_p)
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*word4_p = word4;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (yuv_format_p)
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*yuv_format_p = yuv_format;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return result;
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout_unknown:
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ~0;
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1172