1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2016 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21b8e80941Smrg * DEALINGS IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#include "tu_private.h" 25b8e80941Smrg 26b8e80941Smrg#include "a6xx.xml.h" 27b8e80941Smrg#include "adreno_common.xml.h" 28b8e80941Smrg#include "adreno_pm4.xml.h" 29b8e80941Smrg 30b8e80941Smrg#include "vk_format.h" 31b8e80941Smrg 32b8e80941Smrg#include "tu_cs.h" 33b8e80941Smrg 34b8e80941Smrg/* 35b8e80941Smrg * TODO: 36b8e80941Smrg * - image -> image copies 37b8e80941Smrg * - 3D textures 38b8e80941Smrg * - compressed image formats (need to divide offset/extent) 39b8e80941Smrg */ 40b8e80941Smrg 41b8e80941Smrgstatic uint32_t 42b8e80941Smrgblit_control(enum a6xx_color_fmt fmt) 43b8e80941Smrg{ 44b8e80941Smrg unsigned blit_cntl = 0xf00000; 45b8e80941Smrg blit_cntl |= A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(fmt); 46b8e80941Smrg blit_cntl |= A6XX_RB_2D_BLIT_CNTL_IFMT(tu6_rb_fmt_to_ifmt(fmt)); 47b8e80941Smrg return blit_cntl; 48b8e80941Smrg} 49b8e80941Smrg 50b8e80941Smrgstatic uint32_t tu6_sp_2d_src_format(VkFormat format) 51b8e80941Smrg{ 52b8e80941Smrg const struct vk_format_description *desc = vk_format_description(format); 53b8e80941Smrg uint32_t reg = 0xf000 | A6XX_SP_2D_SRC_FORMAT_COLOR_FORMAT(tu6_get_native_format(format)->rb); 54b8e80941Smrg 55b8e80941Smrg int channel = vk_format_get_first_non_void_channel(format); 56b8e80941Smrg if (channel < 0) { 57b8e80941Smrg /* TODO special format. */ 58b8e80941Smrg return reg; 59b8e80941Smrg } 60b8e80941Smrg if (desc->channel[channel].normalized) { 61b8e80941Smrg if (desc->channel[channel].type == VK_FORMAT_TYPE_SIGNED) 62b8e80941Smrg reg |= A6XX_SP_2D_SRC_FORMAT_SINT; 63b8e80941Smrg reg |= A6XX_SP_2D_SRC_FORMAT_NORM; 64b8e80941Smrg } else if (desc->channel[channel].pure_integer) { 65b8e80941Smrg if (desc->channel[channel].type == VK_FORMAT_TYPE_SIGNED) 66b8e80941Smrg reg |= A6XX_SP_2D_SRC_FORMAT_SINT; 67b8e80941Smrg else 68b8e80941Smrg reg |= A6XX_SP_2D_SRC_FORMAT_UINT; 69b8e80941Smrg } 70b8e80941Smrg return reg; 71b8e80941Smrg} 72b8e80941Smrg 73b8e80941Smrgstatic void 74b8e80941Smrgtu_dma_prepare(struct tu_cmd_buffer *cmdbuf) 75b8e80941Smrg{ 76b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 10); 77b8e80941Smrg 78b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_EVENT_WRITE, 1); 79b8e80941Smrg tu_cs_emit(&cmdbuf->cs, PC_CCU_INVALIDATE_COLOR); 80b8e80941Smrg 81b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_EVENT_WRITE, 1); 82b8e80941Smrg tu_cs_emit(&cmdbuf->cs, LRZ_FLUSH); 83b8e80941Smrg 84b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_SKIP_IB2_ENABLE_GLOBAL, 1); 85b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x0); 86b8e80941Smrg 87b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 88b8e80941Smrg 89b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_CCU_CNTL, 1); 90b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x10000000); 91b8e80941Smrg} 92b8e80941Smrg 93b8e80941Smrgstatic void 94b8e80941Smrgtu_copy_buffer(struct tu_cmd_buffer *cmdbuf, 95b8e80941Smrg struct tu_bo *src_bo, 96b8e80941Smrg uint64_t src_offset, 97b8e80941Smrg struct tu_bo *dst_bo, 98b8e80941Smrg uint64_t dst_offset, 99b8e80941Smrg uint64_t size) 100b8e80941Smrg{ 101b8e80941Smrg const unsigned max_size_per_iter = 0x4000 - 0x40; 102b8e80941Smrg const unsigned max_iterations = 103b8e80941Smrg (size + max_size_per_iter) / max_size_per_iter; 104b8e80941Smrg 105b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, src_bo, MSM_SUBMIT_BO_READ); 106b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, dst_bo, MSM_SUBMIT_BO_WRITE); 107b8e80941Smrg 108b8e80941Smrg tu_dma_prepare(cmdbuf); 109b8e80941Smrg 110b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 21 + 48 * max_iterations); 111b8e80941Smrg 112b8e80941Smrg /* buffer copy setup */ 113b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_SET_MARKER, 1); 114b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); 115b8e80941Smrg 116b8e80941Smrg const uint32_t blit_cntl = blit_control(RB6_R8_UNORM) | 0x20000000; 117b8e80941Smrg 118b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_BLIT_CNTL, 1); 119b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 120b8e80941Smrg 121b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); 122b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 123b8e80941Smrg 124b8e80941Smrg for (; size;) { 125b8e80941Smrg uint64_t src_va = src_bo->iova + src_offset; 126b8e80941Smrg uint64_t dst_va = dst_bo->iova + dst_offset; 127b8e80941Smrg 128b8e80941Smrg unsigned src_shift = src_va & 0x3f; 129b8e80941Smrg unsigned dst_shift = dst_va & 0x3f; 130b8e80941Smrg unsigned max_shift = MAX2(src_shift, dst_shift); 131b8e80941Smrg 132b8e80941Smrg src_va -= src_shift; 133b8e80941Smrg dst_va -= dst_shift; 134b8e80941Smrg 135b8e80941Smrg uint32_t size_todo = MIN2(0x4000 - max_shift, size); 136b8e80941Smrg unsigned pitch = (size_todo + max_shift + 63) & ~63; 137b8e80941Smrg 138b8e80941Smrg /* 139b8e80941Smrg * Emit source: 140b8e80941Smrg */ 141b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_PS_2D_SRC_INFO, 13); 142b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 143b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(RB6_R8_UNORM) | 144b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(TILE6_LINEAR) | 145b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 0x500000); 146b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 147b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_WIDTH(src_shift + size_todo) | 148b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(1)); /* SP_PS_2D_SRC_SIZE */ 149b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, src_va); 150b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(pitch)); 151b8e80941Smrg 152b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 153b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 154b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 155b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 156b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 157b8e80941Smrg 158b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 159b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 160b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 161b8e80941Smrg 162b8e80941Smrg /* 163b8e80941Smrg * Emit destination: 164b8e80941Smrg */ 165b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_DST_INFO, 9); 166b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(RB6_R8_UNORM) | 167b8e80941Smrg A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) | 168b8e80941Smrg A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX)); 169b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, dst_va); 170b8e80941Smrg 171b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_RB_2D_DST_SIZE_PITCH(pitch)); 172b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 173b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 174b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 175b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 176b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 177b8e80941Smrg 178b8e80941Smrg /* 179b8e80941Smrg * Blit command: 180b8e80941Smrg */ 181b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_SRC_TL_X, 4); 182b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_X_X(src_shift)); 183b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 184b8e80941Smrg A6XX_GRAS_2D_SRC_BR_X_X(src_shift + size_todo - 1)); 185b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_Y_Y(0)); 186b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_BR_Y_Y(0)); 187b8e80941Smrg 188b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_DST_TL, 2); 189b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 190b8e80941Smrg A6XX_GRAS_2D_DST_TL_X(dst_shift) | A6XX_GRAS_2D_DST_TL_Y(0)); 191b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 192b8e80941Smrg A6XX_GRAS_2D_DST_BR_X(dst_shift + size_todo - 1) | 193b8e80941Smrg A6XX_GRAS_2D_DST_BR_Y(0)); 194b8e80941Smrg 195b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_EVENT_WRITE, 1); 196b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x3f); 197b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 198b8e80941Smrg 199b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8C01, 1); 200b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 201b8e80941Smrg 202b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_2D_SRC_FORMAT, 1); 203b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0xf180); 204b8e80941Smrg 205b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 206b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x01000000); 207b8e80941Smrg 208b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_BLIT, 1); 209b8e80941Smrg tu_cs_emit(&cmdbuf->cs, CP_BLIT_0_OP(BLIT_OP_SCALE)); 210b8e80941Smrg 211b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 212b8e80941Smrg 213b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 214b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 215b8e80941Smrg 216b8e80941Smrg src_offset += size_todo; 217b8e80941Smrg dst_offset += size_todo; 218b8e80941Smrg size -= size_todo; 219b8e80941Smrg } 220b8e80941Smrg 221b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, 0x1d, true); 222b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, FACENESS_FLUSH, true); 223b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, CACHE_FLUSH_TS, true); 224b8e80941Smrg} 225b8e80941Smrg 226b8e80941Smrgstatic void 227b8e80941Smrgtu_copy_buffer_to_image_step(struct tu_cmd_buffer *cmdbuf, 228b8e80941Smrg struct tu_buffer *src_buffer, 229b8e80941Smrg struct tu_image *dst_image, 230b8e80941Smrg const VkBufferImageCopy *copy_info, 231b8e80941Smrg VkFormat format, 232b8e80941Smrg uint32_t layer, 233b8e80941Smrg uint64_t src_va) 234b8e80941Smrg{ 235b8e80941Smrg const enum a6xx_color_fmt rb_fmt = tu6_get_native_format(format)->rb; 236b8e80941Smrg 237b8e80941Smrg uint64_t dst_va = dst_image->bo->iova + dst_image->bo_offset + dst_image->layer_size * layer + dst_image->levels[copy_info->imageSubresource.mipLevel].offset; 238b8e80941Smrg unsigned dst_pitch = dst_image->levels[copy_info->imageSubresource.mipLevel].pitch * 239b8e80941Smrg vk_format_get_blocksize(format); 240b8e80941Smrg 241b8e80941Smrg unsigned src_pitch; 242b8e80941Smrg unsigned src_offset = 0; 243b8e80941Smrg if (copy_info->imageExtent.height == 1) { 244b8e80941Smrg /* Can't find this in the spec, but not having it is sort of insane? */ 245b8e80941Smrg assert(src_va % vk_format_get_blocksize(format) == 0); 246b8e80941Smrg 247b8e80941Smrg src_offset = (src_va & 63) / vk_format_get_blocksize(format); 248b8e80941Smrg src_va &= ~63; 249b8e80941Smrg 250b8e80941Smrg src_pitch = align((src_offset + copy_info->imageExtent.width) * vk_format_get_blocksize(format), 64); 251b8e80941Smrg } else { 252b8e80941Smrg unsigned src_pixel_stride = copy_info->bufferRowLength 253b8e80941Smrg ? copy_info->bufferRowLength 254b8e80941Smrg : copy_info->imageExtent.width; 255b8e80941Smrg src_pitch = src_pixel_stride * vk_format_get_blocksize(format); 256b8e80941Smrg assert(!(src_pitch & 63)); 257b8e80941Smrg assert(!(src_va & 63)); 258b8e80941Smrg } 259b8e80941Smrg 260b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 48); 261b8e80941Smrg 262b8e80941Smrg /* 263b8e80941Smrg * Emit source: 264b8e80941Smrg */ 265b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_PS_2D_SRC_INFO, 13); 266b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(rb_fmt) | 267b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(TILE6_LINEAR) | 268b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 269b8e80941Smrg 0x500000); 270b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 271b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_WIDTH(src_offset + copy_info->imageExtent.width) | 272b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_HEIGHT( 273b8e80941Smrg copy_info->imageExtent.height)); /* SP_PS_2D_SRC_SIZE */ 274b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, src_va); 275b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(src_pitch)); 276b8e80941Smrg 277b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 278b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 279b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 280b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 281b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 282b8e80941Smrg 283b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 284b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 285b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 286b8e80941Smrg 287b8e80941Smrg /* 288b8e80941Smrg * Emit destination: 289b8e80941Smrg */ 290b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_DST_INFO, 9); 291b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 292b8e80941Smrg A6XX_RB_2D_DST_INFO_COLOR_FORMAT(rb_fmt) | 293b8e80941Smrg A6XX_RB_2D_DST_INFO_TILE_MODE(dst_image->tile_mode) | 294b8e80941Smrg A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX)); 295b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, dst_va); 296b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_RB_2D_DST_SIZE_PITCH(dst_pitch)); 297b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 298b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 299b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 300b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 301b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 302b8e80941Smrg 303b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_SRC_TL_X, 4); 304b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_X_X(src_offset)); 305b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 306b8e80941Smrg A6XX_GRAS_2D_SRC_BR_X_X(src_offset + copy_info->imageExtent.width - 1)); 307b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_Y_Y(0)); 308b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 309b8e80941Smrg A6XX_GRAS_2D_SRC_BR_Y_Y(copy_info->imageExtent.height - 1)); 310b8e80941Smrg 311b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_DST_TL, 2); 312b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 313b8e80941Smrg A6XX_GRAS_2D_DST_TL_X(copy_info->imageOffset.x) | 314b8e80941Smrg A6XX_GRAS_2D_DST_TL_Y(copy_info->imageOffset.y)); 315b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 316b8e80941Smrg A6XX_GRAS_2D_DST_BR_X(copy_info->imageOffset.x + 317b8e80941Smrg copy_info->imageExtent.width - 1) | 318b8e80941Smrg A6XX_GRAS_2D_DST_BR_Y(copy_info->imageOffset.y + 319b8e80941Smrg copy_info->imageExtent.height - 1)); 320b8e80941Smrg 321b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_EVENT_WRITE, 1); 322b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x3f); 323b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 324b8e80941Smrg 325b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8C01, 1); 326b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 327b8e80941Smrg 328b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_2D_SRC_FORMAT, 1); 329b8e80941Smrg tu_cs_emit(&cmdbuf->cs, tu6_sp_2d_src_format(format)); 330b8e80941Smrg 331b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 332b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x01000000); 333b8e80941Smrg 334b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_BLIT, 1); 335b8e80941Smrg tu_cs_emit(&cmdbuf->cs, CP_BLIT_0_OP(BLIT_OP_SCALE)); 336b8e80941Smrg 337b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 338b8e80941Smrg 339b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 340b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 341b8e80941Smrg} 342b8e80941Smrg 343b8e80941Smrgstatic void 344b8e80941Smrgtu_copy_buffer_to_image(struct tu_cmd_buffer *cmdbuf, 345b8e80941Smrg struct tu_buffer *src_buffer, 346b8e80941Smrg struct tu_image *dst_image, 347b8e80941Smrg const VkBufferImageCopy *copy_info) 348b8e80941Smrg{ 349b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, src_buffer->bo, MSM_SUBMIT_BO_READ); 350b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, dst_image->bo, MSM_SUBMIT_BO_WRITE); 351b8e80941Smrg 352b8e80941Smrg /* general setup */ 353b8e80941Smrg tu_dma_prepare(cmdbuf); 354b8e80941Smrg 355b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 6); 356b8e80941Smrg 357b8e80941Smrg /* buffer copy setup */ 358b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_SET_MARKER, 1); 359b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); 360b8e80941Smrg 361b8e80941Smrg VkFormat format = dst_image->vk_format; 362b8e80941Smrg const enum a6xx_color_fmt rb_fmt = tu6_get_native_format(format)->rb; 363b8e80941Smrg 364b8e80941Smrg const uint32_t blit_cntl = blit_control(rb_fmt) | 0x20000000; 365b8e80941Smrg 366b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_BLIT_CNTL, 1); 367b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 368b8e80941Smrg 369b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); 370b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 371b8e80941Smrg 372b8e80941Smrg unsigned src_pixel_stride = copy_info->bufferRowLength 373b8e80941Smrg ? copy_info->bufferRowLength 374b8e80941Smrg : copy_info->imageExtent.width; 375b8e80941Smrg unsigned cpp = vk_format_get_blocksize(format); 376b8e80941Smrg unsigned src_pitch = src_pixel_stride * cpp; 377b8e80941Smrg 378b8e80941Smrg for (unsigned layer_offset = 0; layer_offset < copy_info->imageSubresource.layerCount; ++layer_offset) { 379b8e80941Smrg unsigned layer = copy_info->imageSubresource.baseArrayLayer + layer_offset; 380b8e80941Smrg uint64_t src_va = src_buffer->bo->iova + src_buffer->bo_offset + copy_info->bufferOffset + layer_offset * copy_info->bufferImageHeight * src_pitch; 381b8e80941Smrg 382b8e80941Smrg if ((src_pitch & 63) || (src_va & 63)) { 383b8e80941Smrg /* Do a per line copy */ 384b8e80941Smrg VkBufferImageCopy line_copy_info = *copy_info; 385b8e80941Smrg line_copy_info.imageExtent.height = 1; 386b8e80941Smrg for (unsigned r = 0; r < copy_info->imageExtent.height; ++r) { 387b8e80941Smrg /* 388b8e80941Smrg * if src_va is not aligned the line copy will need to adjust. Give it 389b8e80941Smrg * room to do so. 390b8e80941Smrg */ 391b8e80941Smrg unsigned max_width = 16384 - (src_va & 0x3f) ? 64 : 0; 392b8e80941Smrg line_copy_info.imageOffset.x = copy_info->imageOffset.x; 393b8e80941Smrg line_copy_info.imageExtent.width = copy_info->imageExtent.width; 394b8e80941Smrg 395b8e80941Smrg for (unsigned c = 0; c < copy_info->imageExtent.width; c += max_width) { 396b8e80941Smrg tu_copy_buffer_to_image_step(cmdbuf, src_buffer, dst_image, &line_copy_info, format, layer, src_va + c * cpp); 397b8e80941Smrg 398b8e80941Smrg line_copy_info.imageOffset.x += max_width; 399b8e80941Smrg line_copy_info.imageExtent.width -= max_width; 400b8e80941Smrg } 401b8e80941Smrg 402b8e80941Smrg line_copy_info.imageOffset.y++; 403b8e80941Smrg src_va += src_pitch; 404b8e80941Smrg } 405b8e80941Smrg } else { 406b8e80941Smrg tu_copy_buffer_to_image_step(cmdbuf, src_buffer, dst_image, copy_info, format, layer, src_va); 407b8e80941Smrg } 408b8e80941Smrg } 409b8e80941Smrg 410b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 15); 411b8e80941Smrg 412b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, 0x1d, true); 413b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, FACENESS_FLUSH, true); 414b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, CACHE_FLUSH_TS, true); 415b8e80941Smrg} 416b8e80941Smrg 417b8e80941Smrgstatic void 418b8e80941Smrgtu_copy_image_to_buffer_step(struct tu_cmd_buffer *cmdbuf, 419b8e80941Smrg struct tu_image *src_image, 420b8e80941Smrg struct tu_buffer *dst_buffer, 421b8e80941Smrg const VkBufferImageCopy *copy_info, 422b8e80941Smrg VkFormat format, 423b8e80941Smrg uint32_t layer, 424b8e80941Smrg uint64_t dst_va) 425b8e80941Smrg{ 426b8e80941Smrg const enum a6xx_color_fmt rb_fmt = tu6_get_native_format(format)->rb; 427b8e80941Smrg 428b8e80941Smrg uint64_t src_va = src_image->bo->iova + src_image->bo_offset + src_image->layer_size * layer + src_image->levels[copy_info->imageSubresource.mipLevel].offset; 429b8e80941Smrg unsigned src_pitch = src_image->levels[copy_info->imageSubresource.mipLevel].pitch * 430b8e80941Smrg vk_format_get_blocksize(format); 431b8e80941Smrg 432b8e80941Smrg unsigned dst_pitch; 433b8e80941Smrg unsigned dst_offset = 0; 434b8e80941Smrg if (copy_info->imageExtent.height == 1) { 435b8e80941Smrg /* Can't find this in the spec, but not having it is sort of insane? */ 436b8e80941Smrg assert(dst_va % vk_format_get_blocksize(format) == 0); 437b8e80941Smrg 438b8e80941Smrg dst_offset = (dst_va & 63) / vk_format_get_blocksize(format); 439b8e80941Smrg dst_va &= ~63; 440b8e80941Smrg 441b8e80941Smrg dst_pitch = align((dst_offset + copy_info->imageExtent.width) * vk_format_get_blocksize(format), 64); 442b8e80941Smrg } else { 443b8e80941Smrg unsigned dst_pixel_stride = copy_info->bufferRowLength 444b8e80941Smrg ? copy_info->bufferRowLength 445b8e80941Smrg : copy_info->imageExtent.width; 446b8e80941Smrg dst_pitch = dst_pixel_stride * vk_format_get_blocksize(format); 447b8e80941Smrg assert(!(dst_pitch & 63)); 448b8e80941Smrg assert(!(dst_va & 63)); 449b8e80941Smrg } 450b8e80941Smrg 451b8e80941Smrg 452b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 48); 453b8e80941Smrg 454b8e80941Smrg /* 455b8e80941Smrg * Emit source: 456b8e80941Smrg */ 457b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_PS_2D_SRC_INFO, 13); 458b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 459b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(rb_fmt) | 460b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(src_image->tile_mode) | 461b8e80941Smrg A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(WZYX) | 0x500000); 462b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 463b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_WIDTH(src_image->extent.width) | 464b8e80941Smrg A6XX_SP_PS_2D_SRC_SIZE_HEIGHT( 465b8e80941Smrg src_image->extent.height)); /* SP_PS_2D_SRC_SIZE */ 466b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, src_va); 467b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(src_pitch)); 468b8e80941Smrg 469b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 470b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 471b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 472b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 473b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 474b8e80941Smrg 475b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 476b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 477b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 478b8e80941Smrg 479b8e80941Smrg /* 480b8e80941Smrg * Emit destination: 481b8e80941Smrg */ 482b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_DST_INFO, 9); 483b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(rb_fmt) | 484b8e80941Smrg A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) | 485b8e80941Smrg A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX)); 486b8e80941Smrg tu_cs_emit_qw(&cmdbuf->cs, dst_va); 487b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_RB_2D_DST_SIZE_PITCH(dst_pitch)); 488b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 489b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 490b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 491b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 492b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x00000000); 493b8e80941Smrg 494b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_SRC_TL_X, 4); 495b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_X_X(copy_info->imageOffset.x)); 496b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 497b8e80941Smrg A6XX_GRAS_2D_SRC_BR_X_X(copy_info->imageOffset.x + 498b8e80941Smrg copy_info->imageExtent.width - 1)); 499b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A6XX_GRAS_2D_SRC_TL_Y_Y(copy_info->imageOffset.y)); 500b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 501b8e80941Smrg A6XX_GRAS_2D_SRC_BR_Y_Y(copy_info->imageOffset.y + 502b8e80941Smrg copy_info->imageExtent.height - 1)); 503b8e80941Smrg 504b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_DST_TL, 2); 505b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 506b8e80941Smrg A6XX_GRAS_2D_DST_TL_X(dst_offset) | A6XX_GRAS_2D_DST_TL_Y(0)); 507b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 508b8e80941Smrg A6XX_GRAS_2D_DST_BR_X(dst_offset + copy_info->imageExtent.width - 1) | 509b8e80941Smrg A6XX_GRAS_2D_DST_BR_Y(copy_info->imageExtent.height - 1)); 510b8e80941Smrg 511b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_EVENT_WRITE, 1); 512b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x3f); 513b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 514b8e80941Smrg 515b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8C01, 1); 516b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 517b8e80941Smrg 518b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_SP_2D_SRC_FORMAT, 1); 519b8e80941Smrg tu_cs_emit(&cmdbuf->cs, tu6_sp_2d_src_format(format)); 520b8e80941Smrg 521b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 522b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0x01000000); 523b8e80941Smrg 524b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_BLIT, 1); 525b8e80941Smrg tu_cs_emit(&cmdbuf->cs, CP_BLIT_0_OP(BLIT_OP_SCALE)); 526b8e80941Smrg 527b8e80941Smrg tu_cs_emit_wfi(&cmdbuf->cs); 528b8e80941Smrg 529b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_UNKNOWN_8E04, 1); 530b8e80941Smrg tu_cs_emit(&cmdbuf->cs, 0); 531b8e80941Smrg} 532b8e80941Smrg 533b8e80941Smrgstatic void 534b8e80941Smrgtu_copy_image_to_buffer(struct tu_cmd_buffer *cmdbuf, 535b8e80941Smrg struct tu_image *src_image, 536b8e80941Smrg struct tu_buffer *dst_buffer, 537b8e80941Smrg const VkBufferImageCopy *copy_info) 538b8e80941Smrg{ 539b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, src_image->bo, MSM_SUBMIT_BO_READ); 540b8e80941Smrg tu_bo_list_add(&cmdbuf->bo_list, dst_buffer->bo, MSM_SUBMIT_BO_WRITE); 541b8e80941Smrg 542b8e80941Smrg /* general setup */ 543b8e80941Smrg tu_dma_prepare(cmdbuf); 544b8e80941Smrg 545b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 6); 546b8e80941Smrg 547b8e80941Smrg /* buffer copy setup */ 548b8e80941Smrg tu_cs_emit_pkt7(&cmdbuf->cs, CP_SET_MARKER, 1); 549b8e80941Smrg tu_cs_emit(&cmdbuf->cs, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE)); 550b8e80941Smrg 551b8e80941Smrg VkFormat format = src_image->vk_format; 552b8e80941Smrg const enum a6xx_color_fmt rb_fmt = tu6_get_native_format(format)->rb; 553b8e80941Smrg 554b8e80941Smrg unsigned dst_pixel_stride = copy_info->bufferRowLength 555b8e80941Smrg ? copy_info->bufferRowLength 556b8e80941Smrg : copy_info->imageExtent.width; 557b8e80941Smrg unsigned cpp = vk_format_get_blocksize(format); 558b8e80941Smrg unsigned dst_pitch = dst_pixel_stride * cpp; 559b8e80941Smrg 560b8e80941Smrg 561b8e80941Smrg const uint32_t blit_cntl = blit_control(rb_fmt) | 0x20000000; 562b8e80941Smrg 563b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_BLIT_CNTL, 1); 564b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 565b8e80941Smrg 566b8e80941Smrg tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_BLIT_CNTL, 1); 567b8e80941Smrg tu_cs_emit(&cmdbuf->cs, blit_cntl); 568b8e80941Smrg 569b8e80941Smrg for (unsigned layer_offset = 0; layer_offset < copy_info->imageSubresource.layerCount; ++layer_offset) { 570b8e80941Smrg unsigned layer = copy_info->imageSubresource.baseArrayLayer + layer_offset; 571b8e80941Smrg uint64_t dst_va = dst_buffer->bo->iova + dst_buffer->bo_offset + copy_info->bufferOffset + layer_offset * copy_info->bufferImageHeight * dst_pitch; 572b8e80941Smrg 573b8e80941Smrg if ((dst_pitch & 63) || (dst_va & 63)) { 574b8e80941Smrg /* Do a per line copy */ 575b8e80941Smrg VkBufferImageCopy line_copy_info = *copy_info; 576b8e80941Smrg line_copy_info.imageExtent.height = 1; 577b8e80941Smrg for (unsigned r = 0; r < copy_info->imageExtent.height; ++r) { 578b8e80941Smrg /* 579b8e80941Smrg * if dst_va is not aligned the line copy will need to adjust. Give it 580b8e80941Smrg * room to do so. 581b8e80941Smrg */ 582b8e80941Smrg unsigned max_width = 16384 - (dst_va & 0x3f) ? 64 : 0; 583b8e80941Smrg line_copy_info.imageOffset.x = copy_info->imageOffset.x; 584b8e80941Smrg line_copy_info.imageExtent.width = copy_info->imageExtent.width; 585b8e80941Smrg 586b8e80941Smrg for (unsigned c = 0; c < copy_info->imageExtent.width; c += max_width) { 587b8e80941Smrg tu_copy_image_to_buffer_step(cmdbuf, src_image, dst_buffer, &line_copy_info, format, layer, dst_va + c * cpp); 588b8e80941Smrg 589b8e80941Smrg line_copy_info.imageOffset.x += max_width; 590b8e80941Smrg line_copy_info.imageExtent.width -= max_width; 591b8e80941Smrg } 592b8e80941Smrg 593b8e80941Smrg line_copy_info.imageOffset.y++; 594b8e80941Smrg dst_va += dst_pitch; 595b8e80941Smrg } 596b8e80941Smrg } else { 597b8e80941Smrg tu_copy_image_to_buffer_step(cmdbuf, src_image, dst_buffer, copy_info, format, layer, dst_va); 598b8e80941Smrg } 599b8e80941Smrg } 600b8e80941Smrg 601b8e80941Smrg tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 15); 602b8e80941Smrg 603b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, 0x1d, true); 604b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, FACENESS_FLUSH, true); 605b8e80941Smrg tu6_emit_event_write(cmdbuf, &cmdbuf->cs, CACHE_FLUSH_TS, true); 606b8e80941Smrg} 607b8e80941Smrg 608b8e80941Smrgvoid 609b8e80941Smrgtu_CmdCopyBuffer(VkCommandBuffer commandBuffer, 610b8e80941Smrg VkBuffer srcBuffer, 611b8e80941Smrg VkBuffer destBuffer, 612b8e80941Smrg uint32_t regionCount, 613b8e80941Smrg const VkBufferCopy *pRegions) 614b8e80941Smrg{ 615b8e80941Smrg TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer); 616b8e80941Smrg TU_FROM_HANDLE(tu_buffer, src_buffer, srcBuffer); 617b8e80941Smrg TU_FROM_HANDLE(tu_buffer, dst_buffer, destBuffer); 618b8e80941Smrg 619b8e80941Smrg for (unsigned i = 0; i < regionCount; ++i) { 620b8e80941Smrg uint64_t src_offset = src_buffer->bo_offset + pRegions[i].srcOffset; 621b8e80941Smrg uint64_t dst_offset = dst_buffer->bo_offset + pRegions[i].dstOffset; 622b8e80941Smrg 623b8e80941Smrg tu_copy_buffer(cmdbuf, src_buffer->bo, src_offset, dst_buffer->bo, 624b8e80941Smrg dst_offset, pRegions[i].size); 625b8e80941Smrg } 626b8e80941Smrg} 627b8e80941Smrg 628b8e80941Smrgvoid 629b8e80941Smrgtu_CmdCopyBufferToImage(VkCommandBuffer commandBuffer, 630b8e80941Smrg VkBuffer srcBuffer, 631b8e80941Smrg VkImage destImage, 632b8e80941Smrg VkImageLayout destImageLayout, 633b8e80941Smrg uint32_t regionCount, 634b8e80941Smrg const VkBufferImageCopy *pRegions) 635b8e80941Smrg{ 636b8e80941Smrg TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer); 637b8e80941Smrg TU_FROM_HANDLE(tu_image, dest_image, destImage); 638b8e80941Smrg TU_FROM_HANDLE(tu_buffer, src_buffer, srcBuffer); 639b8e80941Smrg 640b8e80941Smrg for (unsigned i = 0; i < regionCount; ++i) { 641b8e80941Smrg tu_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image, 642b8e80941Smrg pRegions + i); 643b8e80941Smrg } 644b8e80941Smrg} 645b8e80941Smrg 646b8e80941Smrgvoid 647b8e80941Smrgtu_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, 648b8e80941Smrg VkImage srcImage, 649b8e80941Smrg VkImageLayout srcImageLayout, 650b8e80941Smrg VkBuffer destBuffer, 651b8e80941Smrg uint32_t regionCount, 652b8e80941Smrg const VkBufferImageCopy *pRegions) 653b8e80941Smrg{ 654b8e80941Smrg TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer); 655b8e80941Smrg TU_FROM_HANDLE(tu_image, src_image, srcImage); 656b8e80941Smrg TU_FROM_HANDLE(tu_buffer, dst_buffer, destBuffer); 657b8e80941Smrg 658b8e80941Smrg for (unsigned i = 0; i < regionCount; ++i) { 659b8e80941Smrg tu_copy_image_to_buffer(cmd_buffer, src_image, dst_buffer, 660b8e80941Smrg pRegions + i); 661b8e80941Smrg } 662b8e80941Smrg} 663b8e80941Smrg 664b8e80941Smrgstatic void 665b8e80941Smrgmeta_copy_image(struct tu_cmd_buffer *cmd_buffer, 666b8e80941Smrg struct tu_image *src_image, 667b8e80941Smrg VkImageLayout src_image_layout, 668b8e80941Smrg struct tu_image *dest_image, 669b8e80941Smrg VkImageLayout dest_image_layout, 670b8e80941Smrg uint32_t regionCount, 671b8e80941Smrg const VkImageCopy *pRegions) 672b8e80941Smrg{ 673b8e80941Smrg} 674b8e80941Smrg 675b8e80941Smrgvoid 676b8e80941Smrgtu_CmdCopyImage(VkCommandBuffer commandBuffer, 677b8e80941Smrg VkImage srcImage, 678b8e80941Smrg VkImageLayout srcImageLayout, 679b8e80941Smrg VkImage destImage, 680b8e80941Smrg VkImageLayout destImageLayout, 681b8e80941Smrg uint32_t regionCount, 682b8e80941Smrg const VkImageCopy *pRegions) 683b8e80941Smrg{ 684b8e80941Smrg TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer); 685b8e80941Smrg TU_FROM_HANDLE(tu_image, src_image, srcImage); 686b8e80941Smrg TU_FROM_HANDLE(tu_image, dest_image, destImage); 687b8e80941Smrg 688b8e80941Smrg meta_copy_image(cmd_buffer, src_image, srcImageLayout, dest_image, 689b8e80941Smrg destImageLayout, regionCount, pRegions); 690b8e80941Smrg} 691