172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse/*
272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a
572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * copy of this software and associated documentation files (the "Software"),
672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * to deal in the Software without restriction, including without limitation
772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * on the rights to use, copy, modify, merge, publish, distribute, sub
872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * license, and/or sell copies of the Software, and to permit persons to whom
972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * the Software is furnished to do so, subject to the following conditions:
1072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
1172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * The above copyright notice and this permission notice (including the next
1272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * paragraph) shall be included in all copies or substantial portions of the
1372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Software.
1472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
1572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE.
2272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *
2372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Authors:
2472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *      Jerome Glisse
2572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse *      Corbin Simpson
2672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse */
27330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák#include "r600_formats.h"
28330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák#include "r600d.h"
29330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák
30ed99c28d12579bb8ee79eb9cfa55452785be7b6eJerome Glisse#include <errno.h>
318fb7f1a8a4cbab5365491b4b41e50ff3f03306c8Kai Wasserbäch#include "util/u_format_s3tc.h"
328fb7f1a8a4cbab5365491b4b41e50ff3f03306c8Kai Wasserbäch#include "util/u_memory.h"
3372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
34d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell/* Copy from a full GPU texture to a transfer's staging one. */
35d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwellstatic void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
3636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse{
3736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
3836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	struct pipe_resource *texture = transfer->resource;
3936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse
40a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	ctx->resource_copy_region(ctx, &rtransfer->staging->b.b,
414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				0, 0, 0, 0, texture, transfer->level,
424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				&transfer->box);
4336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse}
4436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse
459979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie
46d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell/* Copy from a transfer's staging texture to a full GPU one. */
47d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwellstatic void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
489979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie{
499979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
509979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie	struct pipe_resource *texture = transfer->resource;
514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	struct pipe_box sbox;
524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
53b278aba42310e8fa30f2408b9dcd58dbb4901724Marek Olšák	u_box_origin_2d(transfer->box.width, transfer->box.height, &sbox);
54b278aba42310e8fa30f2408b9dcd58dbb4901724Marek Olšák
554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	ctx->resource_copy_region(ctx, texture, transfer->level,
569979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie				  transfer->box.x, transfer->box.y, transfer->box.z,
57a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák				  &rtransfer->staging->b.b,
584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				  0, &sbox);
599979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie}
609979d60c0e2e4152bce19c2c4128ff2941b9191bDave Airlie
61951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšákunsigned r600_texture_get_offset(struct r600_texture *rtex,
624c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger					unsigned level, unsigned layer)
6372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
64773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák	return rtex->surface.level[level].offset +
65773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák	       layer * rtex->surface.level[level].slice_size;
66a23f25eba1fb8919a29efb88ef9e351abcc65b2eAlex Deucher}
67a23f25eba1fb8919a29efb88ef9e351abcc65b2eAlex Deucher
68ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšákstatic int r600_init_surface(struct r600_screen *rscreen,
69ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák			     struct radeon_surface *surface,
70c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			     const struct pipe_resource *ptex,
71018e3f75d69490598d61059ece56d379867f3995Marek Olšák			     unsigned array_mode,
72018e3f75d69490598d61059ece56d379867f3995Marek Olšák			     bool is_transfer, bool is_flushed_depth)
73c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse{
74018e3f75d69490598d61059ece56d379867f3995Marek Olšák	const struct util_format_description *desc =
75018e3f75d69490598d61059ece56d379867f3995Marek Olšák		util_format_description(ptex->format);
76018e3f75d69490598d61059ece56d379867f3995Marek Olšák	bool is_depth, is_stencil;
77018e3f75d69490598d61059ece56d379867f3995Marek Olšák
78018e3f75d69490598d61059ece56d379867f3995Marek Olšák	is_depth = util_format_has_depth(desc);
79018e3f75d69490598d61059ece56d379867f3995Marek Olšák	is_stencil = util_format_has_stencil(desc);
80018e3f75d69490598d61059ece56d379867f3995Marek Olšák
81c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->npix_x = ptex->width0;
82c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->npix_y = ptex->height0;
83c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->npix_z = ptex->depth0;
84c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->blk_w = util_format_get_blockwidth(ptex->format);
85c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->blk_h = util_format_get_blockheight(ptex->format);
86c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->blk_d = 1;
87c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->array_size = 1;
88c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->last_level = ptex->last_level;
89ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák
90ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	if (rscreen->chip_class >= EVERGREEN &&
91ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	    !is_transfer && !is_flushed_depth &&
92ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	    ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
93ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák		surface->bpe = 4; /* stencil is allocated separately on evergreen */
94ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	} else {
95ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák		surface->bpe = util_format_get_blocksize(ptex->format);
96ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák		/* align byte per element on dword */
97ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák		if (surface->bpe == 3) {
98ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák			surface->bpe = 4;
99ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák		}
100c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
101ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák
1024b78df9c81f1ca8af2b750616de8ff440e99c3c1Marek Olšák	surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1;
103c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	surface->flags = 0;
1044b78df9c81f1ca8af2b750616de8ff440e99c3c1Marek Olšák
105c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	switch (array_mode) {
106c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case V_038000_ARRAY_1D_TILED_THIN1:
107c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
108c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
109c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case V_038000_ARRAY_2D_TILED_THIN1:
110c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
111c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
112c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case V_038000_ARRAY_LINEAR_ALIGNED:
113c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
114c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
115c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case V_038000_ARRAY_LINEAR_GENERAL:
116c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	default:
117c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
118c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
119c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
120c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	switch (ptex->target) {
121c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_1D:
122c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
123c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
124c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_RECT:
125c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_2D:
126c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
127c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
128c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_3D:
129c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
130c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
131c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_1D_ARRAY:
132c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
133c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->array_size = ptex->array_size;
134c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
135c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_2D_ARRAY:
136c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
137c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->array_size = ptex->array_size;
138c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
139c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_TEXTURE_CUBE:
140c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
141c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		break;
142c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	case PIPE_BUFFER:
143c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	default:
144c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		return -EINVAL;
145c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
146c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (ptex->bind & PIPE_BIND_SCANOUT) {
147c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_SCANOUT;
148c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
149018e3f75d69490598d61059ece56d379867f3995Marek Olšák
150018e3f75d69490598d61059ece56d379867f3995Marek Olšák	if (!is_transfer && !is_flushed_depth && is_depth) {
151c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		surface->flags |= RADEON_SURF_ZBUFFER;
152c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse
153018e3f75d69490598d61059ece56d379867f3995Marek Olšák		if (is_stencil) {
154018e3f75d69490598d61059ece56d379867f3995Marek Olšák			surface->flags |= RADEON_SURF_SBUFFER;
155018e3f75d69490598d61059ece56d379867f3995Marek Olšák		}
156018e3f75d69490598d61059ece56d379867f3995Marek Olšák	}
157c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	return 0;
158c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse}
159c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse
160c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glissestatic int r600_setup_surface(struct pipe_screen *screen,
161951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák			      struct r600_texture *rtex,
162c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			      unsigned pitch_in_bytes_override)
163c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse{
164a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	struct pipe_resource *ptex = &rtex->resource.b.b;
165c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	struct r600_screen *rscreen = (struct r600_screen*)screen;
166c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	unsigned i;
167c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	int r;
168c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse
169c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
170c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (r) {
171c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		return r;
172c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
173c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	rtex->size = rtex->surface.bo_size;
174c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
175c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		/* old ddx on evergreen over estimate alignment for 1d, only 1 level
176c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		 * for those
177c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		 */
178c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
179c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
180c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
181c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
182c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
183c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		}
184c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
185c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	for (i = 0; i <= ptex->last_level; i++) {
186c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		switch (rtex->surface.level[i].mode) {
187c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		case RADEON_SURF_MODE_LINEAR_ALIGNED:
188c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED;
189c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			break;
190c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		case RADEON_SURF_MODE_1D:
191c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1;
192c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			break;
193c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		case RADEON_SURF_MODE_2D:
194c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1;
195c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			break;
196c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		default:
197c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		case RADEON_SURF_MODE_LINEAR:
198c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			rtex->array_mode[i] = 0;
199c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			break;
200c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		}
201c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
202c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	return 0;
203c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse}
204c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse
205126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
206126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet					struct pipe_resource *ptex,
207126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet					struct winsys_handle *whandle)
208126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{
209951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)ptex;
210126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	struct r600_resource *resource = &rtex->resource;
21111f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer	struct radeon_surface *surface = &rtex->surface;
2126101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	struct r600_screen *rscreen = (struct r600_screen*)screen;
213126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
21411f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer	rscreen->ws->buffer_set_tiling(resource->buf,
2157446a0407d4e61a826385c11ed6c401837baf095Michel Dänzer				       NULL,
21611f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->level[0].mode >= RADEON_SURF_MODE_1D ?
21711f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
21811f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->level[0].mode >= RADEON_SURF_MODE_2D ?
21911f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
22011f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->bankw, surface->bankh,
22111f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->tile_split,
22211f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->stencil_tile_split,
22311f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer				       surface->mtilea,
224773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák				       rtex->surface.level[0].pitch_bytes);
22511f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer
2266101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	return rscreen->ws->buffer_get_handle(resource->buf,
227773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák					      rtex->surface.level[0].pitch_bytes, whandle);
228126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet}
229126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
230126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic void r600_texture_destroy(struct pipe_screen *screen,
231126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet				 struct pipe_resource *ptex)
232126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{
233951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)ptex;
234126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	struct r600_resource *resource = &rtex->resource;
235126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
236126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	if (rtex->flushed_depth_texture)
237126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet		pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
238126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
2396101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	pb_reference(&resource->buf, NULL);
240126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	FREE(rtex);
241126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet}
242126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
243126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic const struct u_resource_vtbl r600_texture_vtbl =
244126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{
245126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_get_handle,	/* get_handle */
246126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_destroy,		/* resource_destroy */
247126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_get_transfer,	/* get_transfer */
248126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_transfer_destroy,	/* transfer_destroy */
249126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_transfer_map,	/* transfer_map */
250bf4fedcef3e345f5117232d58bd9000c2441de74Marek Olšák	NULL,				/* transfer_flush_region */
251126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet	r600_texture_transfer_unmap,	/* transfer_unmap */
252ab1328882101f67335a332e940fea92eeaf70e12Marek Olšák	NULL				/* transfer_inline_write */
253126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet};
254126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet
25578354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák/* The number of samples can be specified independently of the texture. */
25678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšákvoid r600_texture_get_fmask_info(struct r600_screen *rscreen,
25778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				 struct r600_texture *rtex,
25878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				 unsigned nr_samples,
25978354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				 struct r600_fmask_info *out)
260a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák{
261a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	/* FMASK is allocated pretty much like an ordinary texture.
262a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	 * Here we use bpe in the units of bits, not bytes. */
263a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	struct radeon_surface fmask = rtex->surface;
264a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
265a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	switch (nr_samples) {
266a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	case 2:
267a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		/* This should be 8,1, but we should set nsamples > 1
268a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		 * for the allocator to treat it as a multisample surface.
269a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		 * Let's set 4,2 then. */
270a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	case 4:
271a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.bpe = 4;
272a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.nsamples = 2;
273a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		break;
274a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	case 8:
275a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.bpe = 8;
276a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.nsamples = 4;
277a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		break;
278a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	case 16:
279a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.bpe = 16;
280a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.nsamples = 4;
281a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		break;
282a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	default:
283a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		R600_ERR("Invalid sample count for FMASK allocation.\n");
284a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		return;
285a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
286a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
2878698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák	/* R600-R700 errata? Anyway, this fixes colorbuffer corruption. */
2888698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák	if (rscreen->chip_class <= R700) {
2898698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák		fmask.bpe *= 2;
2908698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák	}
2918698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák
292a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	if (rscreen->chip_class >= EVERGREEN) {
293a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		fmask.bankh = nr_samples <= 4 ? 4 : 1;
294a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
295a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
296a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	if (rscreen->ws->surface_init(rscreen->ws, &fmask)) {
297a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		R600_ERR("Got error in surface_init while allocating FMASK.\n");
298a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		return;
299a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
300a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
301a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
30278354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->bank_height = fmask.bankh;
30378354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->alignment = MAX2(256, fmask.bo_alignment);
30478354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->size = (fmask.bo_size + 7) / 8;
30578354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák}
30678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
30778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšákstatic void r600_texture_allocate_fmask(struct r600_screen *rscreen,
30878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák					struct r600_texture *rtex)
30978354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák{
31078354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	struct r600_fmask_info fmask;
31178354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
31278354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	r600_texture_get_fmask_info(rscreen, rtex,
31378354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				    rtex->resource.b.b.nr_samples, &fmask);
31478354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
315a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	/* Reserve space for FMASK while converting bits back to bytes. */
31678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->fmask_bank_height = fmask.bank_height;
31778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->fmask_offset = align(rtex->size, fmask.alignment);
31878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->fmask_size = fmask.size;
319a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	rtex->size = rtex->fmask_offset + rtex->fmask_size;
320a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák#if 0
321a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	printf("FMASK width=%u, height=%i, bits=%u, size=%u\n",
322a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	       fmask.npix_x, fmask.npix_y, fmask.bpe * fmask.nsamples, rtex->fmask_size);
323a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák#endif
324a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák}
325a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
32678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšákvoid r600_texture_get_cmask_info(struct r600_screen *rscreen,
32778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				 struct r600_texture *rtex,
32878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák				 struct r600_cmask_info *out)
329a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák{
330a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned cmask_tile_width = 8;
331a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned cmask_tile_height = 8;
332a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned cmask_tile_elements = cmask_tile_width * cmask_tile_height;
333a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned element_bits = 4;
334a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned cmask_cache_bits = 1024;
335a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned num_pipes = rscreen->tiling_info.num_channels;
336a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
337a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
338a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned elements_per_macro_tile = (cmask_cache_bits / element_bits) * num_pipes;
339a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned pixels_per_macro_tile = elements_per_macro_tile * cmask_tile_elements;
340a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned sqrt_pixels_per_macro_tile = sqrt(pixels_per_macro_tile);
341a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned macro_tile_width = util_next_power_of_two(sqrt_pixels_per_macro_tile);
342a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned macro_tile_height = pixels_per_macro_tile / macro_tile_width;
343a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
344a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned pitch_elements = align(rtex->surface.npix_x, macro_tile_width);
345a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned height = align(rtex->surface.npix_y, macro_tile_height);
346a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
347a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned base_align = num_pipes * pipe_interleave_bytes;
348a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	unsigned slice_bytes =
349a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		((pitch_elements * height * element_bits + 7) / 8) / cmask_tile_elements;
350a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
351a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	assert(macro_tile_width % 128 == 0);
352a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	assert(macro_tile_height % 128 == 0);
353a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
35478354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
35578354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->alignment = MAX2(256, base_align);
35678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	out->size = rtex->surface.array_size * align(slice_bytes, base_align);
35778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák}
35878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
35978354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšákstatic void r600_texture_allocate_cmask(struct r600_screen *rscreen,
36078354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák					struct r600_texture *rtex)
36178354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák{
36278354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	struct r600_cmask_info cmask;
36378354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
36478354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	r600_texture_get_cmask_info(rscreen, rtex, &cmask);
36578354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák
36678354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->cmask_slice_tile_max = cmask.slice_tile_max;
36778354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->cmask_offset = align(rtex->size, cmask.alignment);
36878354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	rtex->cmask_size = cmask.size;
369a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	rtex->size = rtex->cmask_offset + rtex->cmask_size;
370a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák#if 0
371a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	printf("CMASK: macro tile width = %u, macro tile height = %u, "
372a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	       "pitch elements = %u, height = %u, slice tile max = %u\n",
373a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	       macro_tile_width, macro_tile_height, pitch_elements, height,
374a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	       rtex->cmask_slice_tile_max);
375a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák#endif
376a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák}
377a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
378951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšákstatic struct r600_texture *
3796a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlier600_texture_create_object(struct pipe_screen *screen,
3806a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie			   const struct pipe_resource *base,
3816a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie			   unsigned pitch_in_bytes_override,
3826101b6d442b06a347c001fe85848d636ab7df260Marek Olšák			   struct pb_buffer *buf,
383c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			   boolean alloc_bo,
384c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse			   struct radeon_surface *surface)
38572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
386951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex;
387742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	struct r600_resource *resource;
3886101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	struct r600_screen *rscreen = (struct r600_screen*)screen;
389c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	int r;
390c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse
391951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	rtex = CALLOC_STRUCT(r600_texture);
3926a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie	if (rtex == NULL)
39372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
3946a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie
395742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	resource = &rtex->resource;
396a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	resource->b.b = *base;
397a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	resource->b.vtbl = &r600_texture_vtbl;
398a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	pipe_reference_init(&resource->b.b.reference, 1);
399a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák	resource->b.b.screen = screen;
4006a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie	rtex->pitch_override = pitch_in_bytes_override;
40168c54abb2cfd12a031829e78d721b2480d0c8cc4Marek Olšák
4027c371f46958910dd2ca9487c89af1b72bbfdada9Marek Olšák	/* don't include stencil-only formats which we don't support for rendering */
4037c371f46958910dd2ca9487c89af1b72bbfdada9Marek Olšák	rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
40438b54158b68479e1f97c8452ba0d67f50dce7582Henri Verbeet
405581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák	rtex->surface = *surface;
4061ea263fccb9259218addec9e805db075be9eba7cMarek Olšák	r = r600_setup_surface(screen, rtex,
407581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák			       pitch_in_bytes_override);
408581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák	if (r) {
409581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák		FREE(rtex);
410581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák		return NULL;
41168c54abb2cfd12a031829e78d721b2480d0c8cc4Marek Olšák	}
41268c54abb2cfd12a031829e78d721b2480d0c8cc4Marek Olšák
413a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	if (base->nr_samples > 1 && !rtex->is_depth && alloc_bo) {
414a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		r600_texture_allocate_cmask(rscreen, rtex);
4158698a3b85dd89c5d2fa473e7942b7dc8d25f3c8fMarek Olšák		r600_texture_allocate_fmask(rscreen, rtex);
416a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
417a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
418a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	if (!rtex->is_depth && base->nr_samples > 1 &&
419a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	    (!rtex->fmask_size || !rtex->cmask_size)) {
420a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		FREE(rtex);
421a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		return NULL;
422a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
423a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
4247f29824fd5df27eca516ad65e4a4f8ff94fe7bedMarek Olšák	/* Now create the backing buffer. */
4256101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	if (!buf && alloc_bo) {
426581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák		unsigned base_align = rtex->surface.bo_alignment;
427952c90576753550f4deed4dac42d8fd6129a9cceMarek Olšák		unsigned usage = R600_TEX_IS_TILED(rtex, 0) ? PIPE_USAGE_STATIC : base->usage;
428581f7e3101980a4e1068bb75c2eca60bb2071229Marek Olšák
429952c90576753550f4deed4dac42d8fd6129a9cceMarek Olšák		if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, usage)) {
4306a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie			FREE(rtex);
4316a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie			return NULL;
4326a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie		}
4336101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	} else if (buf) {
4346101b6d442b06a347c001fe85848d636ab7df260Marek Olšák		resource->buf = buf;
4356101b6d442b06a347c001fe85848d636ab7df260Marek Olšák		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
43693f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
43772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	}
438a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák
439a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	if (rtex->cmask_size) {
440a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		/* Initialize the cmask to 0xCC (= compressed state). */
441a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		char *ptr = rscreen->ws->buffer_map(resource->cs_buf, NULL, PIPE_TRANSFER_WRITE);
442a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		memset(ptr + rtex->cmask_offset, 0xCC, rtex->cmask_size);
443a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák		rscreen->ws->buffer_unmap(resource->cs_buf);
444a3d9d7ec79d6f7205fab2324e47d8ea185431de0Marek Olšák	}
4456a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie	return rtex;
4466a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie}
4476a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie
4486a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airliestruct pipe_resource *r600_texture_create(struct pipe_screen *screen,
4496a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie						const struct pipe_resource *templ)
4506a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie{
4511a532ca79a4a87bb86c641a6ca22da0301dc1f62Marek Olšák	struct r600_screen *rscreen = (struct r600_screen*)screen;
452c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	struct radeon_surface surface;
4536a0066a69f6873a53d45684205926e8f5b73ddb2Dave Airlie	unsigned array_mode = 0;
454c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	int r;
455ee07e0e39ad1c4d13d540b23220fecc564d07b16Keith Whitwell
4560d91ddf1d4be712377e80d330480ff560d449c6fMarek Olšák	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER)) {
4570ac90296a092f846647812318913b0e492775f31Marek Olšák		if (templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) {
4580ac90296a092f846647812318913b0e492775f31Marek Olšák			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
4590ac90296a092f846647812318913b0e492775f31Marek Olšák		} else if (!(templ->bind & PIPE_BIND_SCANOUT) &&
4600d91ddf1d4be712377e80d330480ff560d449c6fMarek Olšák		    templ->usage != PIPE_USAGE_STAGING &&
4617c371f46958910dd2ca9487c89af1b72bbfdada9Marek Olšák		    templ->usage != PIPE_USAGE_STREAM) {
4620d91ddf1d4be712377e80d330480ff560d449c6fMarek Olšák			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
463c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		} else if (util_format_is_compressed(templ->format)) {
46498a87a594b6983d2a05d9412e3fa074894c334ffMarek Olšák			array_mode = V_038000_ARRAY_1D_TILED_THIN1;
46598a87a594b6983d2a05d9412e3fa074894c334ffMarek Olšák		}
466089aa0ba247cee908ae689f8e4f3ffc457ce7627Dave Airlie	}
467089aa0ba247cee908ae689f8e4f3ffc457ce7627Dave Airlie
468f36c404f900dee95ecfe9d5c6a7c6efdf5e25963Marek Olšák	/* XXX tiling is broken for the 422 formats */
469f36c404f900dee95ecfe9d5c6a7c6efdf5e25963Marek Olšák	if (util_format_description(templ->format)->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
470f36c404f900dee95ecfe9d5c6a7c6efdf5e25963Marek Olšák		array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
471f36c404f900dee95ecfe9d5c6a7c6efdf5e25963Marek Olšák
472ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	r = r600_init_surface(rscreen, &surface, templ, array_mode,
473018e3f75d69490598d61059ece56d379867f3995Marek Olšák			      templ->flags & R600_RESOURCE_FLAG_TRANSFER,
474018e3f75d69490598d61059ece56d379867f3995Marek Olšák			      templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH);
475c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (r) {
476c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		return NULL;
477c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
478c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	r = rscreen->ws->surface_best(rscreen->ws, &surface);
479c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (r) {
480c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		return NULL;
481c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
482362a25aac5f8cd71c08ad92b4b19be6712d8fd72Marek Olšák	return (struct pipe_resource *)r600_texture_create_object(screen, templ,
4831ea263fccb9259218addec9e805db075be9eba7cMarek Olšák								  0, NULL, TRUE, &surface);
48472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
48572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
4864c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggerstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
487b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák						struct pipe_resource *texture,
488e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák						const struct pipe_surface *templ)
48972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
4906fd9218bb44b8719da60ce325d4f41c4a611e871Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)texture;
49191e513044de21f20c2c085a99e9d784c7a61173cDave Airlie	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
492e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák	unsigned level = templ->u.tex.level;
49372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
494e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák	assert(templ->u.tex.first_layer == templ->u.tex.last_layer);
49572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	if (surface == NULL)
49672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
49791e513044de21f20c2c085a99e9d784c7a61173cDave Airlie	pipe_reference_init(&surface->base.reference, 1);
49891e513044de21f20c2c085a99e9d784c7a61173cDave Airlie	pipe_resource_reference(&surface->base.texture, texture);
4994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	surface->base.context = pipe;
500e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák	surface->base.format = templ->format;
5016fd9218bb44b8719da60ce325d4f41c4a611e871Marek Olšák	surface->base.width = rtex->surface.level[level].npix_x;
5026fd9218bb44b8719da60ce325d4f41c4a611e871Marek Olšák	surface->base.height = rtex->surface.level[level].npix_y;
503e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák	surface->base.usage = templ->usage;
504e6dfc8c77bc00c06a35270a4e50aa52c738c8629Marek Olšák	surface->base.u = templ->u;
50591e513044de21f20c2c085a99e9d784c7a61173cDave Airlie	return &surface->base;
50672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
50772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
5084c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggerstatic void r600_surface_destroy(struct pipe_context *pipe,
5094c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				 struct pipe_surface *surface)
51072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
51178354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	struct r600_surface *surf = (struct r600_surface*)surface;
51278354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL);
51378354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák	pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL);
514b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák	pipe_resource_reference(&surface->texture, NULL);
51572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	FREE(surface);
51672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
51772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
518b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšákstruct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
519742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse					       const struct pipe_resource *templ,
520b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák					       struct winsys_handle *whandle)
52172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
5226101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	struct r600_screen *rscreen = (struct r600_screen*)screen;
5236101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	struct pb_buffer *buf = NULL;
5242ce783d8ddec1b1fcadc0798af0ebb045bba1cc4Marek Olšák	unsigned stride = 0;
5258a74f7422bedb419f3527bb1ccd60e1e9220502cDave Airlie	unsigned array_mode = 0;
5266101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	enum radeon_bo_layout micro, macro;
527c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	struct radeon_surface surface;
528c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	int r;
52972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
53072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse	/* Support only 2D textures without mipmaps */
531ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
532ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri	      templ->depth0 != 1 || templ->last_level != 0)
53372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse		return NULL;
534b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák
535af8eb5c851a9d566059ae9e37745614cd96b9a13Marek Olšák	buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
5366101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	if (!buf)
537ac2bddb9f2c40effb16db321db0177decea81a92Tilman Sauerbeck		return NULL;
5386101b6d442b06a347c001fe85848d636ab7df260Marek Olšák
539c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
540c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse				       &surface.bankw, &surface.bankh,
541c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse				       &surface.tile_split,
542c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse				       &surface.stencil_tile_split,
543c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse				       &surface.mtilea);
5446101b6d442b06a347c001fe85848d636ab7df260Marek Olšák
5456101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	if (macro == RADEON_LAYOUT_TILED)
5466101b6d442b06a347c001fe85848d636ab7df260Marek Olšák		array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
5476101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	else if (micro == RADEON_LAYOUT_TILED)
5486101b6d442b06a347c001fe85848d636ab7df260Marek Olšák		array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
5496101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	else
5506101b6d442b06a347c001fe85848d636ab7df260Marek Olšák		array_mode = 0;
551ac2bddb9f2c40effb16db321db0177decea81a92Tilman Sauerbeck
552ea72351a919c594e7f40e901dca42aebb866f8a6Marek Olšák	r = r600_init_surface(rscreen, &surface, templ, array_mode, false, false);
553c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	if (r) {
554c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse		return NULL;
555c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse	}
556362a25aac5f8cd71c08ad92b4b19be6712d8fd72Marek Olšák	return (struct pipe_resource *)r600_texture_create_object(screen, templ,
5571ea263fccb9259218addec9e805db075be9eba7cMarek Olšák								  stride, buf, FALSE, &surface);
55872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
55972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
560611dd529425281d73f1f0ad2000362d4a5525a25Marek Olšákbool r600_init_flushed_depth_texture(struct pipe_context *ctx,
56137708479608af877986b76302a9c92611d1e23d0Vadim Girlin				     struct pipe_resource *texture,
562951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák				     struct r600_texture **staging)
5632f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie{
564951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)texture;
5652f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie	struct pipe_resource resource;
566951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture **flushed_depth_texture = staging ?
56737708479608af877986b76302a9c92611d1e23d0Vadim Girlin			staging : &rtex->flushed_depth_texture;
5682f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie
56937708479608af877986b76302a9c92611d1e23d0Vadim Girlin	if (!staging && rtex->flushed_depth_texture)
570611dd529425281d73f1f0ad2000362d4a5525a25Marek Olšák		return true; /* it's ready */
5712f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie
572840ad139aff401829552d0e3ba77f8abcb5862bdMarek Olšák	resource.target = texture->target;
5732f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie	resource.format = texture->format;
5742f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie	resource.width0 = texture->width0;
5752f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie	resource.height0 = texture->height0;
576840ad139aff401829552d0e3ba77f8abcb5862bdMarek Olšák	resource.depth0 = texture->depth0;
577840ad139aff401829552d0e3ba77f8abcb5862bdMarek Olšák	resource.array_size = texture->array_size;
5782271c793e8650e0e55c054301ab85b5b92b9bf11Dave Airlie	resource.last_level = texture->last_level;
579840ad139aff401829552d0e3ba77f8abcb5862bdMarek Olšák	resource.nr_samples = texture->nr_samples;
580c4993d15eb07d95ac465b5f25ea96072e4b008bfMarek Olšák	resource.usage = staging ? PIPE_USAGE_STAGING : PIPE_USAGE_STATIC;
58137708479608af877986b76302a9c92611d1e23d0Vadim Girlin	resource.bind = texture->bind & ~PIPE_BIND_DEPTH_STENCIL;
582018e3f75d69490598d61059ece56d379867f3995Marek Olšák	resource.flags = texture->flags | R600_RESOURCE_FLAG_FLUSHED_DEPTH;
58337708479608af877986b76302a9c92611d1e23d0Vadim Girlin
58437708479608af877986b76302a9c92611d1e23d0Vadim Girlin	if (staging)
58537708479608af877986b76302a9c92611d1e23d0Vadim Girlin		resource.flags |= R600_RESOURCE_FLAG_TRANSFER;
5862f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie
587951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	*flushed_depth_texture = (struct r600_texture *)ctx->screen->resource_create(ctx->screen, &resource);
58837708479608af877986b76302a9c92611d1e23d0Vadim Girlin	if (*flushed_depth_texture == NULL) {
58937708479608af877986b76302a9c92611d1e23d0Vadim Girlin		R600_ERR("failed to create temporary texture to hold flushed depth\n");
590611dd529425281d73f1f0ad2000362d4a5525a25Marek Olšák		return false;
5912f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie	}
5922f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie
59337708479608af877986b76302a9c92611d1e23d0Vadim Girlin	(*flushed_depth_texture)->is_flushing_texture = TRUE;
594611dd529425281d73f1f0ad2000362d4a5525a25Marek Olšák	return true;
595da98bb6fc105e1a2f688a1713ca9e50f0ac8fbedMarek Olšák}
596da98bb6fc105e1a2f688a1713ca9e50f0ac8fbedMarek Olšák
597742ee7935da60dda974795243d2e0fcf31accb59Jerome Glissestruct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
598742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse						struct pipe_resource *texture,
5994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger						unsigned level,
600742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse						unsigned usage,
601742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse						const struct pipe_box *box)
602742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse{
60381c04848625182c51d89c91f34ea6ab51d9ed090Marek Olšák	struct r600_context *rctx = (struct r600_context*)ctx;
604951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)texture;
60536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	struct pipe_resource resource;
606742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	struct r600_transfer *trans;
607d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	boolean use_staging_texture = FALSE;
608d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell
609d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	/* We cannot map a tiled texture directly because the data is
610d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 * in a different order, therefore we do detiling using a blit.
611d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 *
612d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 * Also, use a temporary in GTT memory for read transfers, as
613d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 * the CPU is much happier reading out of cached system memory
614d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 * than uncached VRAM.
615d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	 */
616b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	if (R600_TEX_IS_TILED(rtex, level)) {
617d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell		use_staging_texture = TRUE;
618b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	}
619d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell
62081c04848625182c51d89c91f34ea6ab51d9ed090Marek Olšák	/* Use a staging texture for uploads if the underlying BO is busy. */
62181c04848625182c51d89c91f34ea6ab51d9ed090Marek Olšák	if (!(usage & PIPE_TRANSFER_READ) &&
62229e55bc5f1b6d7375b6a86e24ca4ae58e399011eMarek Olšák	    (rctx->ws->cs_is_buffer_referenced(rctx->cs, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
623b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	     rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) {
624119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		use_staging_texture = TRUE;
625b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	}
626119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse
6277c371f46958910dd2ca9487c89af1b72bbfdada9Marek Olšák	if (texture->flags & R600_RESOURCE_FLAG_TRANSFER) {
628119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		use_staging_texture = FALSE;
629b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	}
630e3ea4aec033643a629e2fa48eb538fdb856adf4eKeith Whitwell
631b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
632702838a7061cde91a6bcdd3382817deb61218bf1Michel Dänzer		return NULL;
633b4f0ab0b22625ac1bb3cf16342039557c086ebaeJerome Glisse	}
634702838a7061cde91a6bcdd3382817deb61218bf1Michel Dänzer
635742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	trans = CALLOC_STRUCT(r600_transfer);
636742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	if (trans == NULL)
637742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse		return NULL;
638742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	pipe_resource_reference(&trans->transfer.resource, texture);
6394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	trans->transfer.level = level;
640742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	trans->transfer.usage = usage;
641742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	trans->transfer.box = *box;
642d334d591a71c41d6a1eb4f2ea6cdabedc425e42fMarek Olšák	if (rtex->is_depth) {
643119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		/* XXX: only readback the rectangle which is being mapped?
644119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		*/
645119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		/* XXX: when discard is true, no need to read back from depth texture
646119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		*/
647951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák		struct r600_texture *staging_depth;
64837708479608af877986b76302a9c92611d1e23d0Vadim Girlin
649b242adbe5cfa165b252064a1ea36f802d8251ef1Marek Olšák		if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
6502f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie			R600_ERR("failed to create temporary texture to hold untiled copy\n");
6512f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie			pipe_resource_reference(&trans->transfer.resource, NULL);
6522f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie			FREE(trans);
6532f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie			return NULL;
6542f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie		}
655b242adbe5cfa165b252064a1ea36f802d8251ef1Marek Olšák
65648edfe0505ee79d35f770f53b9c9b7ca3c69fd2bMarek Olšák		r600_blit_decompress_depth(ctx, rtex, staging_depth,
657b242adbe5cfa165b252064a1ea36f802d8251ef1Marek Olšák					   level, level,
65894b634eca0e2bd32d4b5bd92d06d510eae8a5625Marek Olšák					   box->z, box->z + box->depth - 1,
65994b634eca0e2bd32d4b5bd92d06d510eae8a5625Marek Olšák					   0, 0);
660b242adbe5cfa165b252064a1ea36f802d8251ef1Marek Olšák
661773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák		trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes;
66237708479608af877986b76302a9c92611d1e23d0Vadim Girlin		trans->offset = r600_texture_get_offset(staging_depth, level, box->z);
66337708479608af877986b76302a9c92611d1e23d0Vadim Girlin		trans->staging = (struct r600_resource*)staging_depth;
664d0293290ad620084d490b51693d97731a8935094Dave Airlie		return &trans->transfer;
665d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell	} else if (use_staging_texture) {
66636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.target = PIPE_TEXTURE_2D;
66736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.format = texture->format;
66836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.width0 = box->width;
66936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.height0 = box->height;
670833b4fc11e0fcac36490b036135298232310568aDave Airlie		resource.depth0 = 1;
6714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger		resource.array_size = 1;
67236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.last_level = 0;
67336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.nr_samples = 0;
674d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell		resource.usage = PIPE_USAGE_STAGING;
67536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		resource.bind = 0;
67692ed84d11560e226c87bf2758b1503e3075b3f82Dave Airlie		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
67736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		/* For texture reading, the temporary (detiled) texture is used as
67836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		 * a render target when blitting from a tiled texture. */
67936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		if (usage & PIPE_TRANSFER_READ) {
68036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			resource.bind |= PIPE_BIND_RENDER_TARGET;
68136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		}
68236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		/* For texture writing, the temporary texture is used as a sampler
68336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		 * when blitting into a tiled texture. */
68436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		if (usage & PIPE_TRANSFER_WRITE) {
68536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
68636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		}
68736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		/* Create the temporary texture. */
688897af1d499ed91ed3629432424eb1ac62bff2c5fMarek Olšák		trans->staging = (struct r600_resource*)ctx->screen->resource_create(ctx->screen, &resource);
689897af1d499ed91ed3629432424eb1ac62bff2c5fMarek Olšák		if (trans->staging == NULL) {
69036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			R600_ERR("failed to create temporary texture to hold untiled copy\n");
69136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			pipe_resource_reference(&trans->transfer.resource, NULL);
69236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			FREE(trans);
69336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			return NULL;
69436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		}
695e9acf9a3bb45caea7b0fba197aa9ab01f24bb63fDave Airlie
696e9acf9a3bb45caea7b0fba197aa9ab01f24bb63fDave Airlie		trans->transfer.stride =
697951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák			((struct r600_texture *)trans->staging)->surface.level[0].pitch_bytes;
69863c3e3a3dc73f8a72e0d08ac4453df57bccdfdb9Keith Whitwell		if (usage & PIPE_TRANSFER_READ) {
699d4fab99c1c20334131b446b0032303a8b3c5c1a1Keith Whitwell			r600_copy_to_staging_texture(ctx, trans);
70036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			/* Always referenced in the blit. */
701c79e9f0ed59d561849a0a4fbaafe87d5064d3e8cMarek Olšák			r600_flush(ctx, NULL, 0);
70236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		}
703375613afe38e0704b4ce38e64765b12d9660a846Dave Airlie		return &trans->transfer;
70436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	}
705773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák	trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
706773ff5705f3b2d88fb7094b8d2e051bb684c2323Marek Olšák	trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
7074c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	trans->offset = r600_texture_get_offset(rtex, level, box->z);
708742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	return &trans->transfer;
709742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse}
710742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse
711742ee7935da60dda974795243d2e0fcf31accb59Jerome Glissevoid r600_texture_transfer_destroy(struct pipe_context *ctx,
71236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse				   struct pipe_transfer *transfer)
713742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse{
71436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
715aa31a5cbc7b52eb1d03c6eab414479249830eabfDave Airlie	struct pipe_resource *texture = transfer->resource;
716951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex = (struct r600_texture*)texture;
71736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse
71843e226b6efb77db2247741cc2057d9625a2cfa05Marek Olšák	if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) {
71943e226b6efb77db2247741cc2057d9625a2cfa05Marek Olšák		if (rtex->is_depth) {
720e773a48a3bf9ab839f10794506c0a492b7eab883Marek Olšák			ctx->resource_copy_region(ctx, texture, transfer->level,
72143e226b6efb77db2247741cc2057d9625a2cfa05Marek Olšák						  transfer->box.x, transfer->box.y, transfer->box.z,
722e773a48a3bf9ab839f10794506c0a492b7eab883Marek Olšák						  &rtransfer->staging->b.b, transfer->level,
72343e226b6efb77db2247741cc2057d9625a2cfa05Marek Olšák						  &transfer->box);
72443e226b6efb77db2247741cc2057d9625a2cfa05Marek Olšák		} else {
72537708479608af877986b76302a9c92611d1e23d0Vadim Girlin			r600_copy_from_staging_texture(ctx, rtransfer);
72637708479608af877986b76302a9c92611d1e23d0Vadim Girlin		}
727aa31a5cbc7b52eb1d03c6eab414479249830eabfDave Airlie	}
728aa31a5cbc7b52eb1d03c6eab414479249830eabfDave Airlie
72937708479608af877986b76302a9c92611d1e23d0Vadim Girlin	if (rtransfer->staging)
73037708479608af877986b76302a9c92611d1e23d0Vadim Girlin		pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
73137708479608af877986b76302a9c92611d1e23d0Vadim Girlin
73236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	pipe_resource_reference(&transfer->resource, NULL);
73336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	FREE(transfer);
734742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse}
735742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse
736742ee7935da60dda974795243d2e0fcf31accb59Jerome Glissevoid* r600_texture_transfer_map(struct pipe_context *ctx,
737742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse				struct pipe_transfer* transfer)
738742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse{
739e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák	struct r600_context *rctx = (struct r600_context *)ctx;
740742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
7410a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák	struct radeon_winsys_cs_handle *buf;
742951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák	struct r600_texture *rtex =
743951ac46a6a0a901b53a518c8dcde734578cbf228Marek Olšák			(struct r600_texture*)transfer->resource;
744742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	enum pipe_format format = transfer->resource->format;
745f8778eeb40daf355f8dbcfeb1a9b492c57ce6a35Dave Airlie	unsigned offset = 0;
746742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	char *map;
747b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák
7486a829a1b724ca0d960decee217d260b4de8a5463Adam Rak	if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) {
7496a829a1b724ca0d960decee217d260b4de8a5463Adam Rak		return r600_compute_global_transfer_map(ctx, transfer);
7506a829a1b724ca0d960decee217d260b4de8a5463Adam Rak	}
7516a829a1b724ca0d960decee217d260b4de8a5463Adam Rak
752897af1d499ed91ed3629432424eb1ac62bff2c5fMarek Olšák	if (rtransfer->staging) {
7530a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák		buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
75436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	} else {
75537708479608af877986b76302a9c92611d1e23d0Vadim Girlin		buf = ((struct r600_resource *)transfer->resource)->cs_buf;
75637708479608af877986b76302a9c92611d1e23d0Vadim Girlin	}
7572f8453eea3b5ff8d2818517753d3990490f699b8Dave Airlie
75837708479608af877986b76302a9c92611d1e23d0Vadim Girlin	if (rtex->is_depth || !rtransfer->staging)
759d843bbfd3f92d5afea665c3ff16bcca0628f2e7bJerome Glisse		offset = rtransfer->offset +
760d843bbfd3f92d5afea665c3ff16bcca0628f2e7bJerome Glisse			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
761d843bbfd3f92d5afea665c3ff16bcca0628f2e7bJerome Glisse			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
76214c0bbf469642722f86df315b9f85d23f9753956Keith Whitwell
763e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák	if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
764742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse		return NULL;
765742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse	}
766b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák
767d843bbfd3f92d5afea665c3ff16bcca0628f2e7bJerome Glisse	return map + offset;
76872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
76972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
770742ee7935da60dda974795243d2e0fcf31accb59Jerome Glissevoid r600_texture_transfer_unmap(struct pipe_context *ctx,
771742ee7935da60dda974795243d2e0fcf31accb59Jerome Glisse				 struct pipe_transfer* transfer)
77272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
77336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
774e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák	struct r600_context *rctx = (struct r600_context*)ctx;
7750a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák	struct radeon_winsys_cs_handle *buf;
776b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák
7776a829a1b724ca0d960decee217d260b4de8a5463Adam Rak	if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) {
7786a829a1b724ca0d960decee217d260b4de8a5463Adam Rak		return r600_compute_global_transfer_unmap(ctx, transfer);
7796a829a1b724ca0d960decee217d260b4de8a5463Adam Rak	}
7806a829a1b724ca0d960decee217d260b4de8a5463Adam Rak
781897af1d499ed91ed3629432424eb1ac62bff2c5fMarek Olšák	if (rtransfer->staging) {
7820a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák		buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
78336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	} else {
78437708479608af877986b76302a9c92611d1e23d0Vadim Girlin		buf = ((struct r600_resource *)transfer->resource)->cs_buf;
78536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	}
7866101b6d442b06a347c001fe85848d636ab7df260Marek Olšák	rctx->ws->buffer_unmap(buf);
78772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
78872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse
789e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšákvoid r600_init_surface_functions(struct r600_context *r600)
79072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{
7914c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	r600->context.create_surface = r600_create_surface;
7924c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger	r600->context.surface_destroy = r600_surface_destroy;
79372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse}
794e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
795e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airliestatic unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
79636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		const unsigned char *swizzle_view)
797e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie{
79836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	unsigned i;
79936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	unsigned char swizzle[4];
80036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	unsigned result = 0;
80136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	const uint32_t swizzle_shift[4] = {
80236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		16, 19, 22, 25,
80336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	};
80436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	const uint32_t swizzle_bit[4] = {
80536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		0, 1, 2, 3,
80636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	};
80736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse
80836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	if (swizzle_view) {
809be7407b75b12c70e1925c10117937ae2b9e6711fMarek Olšák		util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
81036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	} else {
81136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		memcpy(swizzle, swizzle_format, 4);
81236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	}
81336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse
81436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	/* Get swizzle. */
81536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	for (i = 0; i < 4; i++) {
81636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		switch (swizzle[i]) {
81736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		case UTIL_FORMAT_SWIZZLE_Y:
81836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= swizzle_bit[1] << swizzle_shift[i];
81936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			break;
82036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		case UTIL_FORMAT_SWIZZLE_Z:
82136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= swizzle_bit[2] << swizzle_shift[i];
82236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			break;
82336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		case UTIL_FORMAT_SWIZZLE_W:
82436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= swizzle_bit[3] << swizzle_shift[i];
82536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			break;
82636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		case UTIL_FORMAT_SWIZZLE_0:
82736efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
82836efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			break;
82936efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		case UTIL_FORMAT_SWIZZLE_1:
83036efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
83136efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			break;
83236efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		default: /* UTIL_FORMAT_SWIZZLE_X */
83336efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse			result |= swizzle_bit[0] << swizzle_shift[i];
83436efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse		}
83536efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	}
83636efb86c0570d86d8dfce87fd2416125e0e91b40Jerome Glisse	return result;
837e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie}
838e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
839e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie/* texture format translate */
840929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlieuint32_t r600_translate_texformat(struct pipe_screen *screen,
841929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie				  enum pipe_format format,
8429e964baaf34fedec385a750b97fd6684fc52584aHenri Verbeet				  const unsigned char *swizzle_view,
843e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				  uint32_t *word4_p, uint32_t *yuv_format_p)
844e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie{
845e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	uint32_t result = 0, word4 = 0, yuv_format = 0;
846e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	const struct util_format_description *desc;
847e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	boolean uniform = TRUE;
848dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie	static int r600_enable_s3tc = -1;
849a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie	bool is_srgb_valid = FALSE;
850dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie
851e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	int i;
852e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	const uint32_t sign_bit[4] = {
853e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
854e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
855e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
856e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
857e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	};
858e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	desc = util_format_description(format);
859e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
860e8ff0f63b6f078b17989e42dd05c9b69729b341bDave Airlie	word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
861e8ff0f63b6f078b17989e42dd05c9b69729b341bDave Airlie
862e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	/* Colorspace (return non-RGB formats directly). */
863e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	switch (desc->colorspace) {
864e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		/* Depth stencil formats */
865e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_COLORSPACE_ZS:
866e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		switch (format) {
867e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case PIPE_FORMAT_Z16_UNORM:
86882114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie			result = FMT_16;
869e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_word4;
870866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_X24S8_UINT:
87140acb109de61ba445b9247f7d53eaf1c2b9b1245Dave Airlie			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
872e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case PIPE_FORMAT_Z24X8_UNORM:
873866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_Z24_UNORM_S8_UINT:
87482114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie			result = FMT_8_24;
875e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_word4;
876866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_S8X24_UINT:
87740acb109de61ba445b9247f7d53eaf1c2b9b1245Dave Airlie			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
8783a1defa5e88cc846d8f5ba73ef475af95e7bc4aeDave Airlie		case PIPE_FORMAT_X8Z24_UNORM:
879866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_S8_UINT_Z24_UNORM:
88082114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie			result = FMT_24_8;
8813a1defa5e88cc846d8f5ba73ef475af95e7bc4aeDave Airlie			goto out_word4;
882866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_S8_UINT:
883c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell			result = FMT_8;
88440acb109de61ba445b9247f7d53eaf1c2b9b1245Dave Airlie			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
88540acb109de61ba445b9247f7d53eaf1c2b9b1245Dave Airlie			goto out_word4;
88689954723bfeef59d055d2332ff112f0204b48130Marek Olšák		case PIPE_FORMAT_Z32_FLOAT:
88789954723bfeef59d055d2332ff112f0204b48130Marek Olšák			result = FMT_32_FLOAT;
88889954723bfeef59d055d2332ff112f0204b48130Marek Olšák			goto out_word4;
8890a21b561c7e476c0c17e346da9fcd0734db0da1fMarek Olšák		case PIPE_FORMAT_X32_S8X24_UINT:
8900a21b561c7e476c0c17e346da9fcd0734db0da1fMarek Olšák			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
891866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie		case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
89289954723bfeef59d055d2332ff112f0204b48130Marek Olšák			result = FMT_X24_8_32_FLOAT;
89389954723bfeef59d055d2332ff112f0204b48130Marek Olšák			goto out_word4;
894e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		default:
895e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
896e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
897e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
898e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_COLORSPACE_YUV:
899e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		yuv_format |= (1 << 30);
900e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		switch (format) {
901119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		case PIPE_FORMAT_UYVY:
902119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		case PIPE_FORMAT_YUYV:
903e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		default:
904e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			break;
905e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
906370c8b5ee7666f4f515d63603afe8282b1b3c682Marek Olšák		goto out_unknown; /* XXX */
9079e964baaf34fedec385a750b97fd6684fc52584aHenri Verbeet
908e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_COLORSPACE_SRGB:
909e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		word4 |= S_038010_FORCE_DEGAMMA(1);
910e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		break;
911e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
912e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	default:
913e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		break;
914e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
915e0b6df4fcce0964ea7930efeb40cb487b4c53337John Doe
916929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie	if (r600_enable_s3tc == -1) {
917929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie		struct r600_screen *rscreen = (struct r600_screen *)screen;
9181a532ca79a4a87bb86c641a6ca22da0301dc1f62Marek Olšák		if (rscreen->info.drm_minor >= 9)
919929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie			r600_enable_s3tc = 1;
920929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie		else
921929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie			r600_enable_s3tc = debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
922929be6eb95c33d5885a89b36dbc82db64c1344feDave Airlie	}
9236baad55f157387d0bb44144680a96bc32280109fKeith Whitwell
924dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie	if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
925dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		if (!r600_enable_s3tc)
926dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			goto out_unknown;
927dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie
928dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		switch (format) {
929dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		case PIPE_FORMAT_RGTC1_SNORM:
930def6a91a62beb79956cb55805bff7d4c3e5461ecMarek Olšák		case PIPE_FORMAT_LATC1_SNORM:
931b2413de91682e3908d8ab1635956a290f603681cDave Airlie			word4 |= sign_bit[0];
932b2413de91682e3908d8ab1635956a290f603681cDave Airlie		case PIPE_FORMAT_RGTC1_UNORM:
933def6a91a62beb79956cb55805bff7d4c3e5461ecMarek Olšák		case PIPE_FORMAT_LATC1_UNORM:
934dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			result = FMT_BC4;
935dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			goto out_word4;
936dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		case PIPE_FORMAT_RGTC2_SNORM:
937def6a91a62beb79956cb55805bff7d4c3e5461ecMarek Olšák		case PIPE_FORMAT_LATC2_SNORM:
938b2413de91682e3908d8ab1635956a290f603681cDave Airlie			word4 |= sign_bit[0] | sign_bit[1];
939b2413de91682e3908d8ab1635956a290f603681cDave Airlie		case PIPE_FORMAT_RGTC2_UNORM:
940def6a91a62beb79956cb55805bff7d4c3e5461ecMarek Olšák		case PIPE_FORMAT_LATC2_UNORM:
941dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			result = FMT_BC5;
942dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			goto out_word4;
943dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		default:
944dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie			goto out_unknown;
945dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie		}
946dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie	}
947dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie
948dfa59284049e735cb55e1b39f32cfcfb71ebbff3Dave Airlie	if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
9496baad55f157387d0bb44144680a96bc32280109fKeith Whitwell
950119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		if (!r600_enable_s3tc)
951119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			goto out_unknown;
9526baad55f157387d0bb44144680a96bc32280109fKeith Whitwell
9538e0437914bb786d0b05be8f95e4ff37bf5a19f44Dave Airlie		if (!util_format_s3tc_enabled) {
9548e0437914bb786d0b05be8f95e4ff37bf5a19f44Dave Airlie			goto out_unknown;
9558e0437914bb786d0b05be8f95e4ff37bf5a19f44Dave Airlie		}
9568e0437914bb786d0b05be8f95e4ff37bf5a19f44Dave Airlie
957c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell		switch (format) {
958c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell		case PIPE_FORMAT_DXT1_RGB:
959c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell		case PIPE_FORMAT_DXT1_RGBA:
960632918d3ecd9756ad34098d28ed9eeda874d41a9Dave Airlie		case PIPE_FORMAT_DXT1_SRGB:
961632918d3ecd9756ad34098d28ed9eeda874d41a9Dave Airlie		case PIPE_FORMAT_DXT1_SRGBA:
962119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			result = FMT_BC1;
963a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie			is_srgb_valid = TRUE;
964119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			goto out_word4;
965c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell		case PIPE_FORMAT_DXT3_RGBA:
966632918d3ecd9756ad34098d28ed9eeda874d41a9Dave Airlie		case PIPE_FORMAT_DXT3_SRGBA:
967119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			result = FMT_BC2;
968a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie			is_srgb_valid = TRUE;
969119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			goto out_word4;
970c2c55547dc36f404e29dbc9253166f90df6783afKeith Whitwell		case PIPE_FORMAT_DXT5_RGBA:
971632918d3ecd9756ad34098d28ed9eeda874d41a9Dave Airlie		case PIPE_FORMAT_DXT5_SRGBA:
972119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			result = FMT_BC3;
973a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie			is_srgb_valid = TRUE;
974119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			goto out_word4;
975119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		default:
976119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse			goto out_unknown;
977119f00659c03c48cfab0f2770dd6b6fb89af31e4Jerome Glisse		}
978e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
979e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
980fb016854bc4327151e9eee3b7b08d0499976631aChristian König	if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
981fb016854bc4327151e9eee3b7b08d0499976631aChristian König		switch (format) {
982fb016854bc4327151e9eee3b7b08d0499976631aChristian König		case PIPE_FORMAT_R8G8_B8G8_UNORM:
983fb016854bc4327151e9eee3b7b08d0499976631aChristian König		case PIPE_FORMAT_G8R8_B8R8_UNORM:
984fb016854bc4327151e9eee3b7b08d0499976631aChristian König			result = FMT_GB_GR;
985fb016854bc4327151e9eee3b7b08d0499976631aChristian König			goto out_word4;
986fb016854bc4327151e9eee3b7b08d0499976631aChristian König		case PIPE_FORMAT_G8R8_G8B8_UNORM:
987fb016854bc4327151e9eee3b7b08d0499976631aChristian König		case PIPE_FORMAT_R8G8_R8B8_UNORM:
988fb016854bc4327151e9eee3b7b08d0499976631aChristian König			result = FMT_BG_RG;
989fb016854bc4327151e9eee3b7b08d0499976631aChristian König			goto out_word4;
990fb016854bc4327151e9eee3b7b08d0499976631aChristian König		default:
991fb016854bc4327151e9eee3b7b08d0499976631aChristian König			goto out_unknown;
992fb016854bc4327151e9eee3b7b08d0499976631aChristian König		}
993fb016854bc4327151e9eee3b7b08d0499976631aChristian König	}
994fb016854bc4327151e9eee3b7b08d0499976631aChristian König
995de9f55437ab7110dd79ebebaac543d35493380ceMarek Olšák	if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
996de9f55437ab7110dd79ebebaac543d35493380ceMarek Olšák		result = FMT_5_9_9_9_SHAREDEXP;
997de9f55437ab7110dd79ebebaac543d35493380ceMarek Olšák		goto out_word4;
9988b558451ad7560a53263f1848b5c826069aa8f51Marek Olšák	} else if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
9998b558451ad7560a53263f1848b5c826069aa8f51Marek Olšák		result = FMT_10_11_11_FLOAT;
10008b558451ad7560a53263f1848b5c826069aa8f51Marek Olšák		goto out_word4;
1001de9f55437ab7110dd79ebebaac543d35493380ceMarek Olšák	}
1002de9f55437ab7110dd79ebebaac543d35493380ceMarek Olšák
1003e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
10049e964baaf34fedec385a750b97fd6684fc52584aHenri Verbeet	for (i = 0; i < desc->nr_channels; i++) {
1005e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
1006e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			word4 |= sign_bit[i];
1007e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
1008e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
1009e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
1010370c8b5ee7666f4f515d63603afe8282b1b3c682Marek Olšák	/* R8G8Bx_SNORM - XXX CxV8U8 */
1011e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
1012e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	/* See whether the components are of the same size. */
1013e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	for (i = 1; i < desc->nr_channels; i++) {
1014e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		uniform = uniform && desc->channel[0].size == desc->channel[i].size;
1015e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
10169e964baaf34fedec385a750b97fd6684fc52584aHenri Verbeet
1017e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	/* Non-uniform formats. */
1018e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	if (!uniform) {
1019d38768fe3882ac4bc29d4cb7aca975f20c981c0cDave Airlie		if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
1020d38768fe3882ac4bc29d4cb7aca975f20c981c0cDave Airlie		    desc->channel[0].pure_integer)
1021d38768fe3882ac4bc29d4cb7aca975f20c981c0cDave Airlie			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
1022e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		switch(desc->nr_channels) {
1023e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 3:
1024e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			if (desc->channel[0].size == 5 &&
1025e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[1].size == 6 &&
1026e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[2].size == 5) {
102782114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_5_6_5;
1028e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1029e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1030e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1031e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 4:
1032e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			if (desc->channel[0].size == 5 &&
1033e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[1].size == 5 &&
1034e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[2].size == 5 &&
1035e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[3].size == 1) {
103682114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_1_5_5_5;
1037e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1038e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1039e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			if (desc->channel[0].size == 10 &&
1040e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[1].size == 10 &&
1041e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[2].size == 10 &&
1042e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			    desc->channel[3].size == 2) {
1043065c8696e7b8290f9361ae88b8a7d99be9e2d0efDave Airlie				result = FMT_2_10_10_10;
1044e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1045e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1046e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1047e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
1048e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		goto out_unknown;
1049e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
1050e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
1051534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie	/* Find the first non-VOID channel. */
1052534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie	for (i = 0; i < 4; i++) {
1053534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
1054534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie			break;
1055534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		}
1056534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie	}
1057534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie
1058534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie	if (i == 4)
1059534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		goto out_unknown;
1060534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie
1061e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	/* uniform formats */
1062534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie	switch (desc->channel[i].type) {
1063e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_TYPE_UNSIGNED:
1064e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_TYPE_SIGNED:
1065f2bae9456f141f8c1104ef2a0aab31f6190ae5f0Dave Airlie#if 0
1066534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		if (!desc->channel[i].normalized &&
1067e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		    desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
1068e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1069e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
1070f2bae9456f141f8c1104ef2a0aab31f6190ae5f0Dave Airlie#endif
1071f2bae9456f141f8c1104ef2a0aab31f6190ae5f0Dave Airlie		if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
10720110aa09e5898987ee86586e438ac571075eba3aDave Airlie		    desc->channel[i].pure_integer)
1073f2bae9456f141f8c1104ef2a0aab31f6190ae5f0Dave Airlie			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
1074e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
1075534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		switch (desc->channel[i].size) {
1076e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 4:
1077e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			switch (desc->nr_channels) {
1078e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 2:
107982114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_4_4;
1080e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1081e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 4:
108282114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_4_4_4_4;
1083e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1084e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1085e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1086e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 8:
1087e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			switch (desc->nr_channels) {
1088e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 1:
108982114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_8;
1090e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1091e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 2:
109282114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_8_8;
1093e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1094e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 4:
109582114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_8_8_8_8;
1096a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie				is_srgb_valid = TRUE;
1097e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1098e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1099e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1100e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 16:
1101e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			switch (desc->nr_channels) {
1102e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 1:
110382114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16;
1104e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1105e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 2:
110682114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16_16;
1107e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1108e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 4:
110982114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16_16_16_16;
1110e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1111e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
11120d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			goto out_unknown;
11130d851f6e9c6046052ddce3860e625537832530a0Dave Airlie		case 32:
11140d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			switch (desc->nr_channels) {
11150d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			case 1:
11160d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				result = FMT_32;
11170d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				goto out_word4;
11180d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			case 2:
11190d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				result = FMT_32_32;
11200d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				goto out_word4;
11210d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			case 4:
11220d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				result = FMT_32_32_32_32;
11230d851f6e9c6046052ddce3860e625537832530a0Dave Airlie				goto out_word4;
11240d851f6e9c6046052ddce3860e625537832530a0Dave Airlie			}
1125e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
1126e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		goto out_unknown;
1127e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie
1128e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	case UTIL_FORMAT_TYPE_FLOAT:
1129534f7d5749e34003fc9a0a4c83e6cd6f86a1c2cbDave Airlie		switch (desc->channel[i].size) {
1130e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 16:
1131e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			switch (desc->nr_channels) {
1132e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 1:
113382114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16_FLOAT;
1134e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1135e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 2:
113682114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16_16_FLOAT;
1137e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1138e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 4:
113982114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_16_16_16_16_FLOAT;
1140e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1141e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1142e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			goto out_unknown;
1143e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		case 32:
1144e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			switch (desc->nr_channels) {
1145e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 1:
114682114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_32_FLOAT;
1147e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1148e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 2:
114982114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_32_32_FLOAT;
1150e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1151e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			case 4:
115282114ac02a2d5a764ce69711fc0a71f559ee9137Dave Airlie				result = FMT_32_32_32_32_FLOAT;
1153e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie				goto out_word4;
1154e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie			}
1155e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		}
11567d488ade239652d67f78a79bbd9712e4690591cbMarek Olšák		goto out_unknown;
1157e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	}
11587d488ade239652d67f78a79bbd9712e4690591cbMarek Olšák
1159e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlieout_word4:
1160a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie
1161a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid)
1162a9d8809f16feb7f6d5d723f2afa2cfbea60cae55Dave Airlie		return ~0;
1163e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	if (word4_p)
1164e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		*word4_p = word4;
1165e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	if (yuv_format_p)
1166e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie		*yuv_format_p = yuv_format;
1167e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	return result;
1168e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlieout_unknown:
1169b2a98c3531c276b76024bb9b10fdd6c3360cb0c9Henri Verbeet	/* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */
1170e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie	return ~0;
1171e2df0a8b234efde140b340c2c9b67b06b789b758Dave Airlie}
1172