r600_texture.c revision 8e0437914bb786d0b05be8f95e4ff37bf5a19f44
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"),
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to deal in the Software without restriction, including without limitation
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the rights to use, copy, modify, merge, publish, distribute, sub
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license, and/or sell copies of the Software, and to permit persons to whom
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Software is furnished to do so, subject to the following conditions:
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the next
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * paragraph) shall be included in all copies or substantial portions of the
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Software.
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *
155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * USE OR OTHER DEALINGS IN THE SOFTWARE.
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Authors:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Jerome Glisse
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      Corbin Simpson
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include <pipe/p_screen.h>
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <util/u_format.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <util/u_format_s3tc.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <util/u_math.h>
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <util/u_inlines.h>
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <util/u_memory.h>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "state_tracker/drm_driver.h"
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "pipebuffer/pb_buffer.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "r600_pipe.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "r600_resource.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "r600_state_inlines.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "r600d.h"
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "r600_formats.h"
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* Copy from a full GPU texture to a transfer's staging one. */
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct pipe_resource *texture = transfer->resource;
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	ctx->resource_copy_region(ctx, rtransfer->staging_texture,
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				0, 0, 0, 0, texture, transfer->level,
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				&transfer->box);
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* Copy from a transfer's staging texture to a full GPU one. */
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct pipe_resource *texture = transfer->resource;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct pipe_box sbox;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	sbox.x = sbox.y = sbox.z = 0;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	sbox.width = transfer->box.width;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	sbox.height = transfer->box.height;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	/* XXX that might be wrong */
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	sbox.depth = 1;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ctx->resource_copy_region(ctx, texture, transfer->level,
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				  transfer->box.x, transfer->box.y, transfer->box.z,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				  rtransfer->staging_texture,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				  0, &sbox);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ctx->flush(ctx, 0, NULL);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					unsigned level, unsigned layer)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	unsigned offset = rtex->offset[level];
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	switch (rtex->resource.b.b.b.target) {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case PIPE_TEXTURE_3D:
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case PIPE_TEXTURE_CUBE:
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		return offset + layer * rtex->layer_size[level];
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	default:
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		assert(layer == 0);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		return offset;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static unsigned r600_get_block_alignment(struct pipe_screen *screen,
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					 enum pipe_format format,
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					 unsigned array_mode)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct r600_screen* rscreen = (struct r600_screen *)screen;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	unsigned pixsize = util_format_get_blocksize(format);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int p_align;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	switch(array_mode) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_1D_TILED_THIN1:
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		p_align = MAX2(8,
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			       ((rscreen->tiling_info->group_bytes / 8 / pixsize)));
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_2D_TILED_THIN1:
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		p_align = MAX2(rscreen->tiling_info->num_banks,
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			       (((rscreen->tiling_info->group_bytes / 8 / pixsize)) *
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				rscreen->tiling_info->num_banks)) * 8;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_ALIGNED:
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		p_align = MAX2(64, rscreen->tiling_info->group_bytes / pixsize);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_GENERAL:
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	default:
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		p_align = rscreen->tiling_info->group_bytes / pixsize;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	return p_align;
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static unsigned r600_get_height_alignment(struct pipe_screen *screen,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					  unsigned array_mode)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct r600_screen* rscreen = (struct r600_screen *)screen;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int h_align;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	switch (array_mode) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_2D_TILED_THIN1:
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		h_align = rscreen->tiling_info->num_channels * 8;
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_1D_TILED_THIN1:
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_ALIGNED:
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		h_align = 8;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_GENERAL:
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	default:
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		h_align = 1;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	return h_align;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static unsigned r600_get_base_alignment(struct pipe_screen *screen,
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					enum pipe_format format,
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					unsigned array_mode)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	struct r600_screen* rscreen = (struct r600_screen *)screen;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	unsigned pixsize = util_format_get_blocksize(format);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int p_align = r600_get_block_alignment(screen, format, array_mode);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int h_align = r600_get_height_alignment(screen, array_mode);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int b_align;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	switch (array_mode) {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_2D_TILED_THIN1:
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		b_align = MAX2(rscreen->tiling_info->num_banks * rscreen->tiling_info->num_channels * 8 * 8 * pixsize,
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			       p_align * pixsize * h_align);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_1D_TILED_THIN1:
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_ALIGNED:
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	case V_038000_ARRAY_LINEAR_GENERAL:
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	default:
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		b_align = rscreen->tiling_info->group_bytes;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		break;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	}
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return b_align;
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static unsigned mip_minify(unsigned size, unsigned level)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	unsigned val;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	val = u_minify(size, level);
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (level > 0)
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		val = util_next_power_of_two(val);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return val;
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static unsigned r600_texture_get_nblocksx(struct pipe_screen *screen,
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					  struct r600_resource_texture *rtex,
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)					  unsigned level)
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	struct pipe_resource *ptex = &rtex->resource.b.b.b;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	unsigned nblocksx, block_align, width;
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	unsigned blocksize = util_format_get_blocksize(ptex->format);
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (rtex->pitch_override)
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		return rtex->pitch_override / blocksize;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	width = mip_minify(ptex->width0, level);
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	nblocksx = util_format_get_nblocksx(ptex->format, width);
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	block_align = r600_get_block_alignment(screen, ptex->format,
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					      rtex->array_mode[level]);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	nblocksx = align(nblocksx, block_align);
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return nblocksx;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static unsigned r600_texture_get_nblocksy(struct pipe_screen *screen,
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					  struct r600_resource_texture *rtex,
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					  unsigned level)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	struct pipe_resource *ptex = &rtex->resource.b.b.b;
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	unsigned height, tile_height;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	height = mip_minify(ptex->height0, level);
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	height = util_format_get_nblocksy(ptex->format, height);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tile_height = r600_get_height_alignment(screen,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						rtex->array_mode[level]);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	height = align(height, tile_height);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return height;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void r600_texture_set_array_mode(struct pipe_screen *screen,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					struct r600_resource_texture *rtex,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					unsigned level, unsigned array_mode)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct pipe_resource *ptex = &rtex->resource.b.b.b;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (array_mode) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case V_0280A0_ARRAY_LINEAR_GENERAL:
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case V_0280A0_ARRAY_LINEAR_ALIGNED:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case V_0280A0_ARRAY_1D_TILED_THIN1:
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	default:
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		rtex->array_mode[level] = array_mode;
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		break;
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	case V_0280A0_ARRAY_2D_TILED_THIN1:
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	{
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		unsigned w, h, tile_height, tile_width;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tile_height = r600_get_height_alignment(screen, array_mode);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tile_width = r600_get_block_alignment(screen, ptex->format, array_mode);
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		w = mip_minify(ptex->width0, level);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		h = mip_minify(ptex->height0, level);
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		if (w < tile_width || h < tile_height)
232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			rtex->array_mode[level] = V_0280A0_ARRAY_1D_TILED_THIN1;
233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		else
234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			rtex->array_mode[level] = array_mode;
235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	}
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	break;
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	}
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic void r600_setup_miptree(struct pipe_screen *screen,
241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch			       struct r600_resource_texture *rtex,
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch			       unsigned array_mode)
243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	struct pipe_resource *ptex = &rtex->resource.b.b.b;
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	struct radeon *radeon = (struct radeon *)screen->winsys;
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	enum chip_class chipc = r600_get_family_class(radeon);
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	unsigned size, layer_size, i, offset;
248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	unsigned nblocksx, nblocksy;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)	for (i = 0, offset = 0; i <= ptex->last_level; i++) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned blocksize = util_format_get_blocksize(ptex->format);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		r600_texture_set_array_mode(screen, rtex, i, array_mode);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nblocksx = r600_texture_get_nblocksx(screen, rtex, i);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		nblocksy = r600_texture_get_nblocksy(screen, rtex, i);
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		layer_size = nblocksx * nblocksy * blocksize;
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		if (ptex->target == PIPE_TEXTURE_CUBE) {
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch			if (chipc >= R700)
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch				size = layer_size * 8;
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			else
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				size = layer_size * 6;
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			size = layer_size * u_minify(ptex->depth0, i);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* align base image and start of miptree */
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((i == 0) || (i == 1))
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rtex->offset[i] = offset;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rtex->layer_size[i] = layer_size;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rtex->pitch_in_bytes[i] = nblocksx * blocksize;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		offset += size;
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	rtex->size = offset;
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/* Figure out whether u_blitter will fallback to a transfer operation.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If so, don't use a staging resource.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static boolean permit_hardware_blit(struct pipe_screen *screen,
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)					const struct pipe_resource *res)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	unsigned bind;
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)	if (util_format_is_depth_or_stencil(res->format))
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		bind = PIPE_BIND_DEPTH_STENCIL;
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	else
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bind = PIPE_BIND_RENDER_TARGET;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* hackaround for S3TC */
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (util_format_is_s3tc(res->format))
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		return TRUE;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	if (!screen->is_format_supported(screen,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				res->format,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				res->target,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				res->nr_samples,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				bind, 0))
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return FALSE;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	if (!screen->is_format_supported(screen,
30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)				res->format,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				res->target,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				res->nr_samples,
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch				PIPE_BIND_SAMPLER_VIEW, 0))
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch		return FALSE;
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	return TRUE;
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic boolean r600_texture_get_handle(struct pipe_screen* screen,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					struct pipe_resource *ptex,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					struct winsys_handle *whandle)
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource *resource = &rtex->resource;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct radeon *radeon = (struct radeon *)screen->winsys;
321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	return r600_bo_get_winsys_handle(radeon, resource->bo,
323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			rtex->pitch_in_bytes[0], whandle);
324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static void r600_texture_destroy(struct pipe_screen *screen,
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				 struct pipe_resource *ptex)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource *resource = &rtex->resource;
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	struct radeon *radeon = (struct radeon *)screen->winsys;
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex->flushed_depth_texture)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	if (resource->bo) {
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		r600_bo_reference(radeon, &resource->bo, NULL);
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	FREE(rtex);
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static unsigned int r600_texture_is_referenced(struct pipe_context *context,
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)						struct pipe_resource *texture,
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)						unsigned level, int layer)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	/* FIXME */
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static const struct u_resource_vtbl r600_texture_vtbl =
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles){
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	r600_texture_get_handle,	/* get_handle */
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_texture_destroy,		/* resource_destroy */
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_texture_is_referenced,	/* is_resource_referenced */
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_texture_get_transfer,	/* get_transfer */
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_texture_transfer_destroy,	/* transfer_destroy */
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	r600_texture_transfer_map,	/* transfer_map */
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u_default_transfer_flush_region,/* transfer_flush_region */
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_texture_transfer_unmap,	/* transfer_unmap */
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u_default_transfer_inline_write	/* transfer_inline_write */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct r600_resource_texture *
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)r600_texture_create_object(struct pipe_screen *screen,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   const struct pipe_resource *base,
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			   unsigned array_mode,
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			   unsigned pitch_in_bytes_override,
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			   unsigned max_buffer_size,
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			   struct r600_bo *bo)
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct r600_resource_texture *rtex;
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct r600_resource *resource;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct radeon *radeon = (struct radeon *)screen->winsys;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rtex = CALLOC_STRUCT(r600_resource_texture);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex == NULL)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource = &rtex->resource;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource->b.b.b = *base;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource->b.b.vtbl = &r600_texture_vtbl;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pipe_reference_init(&resource->b.b.b.reference, 1);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource->b.b.b.screen = screen;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource->bo = bo;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rtex->pitch_override = pitch_in_bytes_override;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* only mark depth textures the HW can hit as depth textures */
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (util_format_is_depth_or_stencil(base->format) && permit_hardware_blit(screen, base))
3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		rtex->depth = 1;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_setup_miptree(screen, rtex, array_mode);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource->size = rtex->size;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!resource->bo) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct pipe_resource *ptex = &rtex->resource.b.b.b;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!resource->bo) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			FREE(rtex);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return NULL;
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		}
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	return rtex;
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstruct pipe_resource *r600_texture_create(struct pipe_screen *screen,
408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch						const struct pipe_resource *templ)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	unsigned array_mode = 0;
411effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	static int force_tiling = -1;
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Would like some magic "get_bool_option_once" routine.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (force_tiling == -1)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (force_tiling && permit_hardware_blit(screen, templ)) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    !(templ->bind & PIPE_BIND_SCANOUT)) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    util_format_is_s3tc(templ->format))
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		array_mode = V_038000_ARRAY_1D_TILED_THIN1;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)								  0, 0, NULL);
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)						struct pipe_resource *texture,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						const struct pipe_surface *surf_tmpl)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
4395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
4405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	unsigned level = surf_tmpl->u.tex.level;
4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
4425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
4435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	if (surface == NULL)
4445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu		return NULL;
4455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	/* XXX no offset */
4465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/*	offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
4475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	pipe_reference_init(&surface->base.reference, 1);
4485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	pipe_resource_reference(&surface->base.texture, texture);
4495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	surface->base.context = pipe;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.format = surf_tmpl->format;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.width = mip_minify(texture->width0, level);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.height = mip_minify(texture->height0, level);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.usage = surf_tmpl->usage;
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	surface->base.texture = texture;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->base.u.tex.level = level;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	surface->aligned_height = r600_texture_get_nblocksy(pipe->screen,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							    rtex, level);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return &surface->base;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void r600_surface_destroy(struct pipe_context *pipe,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 struct pipe_surface *surface)
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	pipe_resource_reference(&surface->texture, NULL);
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	FREE(surface);
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)					       const struct pipe_resource *templ,
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)					       struct winsys_handle *whandle)
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct radeon *rw = (struct radeon*)screen->winsys;
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	struct r600_bo *bo = NULL;
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	unsigned array_mode = 0;
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	/* Support only 2D textures without mipmaps */
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	      templ->depth0 != 1 || templ->last_level != 0)
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		return NULL;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bo = r600_bo_handle(rw, whandle->handle, &array_mode);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (bo == NULL) {
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		return NULL;
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)								  whandle->stride,
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)								  0,
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)								  bo);
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint r600_texture_depth_flush(struct pipe_context *ctx,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     struct pipe_resource *texture, boolean just_create)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct pipe_resource resource;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex->flushed_depth_texture)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.target = PIPE_TEXTURE_2D;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.format = texture->format;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.width0 = texture->width0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.height0 = texture->height0;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.depth0 = 1;
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	resource.last_level = texture->last_level;
511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	resource.nr_samples = 0;
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	resource.usage = PIPE_USAGE_DYNAMIC;
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	resource.bind = 0;
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	resource.flags = R600_RESOURCE_FLAG_TRANSFER;
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	resource.bind |= PIPE_BIND_DEPTH_STENCIL;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex->flushed_depth_texture == NULL) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		R600_ERR("failed to create temporary texture to hold untiled copy\n");
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return -ENOMEM;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)out:
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (just_create)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return 0;
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XXX: only do this if the depth texture has actually changed:
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_blit_uncompress_depth(ctx, rtex);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* Needs adjustment for pixelformat:
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
5370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic INLINE unsigned u_box_volume( const struct pipe_box *box )
5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch{
5390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch	return box->width * box->depth * box->height;
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)						struct pipe_resource *texture,
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)						unsigned level,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						unsigned usage,
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)						const struct pipe_box *box)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct pipe_resource resource;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_transfer *trans;
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	int r;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	boolean use_staging_texture = FALSE;
553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* We cannot map a tiled texture directly because the data is
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in a different order, therefore we do detiling using a blit.
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 *
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * Also, use a temporary in GTT memory for read transfers, as
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * the CPU is much happier reading out of cached system memory
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * than uncached VRAM.
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 */
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (R600_TEX_IS_TILED(rtex, level))
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		use_staging_texture = TRUE;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		use_staging_texture = TRUE;
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	/* XXX: Use a staging texture for uploads if the underlying BO
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * is busy.  No interface for checking that currently? so do
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * it eagerly whenever the transfer doesn't require a readback
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * and might block.
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 */
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if ((usage & PIPE_TRANSFER_WRITE) &&
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			!(usage & (PIPE_TRANSFER_READ |
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					PIPE_TRANSFER_DONTBLOCK |
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					PIPE_TRANSFER_UNSYNCHRONIZED)))
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		use_staging_texture = TRUE;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (!permit_hardware_blit(ctx->screen, texture) ||
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		(texture->flags & R600_RESOURCE_FLAG_TRANSFER))
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		use_staging_texture = FALSE;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	trans = CALLOC_STRUCT(r600_transfer);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (trans == NULL)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pipe_resource_reference(&trans->transfer.resource, texture);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	trans->transfer.level = level;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	trans->transfer.usage = usage;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	trans->transfer.box = *box;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex->depth) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* XXX: only readback the rectangle which is being mapped?
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*/
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* XXX: when discard is true, no need to read back from depth texture
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*/
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		r = r600_texture_depth_flush(ctx, texture, FALSE);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (r < 0) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			R600_ERR("failed to create temporary texture to hold untiled copy\n");
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pipe_resource_reference(&trans->transfer.resource, NULL);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			FREE(trans);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return NULL;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level];
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return &trans->transfer;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (use_staging_texture) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		resource.target = PIPE_TEXTURE_2D;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		resource.format = texture->format;
6071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		resource.width0 = box->width;
608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		resource.height0 = box->height;
609effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		resource.depth0 = 1;
610effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		resource.array_size = 1;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		resource.last_level = 0;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		resource.nr_samples = 0;
6131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		resource.usage = PIPE_USAGE_STAGING;
614effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		resource.bind = 0;
615effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		resource.flags = R600_RESOURCE_FLAG_TRANSFER;
616effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		/* For texture reading, the temporary (detiled) texture is used as
617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		 * a render target when blitting from a tiled texture. */
618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (usage & PIPE_TRANSFER_READ) {
619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			resource.bind |= PIPE_BIND_RENDER_TARGET;
620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		/* For texture writing, the temporary texture is used as a sampler
622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		 * when blitting into a tiled texture. */
623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (usage & PIPE_TRANSFER_WRITE) {
624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			resource.bind |= PIPE_BIND_SAMPLER_VIEW;
625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		/* Create the temporary texture. */
627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (trans->staging_texture == NULL) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			R600_ERR("failed to create temporary texture to hold untiled copy\n");
630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			pipe_resource_reference(&trans->transfer.resource, NULL);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			FREE(trans);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return NULL;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
634effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
635effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		trans->transfer.stride =
636effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
637effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		if (usage & PIPE_TRANSFER_READ) {
638effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			r600_copy_to_staging_texture(ctx, trans);
639effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			/* Always referenced in the blit. */
640effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			ctx->flush(ctx, 0, NULL);
641effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		}
642effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch		return &trans->transfer;
643effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	trans->transfer.stride = rtex->pitch_in_bytes[level];
6451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	trans->offset = r600_texture_get_offset(rtex, level, box->z);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return &trans->transfer;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void r600_texture_transfer_destroy(struct pipe_context *ctx,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   struct pipe_transfer *transfer)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct pipe_resource *texture = transfer->resource;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtransfer->staging_texture) {
65746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		if (transfer->usage & PIPE_TRANSFER_WRITE) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			r600_copy_from_staging_texture(ctx, rtransfer);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pipe_resource_reference(&rtransfer->staging_texture, NULL);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
66246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtex->depth && !rtex->is_flushing_texture) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			r600_blit_push_depth(ctx, rtex);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pipe_resource_reference(&transfer->resource, NULL);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	FREE(transfer);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* r600_texture_transfer_map(struct pipe_context *ctx,
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				struct pipe_transfer* transfer)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_bo *bo;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	enum pipe_format format = transfer->resource->format;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned offset = 0;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned usage = 0;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char *map;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtransfer->staging_texture) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bo = ((struct r600_resource *)rtransfer->staging_texture)->bo;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rtex->flushed_depth_texture)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			bo = ((struct r600_resource *)transfer->resource)->bo;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		offset = rtransfer->offset +
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (transfer->usage & PIPE_TRANSFER_WRITE) {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		usage |= PB_USAGE_CPU_WRITE;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		if (transfer->usage & PIPE_TRANSFER_DISCARD) {
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		}
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (transfer->usage & PIPE_TRANSFER_READ) {
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		usage |= PB_USAGE_CPU_READ;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		usage |= PB_USAGE_DONTBLOCK;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		usage |= PB_USAGE_UNSYNCHRONIZED;
718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	}
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	map = r600_bo_map(radeon, bo, usage, ctx);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!map) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return map + offset;
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void r600_texture_transfer_unmap(struct pipe_context *ctx,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 struct pipe_transfer* transfer)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct r600_bo *bo;
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rtransfer->staging_texture) {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bo = ((struct r600_resource *)rtransfer->staging_texture)->bo;
737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	} else {
738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rtex->flushed_depth_texture) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			bo = ((struct r600_resource *)transfer->resource)->bo;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600_bo_unmap(radeon, bo);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void r600_init_surface_functions(struct r600_pipe_context *r600)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600->context.create_surface = r600_create_surface;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	r600->context.surface_destroy = r600_surface_destroy;
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch		const unsigned char *swizzle_view)
757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch{
758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	unsigned i;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char swizzle[4];
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned result = 0;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const uint32_t swizzle_shift[4] = {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		16, 19, 22, 25,
7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const uint32_t swizzle_bit[4] = {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		0, 1, 2, 3,
766116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	};
767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch	if (swizzle_view) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Combine two sets of swizzles. */
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (i = 0; i < 4; i++) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				swizzle_format[swizzle_view[i]] : swizzle_view[i];
7731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		}
7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	} else {
7751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		memcpy(swizzle, swizzle_format, 4);
7761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get swizzle. */
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < 4; i++) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (swizzle[i]) {
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		case UTIL_FORMAT_SWIZZLE_Y:
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			result |= swizzle_bit[1] << swizzle_shift[i];
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case UTIL_FORMAT_SWIZZLE_Z:
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result |= swizzle_bit[2] << swizzle_shift[i];
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case UTIL_FORMAT_SWIZZLE_W:
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result |= swizzle_bit[3] << swizzle_shift[i];
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case UTIL_FORMAT_SWIZZLE_0:
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case UTIL_FORMAT_SWIZZLE_1:
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default: /* UTIL_FORMAT_SWIZZLE_X */
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			result |= swizzle_bit[0] << swizzle_shift[i];
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return result;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* texture format translate */
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint32_t r600_translate_texformat(enum pipe_format format,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  const unsigned char *swizzle_view,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  uint32_t *word4_p, uint32_t *yuv_format_p)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	uint32_t result = 0, word4 = 0, yuv_format = 0;
809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	const struct util_format_description *desc;
810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	boolean uniform = TRUE;
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	int i;
812a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	const uint32_t sign_bit[4] = {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	};
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	desc = util_format_description(format);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Colorspace (return non-RGB formats directly). */
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (desc->colorspace) {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Depth stencil formats */
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case UTIL_FORMAT_COLORSPACE_ZS:
8268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		switch (format) {
8278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_Z16_UNORM:
8288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			result = FMT_16;
8298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			goto out_word4;
8308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_X24S8_USCALED:
8318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
8328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_Z24X8_UNORM:
8338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
8348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			result = FMT_8_24;
8358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			goto out_word4;
8368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_S8X24_USCALED:
8378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
8388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_X8Z24_UNORM:
8398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
8408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			result = FMT_24_8;
8418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)			goto out_word4;
8428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)		case PIPE_FORMAT_S8_USCALED:
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result = FMT_8;
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_word4;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case UTIL_FORMAT_COLORSPACE_YUV:
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		yuv_format |= (1 << 30);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (format) {
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case PIPE_FORMAT_UYVY:
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case PIPE_FORMAT_YUYV:
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out_unknown; /* TODO */
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case UTIL_FORMAT_COLORSPACE_SRGB:
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		word4 |= S_038010_FORCE_DEGAMMA(1);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (format == PIPE_FORMAT_L8A8_SRGB || format == PIPE_FORMAT_L8_SRGB)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown; /* fails for some reason - TODO */
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* S3TC formats. TODO */
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		static int r600_enable_s3tc = -1;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (r600_enable_s3tc == -1)
875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			r600_enable_s3tc =
876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)				debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (!r600_enable_s3tc)
879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			goto out_unknown;
880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		if (!util_format_s3tc_enabled) {
882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			goto out_unknown;
883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		}
884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		switch (format) {
886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		case PIPE_FORMAT_DXT1_RGB:
887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		case PIPE_FORMAT_DXT1_RGBA:
888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			result = FMT_BC1;
889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			goto out_word4;
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case PIPE_FORMAT_DXT3_RGBA:
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result = FMT_BC2;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_word4;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case PIPE_FORMAT_DXT5_RGBA:
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			result = FMT_BC3;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_word4;
896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		default:
897a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			goto out_unknown;
898a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
899a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	for (i = 0; i < desc->nr_channels; i++) {
903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			word4 |= sign_bit[i];
905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
907a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	/* R8G8Bx_SNORM - TODO CxV8U8 */
909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
910a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	/* RGTC - TODO */
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* See whether the components are of the same size. */
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 1; i < desc->nr_channels; i++) {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		uniform = uniform && desc->channel[0].size == desc->channel[i].size;
915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	}
916effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Non-uniform formats. */
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!uniform) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch(desc->nr_channels) {
920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		case 3:
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			if (desc->channel[0].size == 5 &&
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    desc->channel[1].size == 6 &&
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    desc->channel[2].size == 5) {
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				result = FMT_5_6_5;
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				goto out_word4;
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			}
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			goto out_unknown;
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		case 4:
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			if (desc->channel[0].size == 5 &&
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			    desc->channel[1].size == 5 &&
931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			    desc->channel[2].size == 5 &&
932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)			    desc->channel[3].size == 1) {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_1_5_5_5;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			}
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			if (desc->channel[0].size == 10 &&
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			    desc->channel[1].size == 10 &&
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    desc->channel[2].size == 10 &&
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    desc->channel[3].size == 2) {
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_2_10_10_10;
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				goto out_word4;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out_unknown;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	/* Find the first non-VOID channel. */
949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	for (i = 0; i < 4; i++) {
950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			break;
952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
955a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	if (i == 4)
956a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		goto out_unknown;
957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	/* uniform formats */
959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	switch (desc->channel[i].type) {
960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	case UTIL_FORMAT_TYPE_UNSIGNED:
961a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	case UTIL_FORMAT_TYPE_SIGNED:
962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		if (!desc->channel[i].normalized &&
963a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		    desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
964a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			goto out_unknown;
965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		}
966a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
967a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		switch (desc->channel[i].size) {
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 4:
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_4_4;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 4:
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_4_4_4_4;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 8:
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 1:
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_8;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_8_8;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 4:
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_8_8_8_8;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 16:
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 1:
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_16;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_16_16;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 4:
10007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch				result = FMT_16_16_16_16;
10017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch				goto out_word4;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto out_unknown;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 32:
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
10067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch			case 1:
1007a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				result = FMT_32;
10087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch				goto out_word4;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_32_32;
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 4:
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_32_32_32_32;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out_unknown;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case UTIL_FORMAT_TYPE_FLOAT:
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (desc->channel[i].size) {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 16:
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 1:
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				result = FMT_16_FLOAT;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
10271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				result = FMT_16_16_FLOAT;
10281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				goto out_word4;
1029effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch			case 4:
1030effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch				result = FMT_16_16_16_16_FLOAT;
1031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				goto out_word4;
1032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			}
1033a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			goto out_unknown;
1034a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		case 32:
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			switch (desc->nr_channels) {
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			case 1:
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				result = FMT_32_FLOAT;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 2:
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				result = FMT_32_32_FLOAT;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto out_word4;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case 4:
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				result = FMT_32_32_32_32_FLOAT;
1044a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				goto out_word4;
1045a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			}
1046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)		}
1047a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1048a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	}
1049a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)out_word4:
1050a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	if (word4_p)
1051a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		*word4_p = word4;
1052a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	if (yuv_format_p)
1053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		*yuv_format_p = yuv_format;
1054a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	return result;
1055a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)out_unknown:
1056a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//	R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
1057a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	return ~0;
1058a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1059a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)