r600_texture.c revision 2a311b18fce9ea6538b0997ad23d86a061fb273c
1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* 2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Permission is hereby granted, free of charge, to any person obtaining a 5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * copy of this software and associated documentation files (the "Software"), 6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * to deal in the Software without restriction, including without limitation 7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * on the rights to use, copy, modify, merge, publish, distribute, sub 8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * license, and/or sell copies of the Software, and to permit persons to whom 9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the Software is furnished to do so, subject to the following conditions: 10a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * The above copyright notice and this permission notice (including the next 12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * paragraph) shall be included in all copies or substantial portions of the 13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Software. 14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * USE OR OTHER DEALINGS IN THE SOFTWARE. 22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Authors: 24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Jerome Glisse 25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Corbin Simpson 26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <errno.h> 28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "pipe/p_screen.h" 29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_format.h" 30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_format_s3tc.h" 31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_math.h" 32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_inlines.h" 33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_memory.h" 34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "pipebuffer/pb_buffer.h" 35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeonsi_pipe.h" 36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "r600_resource.h" 37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "sid.h" 38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Copy from a full GPU texture to a transfer's staging one. */ 40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) 41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; 43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture = transfer->resource; 44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ctx->resource_copy_region(ctx, rtransfer->staging_texture, 46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 0, 0, 0, 0, texture, transfer->level, 47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard &transfer->box); 48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Copy from a transfer's staging texture to a full GPU one. */ 52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) 53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; 55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture = transfer->resource; 56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_box sbox; 57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard sbox.x = sbox.y = sbox.z = 0; 59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard sbox.width = transfer->box.width; 60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard sbox.height = transfer->box.height; 61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX that might be wrong */ 62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard sbox.depth = 1; 63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ctx->resource_copy_region(ctx, texture, transfer->level, 64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard transfer->box.x, transfer->box.y, transfer->box.z, 65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtransfer->staging_texture, 66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 0, &sbox); 67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardunsigned r600_texture_get_offset(struct r600_resource_texture *rtex, 70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level, unsigned layer) 71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned offset = rtex->offset[level]; 73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 742a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák switch (rtex->resource.b.b.target) { 75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_TEXTURE_3D: 76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_TEXTURE_CUBE: 77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return offset + layer * rtex->layer_size[level]; 79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_block_alignment(struct pipe_screen *screen, 83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum pipe_format format, 84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode) 85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen* rscreen = (struct r600_screen *)screen; 87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned pixsize = util_format_get_blocksize(format); 88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int p_align; 89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch(array_mode) { 91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_1D_TILED_THIN1: 93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard p_align = MAX2(8, 94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ((rscreen->tiling_info.group_bytes / 8 / pixsize))); 95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_2D_TILED_THIN1: 97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard p_align = MAX2(rscreen->tiling_info.num_banks, 98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard (((rscreen->tiling_info.group_bytes / 8 / pixsize)) * 99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rscreen->tiling_info.num_banks)) * 8; 100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_ALIGNED: 102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); 103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_GENERAL: 105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard p_align = rscreen->tiling_info.group_bytes / pixsize; 108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return p_align; 111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 113a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_height_alignment(struct pipe_screen *screen, 114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode) 115a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 116a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen* rscreen = (struct r600_screen *)screen; 117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int h_align; 118a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (array_mode) { 120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_2D_TILED_THIN1: 122a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard h_align = rscreen->tiling_info.num_channels * 8; 123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_1D_TILED_THIN1: 125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_ALIGNED: 126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard h_align = 8; 127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_GENERAL: 129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard h_align = 1; 132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return h_align; 135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_get_base_alignment(struct pipe_screen *screen, 138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum pipe_format format, 139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode) 140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen* rscreen = (struct r600_screen *)screen; 142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned pixsize = util_format_get_blocksize(format); 143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int p_align = r600_get_block_alignment(screen, format, array_mode); 144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int h_align = r600_get_height_alignment(screen, array_mode); 145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int b_align; 146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (array_mode) { 148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_2D_TILED_THIN1: 150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels * 8 * 8 * pixsize, 151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard p_align * pixsize * h_align); 152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_1D_TILED_THIN1: 154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_ALIGNED: 155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_038000_ARRAY_LINEAR_GENERAL: 156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard b_align = rscreen->tiling_info.group_bytes; 159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return b_align; 162a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned mip_minify(unsigned size, unsigned level) 165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned val; 167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard val = u_minify(size, level); 168a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (level > 0) 169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard val = util_next_power_of_two(val); 170a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return val; 171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_texture_get_nblocksx(struct pipe_screen *screen, 174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex, 175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level) 176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 1772a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák struct pipe_resource *ptex = &rtex->resource.b.b; 178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned nblocksx, block_align, width; 179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned blocksize = util_format_get_blocksize(rtex->real_format); 180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->pitch_override) 182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return rtex->pitch_override / blocksize; 183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard width = mip_minify(ptex->width0, level); 185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard nblocksx = util_format_get_nblocksx(rtex->real_format, width); 186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard block_align = r600_get_block_alignment(screen, rtex->real_format, 188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->array_mode[level]); 189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard nblocksx = align(nblocksx, block_align); 190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return nblocksx; 191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned r600_texture_get_nblocksy(struct pipe_screen *screen, 194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex, 195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level) 196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 1972a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák struct pipe_resource *ptex = &rtex->resource.b.b; 198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned height, tile_height; 199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard height = mip_minify(ptex->height0, level); 201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard height = util_format_get_nblocksy(rtex->real_format, height); 202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tile_height = r600_get_height_alignment(screen, 203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->array_mode[level]); 204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX Hack around an alignment issue. Less tests fail with this. 206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * The thing is depth-stencil buffers should be tiled, i.e. 208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the alignment should be >=8. If I make them tiled, stencil starts 209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * working because it no longer overlaps with the depth buffer 210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * in memory, but texturing like drawpix-stencil breaks. */ 211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (util_format_is_depth_or_stencil(rtex->real_format) && tile_height < 8) 212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tile_height = 8; 213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard height = align(height, tile_height); 215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return height; 216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_texture_set_array_mode(struct pipe_screen *screen, 219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex, 220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level, unsigned array_mode) 221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 2222a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák struct pipe_resource *ptex = &rtex->resource.b.b; 223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (array_mode) { 225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_0280A0_ARRAY_LINEAR_GENERAL: 227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_0280A0_ARRAY_LINEAR_ALIGNED: 228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_0280A0_ARRAY_1D_TILED_THIN1: 229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->array_mode[level] = array_mode; 232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case V_0280A0_ARRAY_2D_TILED_THIN1: 235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard { 236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned w, h, tile_height, tile_width; 237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 238a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tile_height = r600_get_height_alignment(screen, array_mode); 239a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tile_width = r600_get_block_alignment(screen, rtex->real_format, array_mode); 240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 241a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard w = mip_minify(ptex->width0, level); 242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard h = mip_minify(ptex->height0, level); 243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (w <= tile_width || h <= tile_height) 244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->array_mode[level] = V_0280A0_ARRAY_1D_TILED_THIN1; 245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->array_mode[level] = array_mode; 247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_setup_miptree(struct pipe_screen *screen, 254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex, 255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode) 256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 2572a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák struct pipe_resource *ptex = &rtex->resource.b.b; 258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum chip_class chipc = ((struct r600_screen*)screen)->chip_class; 259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned size, layer_size, i, offset; 260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned nblocksx, nblocksy; 261a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (i = 0, offset = 0; i <= ptex->last_level; i++) { 263a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned blocksize = util_format_get_blocksize(rtex->real_format); 264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned base_align = r600_get_base_alignment(screen, rtex->real_format, array_mode); 265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_set_array_mode(screen, rtex, i, array_mode); 267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard nblocksx = r600_texture_get_nblocksx(screen, rtex, i); 269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard nblocksy = r600_texture_get_nblocksy(screen, rtex, i); 270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (chipc >= CAYMAN /*&& array_mode == V_038000_ARRAY_LINEAR_GENERAL*/) 272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard layer_size = align(nblocksx, 64) * nblocksy * blocksize; 273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard layer_size = nblocksx * nblocksy * blocksize; 275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (ptex->target == PIPE_TEXTURE_CUBE) { 277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (chipc >= CAYMAN) 278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard size = layer_size * 8; 279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else if (ptex->target == PIPE_TEXTURE_3D) 281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard size = layer_size * u_minify(ptex->depth0, i); 282a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 283a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard size = layer_size * ptex->array_size; 284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* align base image and start of miptree */ 286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if ((i == 0) || (i == 1)) 287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard offset = align(offset, base_align); 288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->offset[i] = offset; 289a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->layer_size[i] = layer_size; 290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */ 291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->pitch_in_bytes[i] = nblocksx * blocksize; 292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard offset += size; 294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->size = offset; 296a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Figure out whether u_blitter will fallback to a transfer operation. 299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * If so, don't use a staging resource. 300a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 301a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean permit_hardware_blit(struct pipe_screen *screen, 302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_resource *res) 303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned bind; 305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 306a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (util_format_is_depth_or_stencil(res->format)) 307a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bind = PIPE_BIND_DEPTH_STENCIL; 308a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bind = PIPE_BIND_RENDER_TARGET; 310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* hackaround for S3TC */ 312a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (util_format_is_compressed(res->format)) 313a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return TRUE; 314a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 315a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!screen->is_format_supported(screen, 316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->format, 317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->target, 318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->nr_samples, 319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bind)) 320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return FALSE; 321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!screen->is_format_supported(screen, 323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->format, 324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->target, 325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard res->nr_samples, 326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard PIPE_BIND_SAMPLER_VIEW)) 327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return FALSE; 328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (res->usage) { 330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_USAGE_STREAM: 331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_USAGE_STAGING: 332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return FALSE; 333a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return TRUE; 336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 338a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic boolean r600_texture_get_handle(struct pipe_screen* screen, 340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *ptex, 341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct winsys_handle *whandle) 342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; 344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource *resource = &rtex->resource; 345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen *rscreen = (struct r600_screen*)screen; 346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return rscreen->ws->buffer_get_handle(resource->buf, 348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->pitch_in_bytes[0], whandle); 349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_texture_destroy(struct pipe_screen *screen, 352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *ptex) 353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; 355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource *resource = &rtex->resource; 356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->flushed_depth_texture) 358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); 359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->stencil) 361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference((struct pipe_resource **)&rtex->stencil, NULL); 362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pb_reference(&resource->buf, NULL); 364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(rtex); 365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic const struct u_resource_vtbl r600_texture_vtbl = 368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_get_handle, /* get_handle */ 370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_destroy, /* resource_destroy */ 371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_get_transfer, /* get_transfer */ 372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_transfer_destroy, /* transfer_destroy */ 373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_transfer_map, /* transfer_map */ 374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard u_default_transfer_flush_region,/* transfer_flush_region */ 375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_texture_transfer_unmap, /* transfer_unmap */ 376a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard u_default_transfer_inline_write /* transfer_inline_write */ 377a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct r600_resource_texture * 380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardr600_texture_create_object(struct pipe_screen *screen, 381a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_resource *base, 382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode, 383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned pitch_in_bytes_override, 384a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned max_buffer_size, 385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pb_buffer *buf, 386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard boolean alloc_bo) 387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 388a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex; 389a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource *resource; 390a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen *rscreen = (struct r600_screen*)screen; 391a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 392a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex = CALLOC_STRUCT(r600_resource_texture); 393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex == NULL) 394a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource = &rtex->resource; 3972a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák resource->b.b = *base; 3982a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák resource->b.vtbl = &r600_texture_vtbl; 3992a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák pipe_reference_init(&resource->b.b.reference, 1); 4002a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák resource->b.b.screen = screen; 401a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->pitch_override = pitch_in_bytes_override; 402a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->real_format = base->format; 403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 404a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* We must split depth and stencil into two separate buffers on Evergreen. */ 405a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!(base->flags & R600_RESOURCE_FLAG_TRANSFER) && 406a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ((struct r600_screen*)screen)->chip_class >= CAYMAN && 407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard util_format_is_depth_and_stencil(base->format)) { 408a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource stencil; 409a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned stencil_pitch_override = 0; 410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (base->format) { 412a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_FORMAT_Z24_UNORM_S8_UINT: 413a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->real_format = PIPE_FORMAT_Z24X8_UNORM; 414a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 415a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_FORMAT_S8_UINT_Z24_UNORM: 416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->real_format = PIPE_FORMAT_X8Z24_UNORM; 417a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 418a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 419a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->real_format = PIPE_FORMAT_Z32_FLOAT; 420a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 422a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard assert(0); 423a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(rtex); 424a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 426a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 427a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Divide the pitch in bytes by 4 for stencil, because it has a smaller pixel size. */ 428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (pitch_in_bytes_override) { 429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard assert(base->format == PIPE_FORMAT_Z24_UNORM_S8_UINT || 430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard base->format == PIPE_FORMAT_S8_UINT_Z24_UNORM); 431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil_pitch_override = pitch_in_bytes_override / 4; 432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 434a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Allocate the stencil buffer. */ 435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil = *base; 436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil.format = PIPE_FORMAT_S8_UINT; 437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->stencil = r600_texture_create_object(screen, &stencil, array_mode, 438a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil_pitch_override, 439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard max_buffer_size, NULL, FALSE); 440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!rtex->stencil) { 441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(rtex); 442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 443a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Proceed in creating the depth buffer. */ 445a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 447a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* only mark depth textures the HW can hit as depth textures */ 448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base)) 449a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->depth = 1; 450a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 451a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_setup_miptree(screen, rtex, array_mode); 452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* If we initialized separate stencil for Evergreen. place it after depth. */ 454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->stencil) { 455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned stencil_align, stencil_offset; 456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil_align = r600_get_base_alignment(screen, rtex->stencil->real_format, array_mode); 458a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stencil_offset = align(rtex->size, stencil_align); 459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 4602a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák for (unsigned i = 0; i <= rtex->stencil->resource.b.b.last_level; i++) 461a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->stencil->offset[i] += stencil_offset; 462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->size = stencil_offset + rtex->stencil->size; 464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Now create the backing buffer. */ 467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!buf && alloc_bo) { 4682a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák struct pipe_resource *ptex = &rtex->resource.b.b; 469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode); 470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) { 472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference((struct pipe_resource**)&rtex->stencil, NULL); 473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(rtex); 474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else if (buf) { 477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource->buf = buf; 478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf); 479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM; 480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 481a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 482a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->stencil) { 483a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf); 484a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->stencil->resource.cs_buf = rtex->resource.cs_buf; 485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->stencil->resource.domains = rtex->resource.domains; 486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 487a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return rtex; 488a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 489a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 490a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardDEBUG_GET_ONCE_BOOL_OPTION(tiling_enabled, "R600_TILING", FALSE); 491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_resource *r600_texture_create(struct pipe_screen *screen, 493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_resource *templ) 494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 495a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen *rscreen = (struct r600_screen*)screen; 496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode = 0; 497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 498a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && 499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard !(templ->bind & PIPE_BIND_SCANOUT)) { 500a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (util_format_is_compressed(templ->format)) { 502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard array_mode = V_038000_ARRAY_1D_TILED_THIN1; 503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 504a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else if (debug_get_option_tiling_enabled() && 505a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rscreen->info.drm_minor >= 9 && 506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard permit_hardware_blit(screen, templ)) { 507a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard array_mode = V_038000_ARRAY_2D_TILED_THIN1; 508a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 511a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, 513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 0, 0, NULL, TRUE); 514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct pipe_surface *r600_create_surface(struct pipe_context *pipe, 517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture, 518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_surface *surf_tmpl) 519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 520a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; 521a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_surface *surface = CALLOC_STRUCT(r600_surface); 522a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level = surf_tmpl->u.tex.level; 523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 524a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); 525a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (surface == NULL) 526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 527a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX no offset */ 528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/ 529a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_reference_init(&surface->base.reference, 1); 530a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&surface->base.texture, texture); 531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.context = pipe; 532a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.format = surf_tmpl->format; 533a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.width = mip_minify(texture->width0, level); 534a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.height = mip_minify(texture->height0, level); 535a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.usage = surf_tmpl->usage; 536a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.texture = texture; 537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer; 538a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer; 539a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->base.u.tex.level = level; 540a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 541a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard surface->aligned_height = r600_texture_get_nblocksy(pipe->screen, 542a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex, level); 543a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return &surface->base; 544a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 545a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 546a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_surface_destroy(struct pipe_context *pipe, 547a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_surface *surface) 548a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 549a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&surface->texture, NULL); 550a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(surface); 551a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 552a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 553a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, 554a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_resource *templ, 555a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct winsys_handle *whandle) 556a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 557a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_screen *rscreen = (struct r600_screen*)screen; 558a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pb_buffer *buf = NULL; 559a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned stride = 0; 560a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned array_mode = 0; 561a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum radeon_bo_layout micro, macro; 562a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 563a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Support only 2D textures without mipmaps */ 564a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) || 565a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard templ->depth0 != 1 || templ->last_level != 0) 566a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 567a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 568a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride); 569a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!buf) 570a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 571a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 572a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rscreen->ws->buffer_get_tiling(buf, µ, ¯o, NULL, NULL, NULL, NULL, NULL); 573a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 574a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 575a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (macro == RADEON_LAYOUT_TILED) 576a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard array_mode = V_0280A0_ARRAY_2D_TILED_THIN1; 577a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else if (micro == RADEON_LAYOUT_TILED) 578a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard array_mode = V_0280A0_ARRAY_1D_TILED_THIN1; 579a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 580a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 581a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard array_mode = 0; 582a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 583a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, 584a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard stride, 0, buf, FALSE); 585a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 586a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 587a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardint r600_texture_depth_flush(struct pipe_context *ctx, 588a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture, boolean just_create) 589a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 590a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; 591a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource resource; 592a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 593a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->flushed_depth_texture) 594a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard goto out; 595a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 596a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.target = texture->target; 597a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.format = texture->format; 598a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.width0 = texture->width0; 599a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.height0 = texture->height0; 600a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.depth0 = texture->depth0; 601a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.array_size = texture->array_size; 602a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.last_level = texture->last_level; 603a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.nr_samples = texture->nr_samples; 604a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.usage = PIPE_USAGE_DYNAMIC; 605a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL; 606a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags; 607a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 608a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource); 609a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->flushed_depth_texture == NULL) { 610a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard R600_ERR("failed to create temporary texture to hold untiled copy\n"); 611a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return -ENOMEM; 612a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 613a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 614a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE; 615a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardout: 616a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (just_create) 617a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return 0; 618a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 619a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: only do this if the depth texture has actually changed: 620a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 621a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_blit_uncompress_depth(ctx, rtex); 622a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return 0; 623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 624a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 625a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Needs adjustment for pixelformat: 626a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 627a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic INLINE unsigned u_box_volume( const struct pipe_box *box ) 628a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 629a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return box->width * box->depth * box->height; 630a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 632a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, 633a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture, 634a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned level, 635a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned usage, 636a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct pipe_box *box) 637a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; 639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource resource; 640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_transfer *trans; 641a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int r; 642a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard boolean use_staging_texture = FALSE; 643a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 644a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if 0 645a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* We cannot map a tiled texture directly because the data is 646a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * in a different order, therefore we do detiling using a blit. 647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Also, use a temporary in GTT memory for read transfers, as 649a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the CPU is much happier reading out of cached system memory 650a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * than uncached VRAM. 651a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 652a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (R600_TEX_IS_TILED(rtex, level)) 653a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard use_staging_texture = TRUE; 654a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 655a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 656a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024) 657a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard use_staging_texture = TRUE; 658a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 659a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Use a staging texture for uploads if the underlying BO 660a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * is busy. No interface for checking that currently? so do 661a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * it eagerly whenever the transfer doesn't require a readback 662a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * and might block. 663a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 664a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if ((usage & PIPE_TRANSFER_WRITE) && 665a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard !(usage & (PIPE_TRANSFER_READ | 666a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard PIPE_TRANSFER_DONTBLOCK | 667a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard PIPE_TRANSFER_UNSYNCHRONIZED))) 668a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard use_staging_texture = TRUE; 669a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 670a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!permit_hardware_blit(ctx->screen, texture) || 671a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard (texture->flags & R600_RESOURCE_FLAG_TRANSFER)) 672a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard use_staging_texture = FALSE; 673a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 674a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) 675a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 676a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 677a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans = CALLOC_STRUCT(r600_transfer); 678a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (trans == NULL) 679a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 680a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&trans->transfer.resource, texture); 681a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.level = level; 682a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.usage = usage; 683a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.box = *box; 684a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->depth) { 685a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: only readback the rectangle which is being mapped? 686a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 687a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: when discard is true, no need to read back from depth texture 688a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 689a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r = r600_texture_depth_flush(ctx, texture, FALSE); 690a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (r < 0) { 691a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard R600_ERR("failed to create temporary texture to hold untiled copy\n"); 692a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&trans->transfer.resource, NULL); 693a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(trans); 694a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 695a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 696a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level]; 697a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z); 698a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return &trans->transfer; 699a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else if (use_staging_texture) { 700a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.target = PIPE_TEXTURE_2D; 701a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.format = texture->format; 702a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.width0 = box->width; 703a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.height0 = box->height; 704a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.depth0 = 1; 705a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.array_size = 1; 706a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.last_level = 0; 707a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.nr_samples = 0; 708a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.usage = PIPE_USAGE_STAGING; 709a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.bind = 0; 710a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.flags = R600_RESOURCE_FLAG_TRANSFER; 711a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* For texture reading, the temporary (detiled) texture is used as 712a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * a render target when blitting from a tiled texture. */ 713a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (usage & PIPE_TRANSFER_READ) { 714a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.bind |= PIPE_BIND_RENDER_TARGET; 715a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 716a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* For texture writing, the temporary texture is used as a sampler 717a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * when blitting into a tiled texture. */ 718a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (usage & PIPE_TRANSFER_WRITE) { 719a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard resource.bind |= PIPE_BIND_SAMPLER_VIEW; 720a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 721a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Create the temporary texture. */ 722a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource); 723a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (trans->staging_texture == NULL) { 724a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard R600_ERR("failed to create temporary texture to hold untiled copy\n"); 725a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&trans->transfer.resource, NULL); 726a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(trans); 727a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 728a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 729a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 730a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.stride = 731a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0]; 732a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (usage & PIPE_TRANSFER_READ) { 733a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_copy_to_staging_texture(ctx, trans); 734a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Always referenced in the blit. */ 735a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard radeonsi_flush(ctx, NULL, 0); 736a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 737a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return &trans->transfer; 738a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 739a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.stride = rtex->pitch_in_bytes[level]; 740a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->transfer.layer_stride = rtex->layer_size[level]; 741a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard trans->offset = r600_texture_get_offset(rtex, level, box->z); 742a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return &trans->transfer; 743a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 744a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 745a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_texture_transfer_destroy(struct pipe_context *ctx, 746a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_transfer *transfer) 747a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 748a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; 749a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_resource *texture = transfer->resource; 750a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; 751a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 752a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtransfer->staging_texture) { 753a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (transfer->usage & PIPE_TRANSFER_WRITE) { 754a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_copy_from_staging_texture(ctx, rtransfer); 755a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 756a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&rtransfer->staging_texture, NULL); 757a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 758a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 759a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->depth && !rtex->is_flushing_texture) { 760a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture) 761a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600_blit_push_depth(ctx, rtex); 762a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 763a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 764a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard pipe_resource_reference(&transfer->resource, NULL); 765a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FREE(transfer); 766a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 767a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 768a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid* r600_texture_transfer_map(struct pipe_context *ctx, 769a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_transfer* transfer) 770a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 771a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_context *rctx = (struct r600_context *)ctx; 772a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; 773a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pb_buffer *buf; 774a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum pipe_format format = transfer->resource->format; 775a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned offset = 0; 776a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard char *map; 777a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 778a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtransfer->staging_texture) { 779a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)rtransfer->staging_texture)->buf; 780a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 781a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; 782a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 783a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->flushed_depth_texture) 784a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf; 785a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard else 786a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)transfer->resource)->buf; 787a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 788a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard offset = rtransfer->offset + 789a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard transfer->box.y / util_format_get_blockheight(format) * transfer->stride + 790a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); 791a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 792a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 793a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) { 794a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 795a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 796a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 797a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return map + offset; 798a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 799a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 800a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_texture_transfer_unmap(struct pipe_context *ctx, 801a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_transfer* transfer) 802a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 803a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; 804a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_context *rctx = (struct r600_context*)ctx; 805a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pb_buffer *buf; 806a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 807a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtransfer->staging_texture) { 808a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)rtransfer->staging_texture)->buf; 809a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 810a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; 811a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 812a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (rtex->flushed_depth_texture) { 813a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf; 814a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 815a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard buf = ((struct r600_resource *)transfer->resource)->buf; 816a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 817a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 818a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard rctx->ws->buffer_unmap(buf); 819a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 820a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 821a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_init_surface_functions(struct r600_context *r600) 822a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 823a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600->context.create_surface = r600_create_surface; 824a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard r600->context.surface_destroy = r600_surface_destroy; 825a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 826