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 uint32_t width0 = prsc->width0; 35 36 if (rsc->layout.tile_mode && prsc->target != PIPE_TEXTURE_CUBE) 37 width0 = util_next_power_of_two(width0); 38 39 /* 32 pixel alignment */ 40 fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5); 41 42 for (level = 0; level <= prsc->last_level; level++) { 43 struct fdl_slice *slice = fd_resource_slice(rsc, level); 44 uint32_t pitch = fdl_pitch(&rsc->layout, level); 45 uint32_t height = u_minify(prsc->height0, level); 46 if (rsc->layout.tile_mode) { 47 height = align(height, 4); 48 if (prsc->target != PIPE_TEXTURE_CUBE) 49 height = util_next_power_of_two(height); 50 } 51 52 uint32_t nblocksy = util_format_get_nblocksy(format, height); 53 54 slice->offset = size; 55 /* 1d array and 2d array textures must all have the same layer size 56 * for each miplevel on a3xx. 3d textures can have different layer 57 * sizes for high levels, but the hw auto-sizer is buggy (or at least 58 * different than what this code does), so as soon as the layer size 59 * range gets into range, we stop reducing it. 60 */ 61 if (prsc->target == PIPE_TEXTURE_3D && 62 (level == 1 || 63 (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000))) 64 slice->size0 = align(nblocksy * pitch, alignment); 65 else if (level == 0 || alignment == 1) 66 slice->size0 = align(nblocksy * pitch, alignment); 67 else 68 slice->size0 = fd_resource_slice(rsc, level - 1)->size0; 69 70 size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size; 71 } 72 73 return size; 74} 75 76uint32_t 77fd3_setup_slices(struct fd_resource *rsc) 78{ 79 uint32_t alignment; 80 81 switch (rsc->b.b.target) { 82 case PIPE_TEXTURE_3D: 83 case PIPE_TEXTURE_1D_ARRAY: 84 case PIPE_TEXTURE_2D_ARRAY: 85 alignment = 4096; 86 break; 87 default: 88 alignment = 1; 89 break; 90 } 91 92 return setup_slices(rsc, alignment, rsc->b.b.format); 93} 94 95static bool 96ok_format(enum pipe_format pfmt) 97{ 98 enum a3xx_color_fmt fmt = fd3_pipe2color(pfmt); 99 100 if (fmt == RB_NONE) 101 return false; 102 103 switch (pfmt) { 104 case PIPE_FORMAT_R8_UINT: 105 case PIPE_FORMAT_R8_SINT: 106 case PIPE_FORMAT_Z32_FLOAT: 107 return false; 108 default: 109 break; 110 } 111 112 return true; 113} 114 115unsigned 116fd3_tile_mode(const struct pipe_resource *tmpl) 117{ 118 if (ok_format(tmpl->format)) 119 return TILE_4X4; 120 return LINEAR; 121} 122