turnip: rework format helpers
[mesa.git] / src / freedreno / vulkan / tu_meta_copy.c
1 /*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "tu_private.h"
25
26 #include "a6xx.xml.h"
27 #include "adreno_common.xml.h"
28 #include "adreno_pm4.xml.h"
29
30 #include "vk_format.h"
31
32 #include "tu_cs.h"
33 #include "tu_blit.h"
34
35 static void
36 tu_copy_buffer(struct tu_cmd_buffer *cmd,
37 struct tu_buffer *src,
38 struct tu_buffer *dst,
39 const VkBufferCopy *region)
40 {
41 tu_bo_list_add(&cmd->bo_list, src->bo, MSM_SUBMIT_BO_READ);
42 tu_bo_list_add(&cmd->bo_list, dst->bo, MSM_SUBMIT_BO_WRITE);
43
44 tu_blit(cmd, &cmd->cs, &(struct tu_blit) {
45 .dst = {
46 .fmt = VK_FORMAT_R8_UNORM,
47 .va = tu_buffer_iova(dst) + region->dstOffset,
48 .width = region->size,
49 .height = 1,
50 .samples = 1,
51 },
52 .src = {
53 .fmt = VK_FORMAT_R8_UNORM,
54 .va = tu_buffer_iova(src) + region->srcOffset,
55 .width = region->size,
56 .height = 1,
57 .samples = 1,
58 },
59 .layers = 1,
60 .type = TU_BLIT_COPY,
61 .buffer = true,
62 });
63 }
64
65 static struct tu_blit_surf
66 tu_blit_buffer(struct tu_buffer *buffer,
67 VkFormat format,
68 const VkBufferImageCopy *info)
69 {
70 if (info->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
71 format = VK_FORMAT_R8_UNORM;
72
73 unsigned pitch = (info->bufferRowLength ?: info->imageExtent.width) *
74 vk_format_get_blocksize(format);
75
76 return (struct tu_blit_surf) {
77 .fmt = format,
78 .tile_mode = TILE6_LINEAR,
79 .va = tu_buffer_iova(buffer) + info->bufferOffset,
80 .pitch = pitch,
81 .layer_size = (info->bufferImageHeight ?: info->imageExtent.height) * pitch / vk_format_get_blockwidth(format) / vk_format_get_blockheight(format),
82 .width = info->imageExtent.width,
83 .height = info->imageExtent.height,
84 .samples = 1,
85 };
86 }
87
88 static void
89 tu_copy_buffer_to_image(struct tu_cmd_buffer *cmdbuf,
90 struct tu_buffer *src_buffer,
91 struct tu_image *dst_image,
92 const VkBufferImageCopy *info)
93 {
94 if (info->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
95 vk_format_get_blocksize(dst_image->vk_format) == 4) {
96 tu_finishme("aspect mask\n");
97 return;
98 }
99
100 tu_blit(cmdbuf, &cmdbuf->cs, &(struct tu_blit) {
101 .dst = tu_blit_surf_ext(dst_image, info->imageSubresource, info->imageOffset, info->imageExtent),
102 .src = tu_blit_buffer(src_buffer, dst_image->vk_format, info),
103 .layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
104 .type = TU_BLIT_COPY,
105 });
106 }
107
108 static void
109 tu_copy_image_to_buffer(struct tu_cmd_buffer *cmdbuf,
110 struct tu_image *src_image,
111 struct tu_buffer *dst_buffer,
112 const VkBufferImageCopy *info)
113 {
114 tu_blit(cmdbuf, &cmdbuf->cs, &(struct tu_blit) {
115 .dst = tu_blit_buffer(dst_buffer, src_image->vk_format, info),
116 .src = tu_blit_surf_ext(src_image, info->imageSubresource, info->imageOffset, info->imageExtent),
117 .layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
118 .type = TU_BLIT_COPY,
119 });
120 }
121
122 static void
123 tu_copy_image_to_image(struct tu_cmd_buffer *cmdbuf,
124 struct tu_image *src_image,
125 struct tu_image *dst_image,
126 const VkImageCopy *info)
127 {
128 if ((info->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
129 vk_format_get_blocksize(dst_image->vk_format) == 4) ||
130 (info->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
131 vk_format_get_blocksize(src_image->vk_format) == 4)) {
132 tu_finishme("aspect mask\n");
133 return;
134 }
135
136 tu_blit(cmdbuf, &cmdbuf->cs, &(struct tu_blit) {
137 .dst = tu_blit_surf_ext(dst_image, info->dstSubresource, info->dstOffset, info->extent),
138 .src = tu_blit_surf_ext(src_image, info->srcSubresource, info->srcOffset, info->extent),
139 .layers = info->extent.depth,
140 .type = TU_BLIT_COPY,
141 });
142 }
143
144 void
145 tu_CmdCopyBuffer(VkCommandBuffer commandBuffer,
146 VkBuffer srcBuffer,
147 VkBuffer destBuffer,
148 uint32_t regionCount,
149 const VkBufferCopy *pRegions)
150 {
151 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
152 TU_FROM_HANDLE(tu_buffer, src_buffer, srcBuffer);
153 TU_FROM_HANDLE(tu_buffer, dst_buffer, destBuffer);
154
155 for (unsigned i = 0; i < regionCount; ++i)
156 tu_copy_buffer(cmdbuf, src_buffer, dst_buffer, &pRegions[i]);
157 }
158
159 void
160 tu_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
161 VkBuffer srcBuffer,
162 VkImage destImage,
163 VkImageLayout destImageLayout,
164 uint32_t regionCount,
165 const VkBufferImageCopy *pRegions)
166 {
167 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
168 TU_FROM_HANDLE(tu_image, dst_image, destImage);
169 TU_FROM_HANDLE(tu_buffer, src_buffer, srcBuffer);
170
171 tu_bo_list_add(&cmdbuf->bo_list, src_buffer->bo, MSM_SUBMIT_BO_READ);
172 tu_bo_list_add(&cmdbuf->bo_list, dst_image->bo, MSM_SUBMIT_BO_WRITE);
173
174 for (unsigned i = 0; i < regionCount; ++i)
175 tu_copy_buffer_to_image(cmdbuf, src_buffer, dst_image, pRegions + i);
176 }
177
178 void
179 tu_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer,
180 VkImage srcImage,
181 VkImageLayout srcImageLayout,
182 VkBuffer destBuffer,
183 uint32_t regionCount,
184 const VkBufferImageCopy *pRegions)
185 {
186 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
187 TU_FROM_HANDLE(tu_image, src_image, srcImage);
188 TU_FROM_HANDLE(tu_buffer, dst_buffer, destBuffer);
189
190 tu_bo_list_add(&cmdbuf->bo_list, src_image->bo, MSM_SUBMIT_BO_READ);
191 tu_bo_list_add(&cmdbuf->bo_list, dst_buffer->bo, MSM_SUBMIT_BO_WRITE);
192
193 for (unsigned i = 0; i < regionCount; ++i)
194 tu_copy_image_to_buffer(cmdbuf, src_image, dst_buffer, pRegions + i);
195 }
196
197 void
198 tu_CmdCopyImage(VkCommandBuffer commandBuffer,
199 VkImage srcImage,
200 VkImageLayout srcImageLayout,
201 VkImage destImage,
202 VkImageLayout destImageLayout,
203 uint32_t regionCount,
204 const VkImageCopy *pRegions)
205 {
206 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
207 TU_FROM_HANDLE(tu_image, src_image, srcImage);
208 TU_FROM_HANDLE(tu_image, dst_image, destImage);
209
210 tu_bo_list_add(&cmdbuf->bo_list, src_image->bo, MSM_SUBMIT_BO_READ);
211 tu_bo_list_add(&cmdbuf->bo_list, dst_image->bo, MSM_SUBMIT_BO_WRITE);
212
213 for (uint32_t i = 0; i < regionCount; ++i)
214 tu_copy_image_to_image(cmdbuf, src_image, dst_image, pRegions + i);
215 }