1/* 2 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 3 * Copyright (C) 2019 Khaled Emara <ekhaled1836@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25#include "fd3_resource.h" 26#include "fd3_format.h" 27 28static uint32_t 29setup_slices(struct fd_resource *rsc, uint32_t alignment, 30 enum pipe_format format) 31{ 32 struct pipe_resource *prsc = &rsc->b.b; 33 uint32_t level, size = 0; 34 35 /* 32 pixel alignment */ 36 fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5); 37 38 for (level = 0; level <= prsc->last_level; level++) { 39 struct fdl_slice *slice = fd_resource_slice(rsc, level); 40 uint32_t pitch = fdl_pitch(&rsc->layout, level); 41 uint32_t height = u_minify(prsc->height0, level); 42 if (rsc->layout.tile_mode) { 43 height = align(height, 4); 44 if (prsc->target != PIPE_TEXTURE_CUBE) 45 height = util_next_power_of_two(height); 46 } 47 48 uint32_t nblocksy = util_format_get_nblocksy(format, height); 49 50 slice->offset = size; 51 /* 1d array and 2d array textures must all have the same layer size 52 * for each miplevel on a3xx. 3d textures can have different layer 53 * sizes for high levels, but the hw auto-sizer is buggy (or at least 54 * different than what this code does), so as soon as the layer size 55 * range gets into range, we stop reducing it. 56 */ 57 if (prsc->target == PIPE_TEXTURE_3D && 58 (level == 1 || 59 (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000))) 60 slice->size0 = align(nblocksy * pitch, alignment); 61 else if (level == 0 || alignment == 1) 62 slice->size0 = align(nblocksy * pitch, alignment); 63 else 64 slice->size0 = fd_resource_slice(rsc, level - 1)->size0; 65 66 size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size; 67 } 68 69 return size; 70} 71 72uint32_t 73fd3_setup_slices(struct fd_resource *rsc) 74{ 75 uint32_t alignment; 76 77 switch (rsc->b.b.target) { 78 case PIPE_TEXTURE_3D: 79 case PIPE_TEXTURE_1D_ARRAY: 80 case PIPE_TEXTURE_2D_ARRAY: 81 alignment = 4096; 82 break; 83 default: 84 alignment = 1; 85 break; 86 } 87 88 return setup_slices(rsc, alignment, rsc->b.b.format); 89} 90 91static bool 92ok_format(enum pipe_format pfmt) 93{ 94 enum a3xx_color_fmt fmt = fd3_pipe2color(pfmt); 95 96 if (fmt == RB_NONE) 97 return false; 98 99 switch (pfmt) { 100 case PIPE_FORMAT_R8_UINT: 101 case PIPE_FORMAT_R8_SINT: 102 case PIPE_FORMAT_Z32_FLOAT: 103 return false; 104 default: 105 break; 106 } 107 108 return true; 109} 110 111unsigned 112fd3_tile_mode(const struct pipe_resource *tmpl) 113{ 114 if (ok_format(tmpl->format)) 115 return TILE_4X4; 116 return LINEAR; 117} 118