1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <assert.h>
25*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
26*61046927SAndroid Build Coastguard Worker #include <stddef.h>
27*61046927SAndroid Build Coastguard Worker #include <stdint.h>
28*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #include "pvr_blit.h"
31*61046927SAndroid Build Coastguard Worker #include "pvr_clear.h"
32*61046927SAndroid Build Coastguard Worker #include "pvr_csb.h"
33*61046927SAndroid Build Coastguard Worker #include "pvr_formats.h"
34*61046927SAndroid Build Coastguard Worker #include "pvr_job_transfer.h"
35*61046927SAndroid Build Coastguard Worker #include "pvr_private.h"
36*61046927SAndroid Build Coastguard Worker #include "pvr_shader_factory.h"
37*61046927SAndroid Build Coastguard Worker #include "pvr_static_shaders.h"
38*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
39*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
40*61046927SAndroid Build Coastguard Worker #include "util/list.h"
41*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
42*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
43*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
44*61046927SAndroid Build Coastguard Worker #include "vk_command_buffer.h"
45*61046927SAndroid Build Coastguard Worker #include "vk_command_pool.h"
46*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
47*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker /* TODO: Investigate where this limit comes from. */
50*61046927SAndroid Build Coastguard Worker #define PVR_MAX_TRANSFER_SIZE_IN_TEXELS 2048U
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker static struct pvr_transfer_cmd *
pvr_transfer_cmd_alloc(struct pvr_cmd_buffer * cmd_buffer)53*61046927SAndroid Build Coastguard Worker pvr_transfer_cmd_alloc(struct pvr_cmd_buffer *cmd_buffer)
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker transfer_cmd = vk_zalloc(&cmd_buffer->vk.pool->alloc,
58*61046927SAndroid Build Coastguard Worker sizeof(*transfer_cmd),
59*61046927SAndroid Build Coastguard Worker 8U,
60*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
61*61046927SAndroid Build Coastguard Worker if (!transfer_cmd) {
62*61046927SAndroid Build Coastguard Worker vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
63*61046927SAndroid Build Coastguard Worker return NULL;
64*61046927SAndroid Build Coastguard Worker }
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker /* transfer_cmd->mapping_count is already set to zero. */
67*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].filter = PVR_FILTER_POINT;
68*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].resolve_op = PVR_RESOLVE_BLEND;
69*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].addr_mode = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
70*61046927SAndroid Build Coastguard Worker transfer_cmd->cmd_buffer = cmd_buffer;
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker return transfer_cmd;
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker
pvr_setup_buffer_surface(struct pvr_transfer_cmd_surface * surface,VkRect2D * rect,pvr_dev_addr_t dev_addr,VkDeviceSize offset,VkFormat vk_format,VkFormat image_format,uint32_t width,uint32_t height,uint32_t stride)75*61046927SAndroid Build Coastguard Worker static void pvr_setup_buffer_surface(struct pvr_transfer_cmd_surface *surface,
76*61046927SAndroid Build Coastguard Worker VkRect2D *rect,
77*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t dev_addr,
78*61046927SAndroid Build Coastguard Worker VkDeviceSize offset,
79*61046927SAndroid Build Coastguard Worker VkFormat vk_format,
80*61046927SAndroid Build Coastguard Worker VkFormat image_format,
81*61046927SAndroid Build Coastguard Worker uint32_t width,
82*61046927SAndroid Build Coastguard Worker uint32_t height,
83*61046927SAndroid Build Coastguard Worker uint32_t stride)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker enum pipe_format pformat = vk_format_to_pipe_format(image_format);
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker surface->dev_addr = PVR_DEV_ADDR_OFFSET(dev_addr, offset);
88*61046927SAndroid Build Coastguard Worker surface->width = width;
89*61046927SAndroid Build Coastguard Worker surface->height = height;
90*61046927SAndroid Build Coastguard Worker surface->stride = stride;
91*61046927SAndroid Build Coastguard Worker surface->vk_format = vk_format;
92*61046927SAndroid Build Coastguard Worker surface->mem_layout = PVR_MEMLAYOUT_LINEAR;
93*61046927SAndroid Build Coastguard Worker surface->sample_count = 1;
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker /* Initialize rectangle extent. Also, rectangle.offset should be set to
96*61046927SAndroid Build Coastguard Worker * zero, as the offset is already adjusted in the device address above. We
97*61046927SAndroid Build Coastguard Worker * don't explicitly set offset to zero as transfer_cmd is zero allocated.
98*61046927SAndroid Build Coastguard Worker */
99*61046927SAndroid Build Coastguard Worker rect->extent.width = width;
100*61046927SAndroid Build Coastguard Worker rect->extent.height = height;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker if (util_format_is_compressed(pformat)) {
103*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(pformat);
104*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(pformat);
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker surface->width = MAX2(1U, DIV_ROUND_UP(surface->width, block_width));
107*61046927SAndroid Build Coastguard Worker surface->height = MAX2(1U, DIV_ROUND_UP(surface->height, block_height));
108*61046927SAndroid Build Coastguard Worker surface->stride = MAX2(1U, DIV_ROUND_UP(surface->stride, block_width));
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker rect->offset.x /= block_width;
111*61046927SAndroid Build Coastguard Worker rect->offset.y /= block_height;
112*61046927SAndroid Build Coastguard Worker rect->extent.width =
113*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(rect->extent.width, block_width));
114*61046927SAndroid Build Coastguard Worker rect->extent.height =
115*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(rect->extent.height, block_height));
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker
pvr_get_raw_copy_format(VkFormat format)119*61046927SAndroid Build Coastguard Worker VkFormat pvr_get_raw_copy_format(VkFormat format)
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker switch (vk_format_get_blocksize(format)) {
122*61046927SAndroid Build Coastguard Worker case 1:
123*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8_UINT;
124*61046927SAndroid Build Coastguard Worker case 2:
125*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8_UINT;
126*61046927SAndroid Build Coastguard Worker case 3:
127*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8B8_UINT;
128*61046927SAndroid Build Coastguard Worker case 4:
129*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32_UINT;
130*61046927SAndroid Build Coastguard Worker case 6:
131*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R16G16B16_UINT;
132*61046927SAndroid Build Coastguard Worker case 8:
133*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32G32_UINT;
134*61046927SAndroid Build Coastguard Worker case 12:
135*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32G32B32_UINT;
136*61046927SAndroid Build Coastguard Worker case 16:
137*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R32G32B32A32_UINT;
138*61046927SAndroid Build Coastguard Worker default:
139*61046927SAndroid Build Coastguard Worker unreachable("Unhandled copy block size.");
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker }
142*61046927SAndroid Build Coastguard Worker
pvr_setup_transfer_surface(struct pvr_device * device,struct pvr_transfer_cmd_surface * surface,VkRect2D * rect,const struct pvr_image * image,uint32_t array_layer,uint32_t mip_level,const VkOffset3D * offset,const VkExtent3D * extent,float fdepth,VkFormat format,VkImageAspectFlags aspect_mask)143*61046927SAndroid Build Coastguard Worker static void pvr_setup_transfer_surface(struct pvr_device *device,
144*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface *surface,
145*61046927SAndroid Build Coastguard Worker VkRect2D *rect,
146*61046927SAndroid Build Coastguard Worker const struct pvr_image *image,
147*61046927SAndroid Build Coastguard Worker uint32_t array_layer,
148*61046927SAndroid Build Coastguard Worker uint32_t mip_level,
149*61046927SAndroid Build Coastguard Worker const VkOffset3D *offset,
150*61046927SAndroid Build Coastguard Worker const VkExtent3D *extent,
151*61046927SAndroid Build Coastguard Worker float fdepth,
152*61046927SAndroid Build Coastguard Worker VkFormat format,
153*61046927SAndroid Build Coastguard Worker VkImageAspectFlags aspect_mask)
154*61046927SAndroid Build Coastguard Worker {
155*61046927SAndroid Build Coastguard Worker const uint32_t height = MAX2(image->vk.extent.height >> mip_level, 1U);
156*61046927SAndroid Build Coastguard Worker const uint32_t width = MAX2(image->vk.extent.width >> mip_level, 1U);
157*61046927SAndroid Build Coastguard Worker enum pipe_format image_pformat = vk_format_to_pipe_format(image->vk.format);
158*61046927SAndroid Build Coastguard Worker enum pipe_format pformat = vk_format_to_pipe_format(format);
159*61046927SAndroid Build Coastguard Worker const VkImageSubresource sub_resource = {
160*61046927SAndroid Build Coastguard Worker .aspectMask = aspect_mask,
161*61046927SAndroid Build Coastguard Worker .mipLevel = mip_level,
162*61046927SAndroid Build Coastguard Worker .arrayLayer = array_layer,
163*61046927SAndroid Build Coastguard Worker };
164*61046927SAndroid Build Coastguard Worker VkSubresourceLayout info;
165*61046927SAndroid Build Coastguard Worker uint32_t depth;
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker if (image->memlayout == PVR_MEMLAYOUT_3DTWIDDLED)
168*61046927SAndroid Build Coastguard Worker depth = MAX2(image->vk.extent.depth >> mip_level, 1U);
169*61046927SAndroid Build Coastguard Worker else
170*61046927SAndroid Build Coastguard Worker depth = 1U;
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker pvr_get_image_subresource_layout(image, &sub_resource, &info);
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker surface->dev_addr = PVR_DEV_ADDR_OFFSET(image->dev_addr, info.offset);
175*61046927SAndroid Build Coastguard Worker surface->width = width;
176*61046927SAndroid Build Coastguard Worker surface->height = height;
177*61046927SAndroid Build Coastguard Worker surface->depth = depth;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker assert(info.rowPitch % vk_format_get_blocksize(format) == 0);
180*61046927SAndroid Build Coastguard Worker surface->stride = info.rowPitch / vk_format_get_blocksize(format);
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker surface->vk_format = format;
183*61046927SAndroid Build Coastguard Worker surface->mem_layout = image->memlayout;
184*61046927SAndroid Build Coastguard Worker surface->sample_count = image->vk.samples;
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker if (image->memlayout == PVR_MEMLAYOUT_3DTWIDDLED)
187*61046927SAndroid Build Coastguard Worker surface->z_position = fdepth;
188*61046927SAndroid Build Coastguard Worker else
189*61046927SAndroid Build Coastguard Worker surface->dev_addr.addr += info.depthPitch * ((uint32_t)fdepth);
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker rect->offset.x = offset->x;
192*61046927SAndroid Build Coastguard Worker rect->offset.y = offset->y;
193*61046927SAndroid Build Coastguard Worker rect->extent.width = extent->width;
194*61046927SAndroid Build Coastguard Worker rect->extent.height = extent->height;
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker if (util_format_is_compressed(image_pformat) &&
197*61046927SAndroid Build Coastguard Worker !util_format_is_compressed(pformat)) {
198*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(image_pformat);
199*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(image_pformat);
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker surface->width = MAX2(1U, DIV_ROUND_UP(surface->width, block_width));
202*61046927SAndroid Build Coastguard Worker surface->height = MAX2(1U, DIV_ROUND_UP(surface->height, block_height));
203*61046927SAndroid Build Coastguard Worker surface->stride = MAX2(1U, DIV_ROUND_UP(surface->stride, block_width));
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker rect->offset.x /= block_width;
206*61046927SAndroid Build Coastguard Worker rect->offset.y /= block_height;
207*61046927SAndroid Build Coastguard Worker rect->extent.width =
208*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(rect->extent.width, block_width));
209*61046927SAndroid Build Coastguard Worker rect->extent.height =
210*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(rect->extent.height, block_height));
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
pvr_CmdBlitImage2(VkCommandBuffer commandBuffer,const VkBlitImageInfo2 * pBlitImageInfo)214*61046927SAndroid Build Coastguard Worker void pvr_CmdBlitImage2(VkCommandBuffer commandBuffer,
215*61046927SAndroid Build Coastguard Worker const VkBlitImageInfo2 *pBlitImageInfo)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
218*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, src, pBlitImageInfo->srcImage);
219*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, dst, pBlitImageInfo->dstImage);
220*61046927SAndroid Build Coastguard Worker struct pvr_device *device = cmd_buffer->device;
221*61046927SAndroid Build Coastguard Worker enum pvr_filter filter = PVR_FILTER_DONTCARE;
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker if (pBlitImageInfo->filter == VK_FILTER_LINEAR)
226*61046927SAndroid Build Coastguard Worker filter = PVR_FILTER_LINEAR;
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < pBlitImageInfo->regionCount; i++) {
229*61046927SAndroid Build Coastguard Worker const VkImageBlit2 *region = &pBlitImageInfo->pRegions[i];
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker assert(region->srcSubresource.layerCount ==
232*61046927SAndroid Build Coastguard Worker region->dstSubresource.layerCount);
233*61046927SAndroid Build Coastguard Worker const bool inverted_dst_z =
234*61046927SAndroid Build Coastguard Worker (region->dstOffsets[1].z < region->dstOffsets[0].z);
235*61046927SAndroid Build Coastguard Worker const bool inverted_src_z =
236*61046927SAndroid Build Coastguard Worker (region->srcOffsets[1].z < region->srcOffsets[0].z);
237*61046927SAndroid Build Coastguard Worker const uint32_t min_src_z = inverted_src_z ? region->srcOffsets[1].z
238*61046927SAndroid Build Coastguard Worker : region->srcOffsets[0].z;
239*61046927SAndroid Build Coastguard Worker const uint32_t max_src_z = inverted_src_z ? region->srcOffsets[0].z
240*61046927SAndroid Build Coastguard Worker : region->srcOffsets[1].z;
241*61046927SAndroid Build Coastguard Worker const uint32_t min_dst_z = inverted_dst_z ? region->dstOffsets[1].z
242*61046927SAndroid Build Coastguard Worker : region->dstOffsets[0].z;
243*61046927SAndroid Build Coastguard Worker const uint32_t max_dst_z = inverted_dst_z ? region->dstOffsets[0].z
244*61046927SAndroid Build Coastguard Worker : region->dstOffsets[1].z;
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker const uint32_t src_width =
247*61046927SAndroid Build Coastguard Worker region->srcOffsets[1].x - region->srcOffsets[0].x;
248*61046927SAndroid Build Coastguard Worker const uint32_t src_height =
249*61046927SAndroid Build Coastguard Worker region->srcOffsets[1].y - region->srcOffsets[0].y;
250*61046927SAndroid Build Coastguard Worker uint32_t dst_width;
251*61046927SAndroid Build Coastguard Worker uint32_t dst_height;
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker float initial_depth_offset;
254*61046927SAndroid Build Coastguard Worker VkExtent3D src_extent;
255*61046927SAndroid Build Coastguard Worker VkExtent3D dst_extent;
256*61046927SAndroid Build Coastguard Worker VkOffset3D dst_offset = region->dstOffsets[0];
257*61046927SAndroid Build Coastguard Worker float z_slice_stride;
258*61046927SAndroid Build Coastguard Worker bool flip_x;
259*61046927SAndroid Build Coastguard Worker bool flip_y;
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker if (region->dstOffsets[1].x > region->dstOffsets[0].x) {
262*61046927SAndroid Build Coastguard Worker dst_width = region->dstOffsets[1].x - region->dstOffsets[0].x;
263*61046927SAndroid Build Coastguard Worker flip_x = false;
264*61046927SAndroid Build Coastguard Worker } else {
265*61046927SAndroid Build Coastguard Worker dst_width = region->dstOffsets[0].x - region->dstOffsets[1].x;
266*61046927SAndroid Build Coastguard Worker flip_x = true;
267*61046927SAndroid Build Coastguard Worker dst_offset.x = region->dstOffsets[1].x;
268*61046927SAndroid Build Coastguard Worker }
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker if (region->dstOffsets[1].y > region->dstOffsets[0].y) {
271*61046927SAndroid Build Coastguard Worker dst_height = region->dstOffsets[1].y - region->dstOffsets[0].y;
272*61046927SAndroid Build Coastguard Worker flip_y = false;
273*61046927SAndroid Build Coastguard Worker } else {
274*61046927SAndroid Build Coastguard Worker dst_height = region->dstOffsets[0].y - region->dstOffsets[1].y;
275*61046927SAndroid Build Coastguard Worker flip_y = true;
276*61046927SAndroid Build Coastguard Worker dst_offset.y = region->dstOffsets[1].y;
277*61046927SAndroid Build Coastguard Worker }
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker /* If any of the extent regions is zero, then reject the blit and
280*61046927SAndroid Build Coastguard Worker * continue.
281*61046927SAndroid Build Coastguard Worker */
282*61046927SAndroid Build Coastguard Worker if (!src_width || !src_height || !dst_width || !dst_height ||
283*61046927SAndroid Build Coastguard Worker !(max_dst_z - min_dst_z) || !(max_src_z - min_src_z)) {
284*61046927SAndroid Build Coastguard Worker mesa_loge("BlitImage: Region %i has an area of zero", i);
285*61046927SAndroid Build Coastguard Worker continue;
286*61046927SAndroid Build Coastguard Worker }
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker src_extent = (VkExtent3D){
289*61046927SAndroid Build Coastguard Worker .width = src_width,
290*61046927SAndroid Build Coastguard Worker .height = src_height,
291*61046927SAndroid Build Coastguard Worker .depth = 0U,
292*61046927SAndroid Build Coastguard Worker };
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker dst_extent = (VkExtent3D){
295*61046927SAndroid Build Coastguard Worker .width = dst_width,
296*61046927SAndroid Build Coastguard Worker .height = dst_height,
297*61046927SAndroid Build Coastguard Worker .depth = 0U,
298*61046927SAndroid Build Coastguard Worker };
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker /* The z_position of a transfer surface is intended to be in the range
301*61046927SAndroid Build Coastguard Worker * of 0.0f <= z_position <= depth. It will be used as a texture coordinate
302*61046927SAndroid Build Coastguard Worker * in the source surface for cases where linear filtering is enabled, so
303*61046927SAndroid Build Coastguard Worker * the fractional part will need to represent the exact midpoint of a z
304*61046927SAndroid Build Coastguard Worker * slice range in the source texture, as it maps to each destination
305*61046927SAndroid Build Coastguard Worker * slice.
306*61046927SAndroid Build Coastguard Worker *
307*61046927SAndroid Build Coastguard Worker * For destination surfaces, the fractional part is discarded, so
308*61046927SAndroid Build Coastguard Worker * we can safely pass the slice index.
309*61046927SAndroid Build Coastguard Worker */
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker /* Calculate the ratio of z slices in our source region to that of our
312*61046927SAndroid Build Coastguard Worker * destination region, to get the number of z slices in our source region
313*61046927SAndroid Build Coastguard Worker * to iterate over for each destination slice.
314*61046927SAndroid Build Coastguard Worker *
315*61046927SAndroid Build Coastguard Worker * If our destination region is inverted, we iterate backwards.
316*61046927SAndroid Build Coastguard Worker */
317*61046927SAndroid Build Coastguard Worker z_slice_stride =
318*61046927SAndroid Build Coastguard Worker (inverted_dst_z ? -1.0f : 1.0f) *
319*61046927SAndroid Build Coastguard Worker ((float)(max_src_z - min_src_z) / (float)(max_dst_z - min_dst_z));
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker /* Offset the initial depth offset by half of the z slice stride, into the
322*61046927SAndroid Build Coastguard Worker * blit region's z range.
323*61046927SAndroid Build Coastguard Worker */
324*61046927SAndroid Build Coastguard Worker initial_depth_offset =
325*61046927SAndroid Build Coastguard Worker (inverted_dst_z ? max_src_z : min_src_z) + (0.5f * z_slice_stride);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0U; j < region->srcSubresource.layerCount; j++) {
328*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface src_surface = { 0 };
329*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface dst_surface = { 0 };
330*61046927SAndroid Build Coastguard Worker VkRect2D src_rect;
331*61046927SAndroid Build Coastguard Worker VkRect2D dst_rect;
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker /* Get the subresource info for the src and dst images, this is
334*61046927SAndroid Build Coastguard Worker * required when incrementing the address of the depth slice used by
335*61046927SAndroid Build Coastguard Worker * the transfer surface.
336*61046927SAndroid Build Coastguard Worker */
337*61046927SAndroid Build Coastguard Worker VkSubresourceLayout src_info, dst_info;
338*61046927SAndroid Build Coastguard Worker const VkImageSubresource src_sub_resource = {
339*61046927SAndroid Build Coastguard Worker .aspectMask = region->srcSubresource.aspectMask,
340*61046927SAndroid Build Coastguard Worker .mipLevel = region->srcSubresource.mipLevel,
341*61046927SAndroid Build Coastguard Worker .arrayLayer = region->srcSubresource.baseArrayLayer + j,
342*61046927SAndroid Build Coastguard Worker };
343*61046927SAndroid Build Coastguard Worker const VkImageSubresource dst_sub_resource = {
344*61046927SAndroid Build Coastguard Worker .aspectMask = region->dstSubresource.aspectMask,
345*61046927SAndroid Build Coastguard Worker .mipLevel = region->dstSubresource.mipLevel,
346*61046927SAndroid Build Coastguard Worker .arrayLayer = region->dstSubresource.baseArrayLayer + j,
347*61046927SAndroid Build Coastguard Worker };
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker pvr_get_image_subresource_layout(src, &src_sub_resource, &src_info);
350*61046927SAndroid Build Coastguard Worker pvr_get_image_subresource_layout(dst, &dst_sub_resource, &dst_info);
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker /* Setup the transfer surfaces once per image layer, which saves us
353*61046927SAndroid Build Coastguard Worker * from repeating subresource queries by manually incrementing the
354*61046927SAndroid Build Coastguard Worker * depth slices.
355*61046927SAndroid Build Coastguard Worker */
356*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(device,
357*61046927SAndroid Build Coastguard Worker &src_surface,
358*61046927SAndroid Build Coastguard Worker &src_rect,
359*61046927SAndroid Build Coastguard Worker src,
360*61046927SAndroid Build Coastguard Worker region->srcSubresource.baseArrayLayer + j,
361*61046927SAndroid Build Coastguard Worker region->srcSubresource.mipLevel,
362*61046927SAndroid Build Coastguard Worker ®ion->srcOffsets[0],
363*61046927SAndroid Build Coastguard Worker &src_extent,
364*61046927SAndroid Build Coastguard Worker initial_depth_offset,
365*61046927SAndroid Build Coastguard Worker src->vk.format,
366*61046927SAndroid Build Coastguard Worker region->srcSubresource.aspectMask);
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(device,
369*61046927SAndroid Build Coastguard Worker &dst_surface,
370*61046927SAndroid Build Coastguard Worker &dst_rect,
371*61046927SAndroid Build Coastguard Worker dst,
372*61046927SAndroid Build Coastguard Worker region->dstSubresource.baseArrayLayer + j,
373*61046927SAndroid Build Coastguard Worker region->dstSubresource.mipLevel,
374*61046927SAndroid Build Coastguard Worker &dst_offset,
375*61046927SAndroid Build Coastguard Worker &dst_extent,
376*61046927SAndroid Build Coastguard Worker min_dst_z,
377*61046927SAndroid Build Coastguard Worker dst->vk.format,
378*61046927SAndroid Build Coastguard Worker region->dstSubresource.aspectMask);
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker for (uint32_t dst_z = min_dst_z; dst_z < max_dst_z; dst_z++) {
381*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
382*61046927SAndroid Build Coastguard Worker VkResult result;
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker /* TODO: See if we can allocate all the transfer cmds in one go. */
385*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
386*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
387*61046927SAndroid Build Coastguard Worker return;
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].src_rect = src_rect;
390*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].dst_rect = dst_rect;
391*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].flip_x = flip_x;
392*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].flip_y = flip_y;
393*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mapping_count++;
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].surface = src_surface;
396*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].filter = filter;
397*61046927SAndroid Build Coastguard Worker transfer_cmd->source_count = 1;
398*61046927SAndroid Build Coastguard Worker
399*61046927SAndroid Build Coastguard Worker transfer_cmd->dst = dst_surface;
400*61046927SAndroid Build Coastguard Worker transfer_cmd->scissor = dst_rect;
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
403*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
404*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
405*61046927SAndroid Build Coastguard Worker return;
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker if (src_surface.mem_layout == PVR_MEMLAYOUT_3DTWIDDLED) {
409*61046927SAndroid Build Coastguard Worker src_surface.z_position += z_slice_stride;
410*61046927SAndroid Build Coastguard Worker } else {
411*61046927SAndroid Build Coastguard Worker src_surface.dev_addr.addr +=
412*61046927SAndroid Build Coastguard Worker src_info.depthPitch * ((uint32_t)z_slice_stride);
413*61046927SAndroid Build Coastguard Worker }
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker if (dst_surface.mem_layout == PVR_MEMLAYOUT_3DTWIDDLED)
416*61046927SAndroid Build Coastguard Worker dst_surface.z_position += 1.0f;
417*61046927SAndroid Build Coastguard Worker else
418*61046927SAndroid Build Coastguard Worker dst_surface.dev_addr.addr += dst_info.depthPitch;
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker }
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker
pvr_get_copy_format(VkFormat format)424*61046927SAndroid Build Coastguard Worker static VkFormat pvr_get_copy_format(VkFormat format)
425*61046927SAndroid Build Coastguard Worker {
426*61046927SAndroid Build Coastguard Worker switch (format) {
427*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8_SNORM:
428*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8_SINT;
429*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8G8_SNORM:
430*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8_SINT;
431*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8G8B8_SNORM:
432*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8B8_SINT;
433*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8G8B8A8_SNORM:
434*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8B8A8_SINT;
435*61046927SAndroid Build Coastguard Worker case VK_FORMAT_B8G8R8A8_SNORM:
436*61046927SAndroid Build Coastguard Worker return VK_FORMAT_B8G8R8A8_SINT;
437*61046927SAndroid Build Coastguard Worker default:
438*61046927SAndroid Build Coastguard Worker return format;
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker static void
pvr_setup_surface_for_image(struct pvr_device * device,struct pvr_transfer_cmd_surface * surface,VkRect2D * rect,const struct pvr_image * image,uint32_t array_layer,uint32_t array_offset,uint32_t mip_level,const VkOffset3D * offset,const VkExtent3D * extent,uint32_t depth,VkFormat format,const VkImageAspectFlags aspect_mask)443*61046927SAndroid Build Coastguard Worker pvr_setup_surface_for_image(struct pvr_device *device,
444*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface *surface,
445*61046927SAndroid Build Coastguard Worker VkRect2D *rect,
446*61046927SAndroid Build Coastguard Worker const struct pvr_image *image,
447*61046927SAndroid Build Coastguard Worker uint32_t array_layer,
448*61046927SAndroid Build Coastguard Worker uint32_t array_offset,
449*61046927SAndroid Build Coastguard Worker uint32_t mip_level,
450*61046927SAndroid Build Coastguard Worker const VkOffset3D *offset,
451*61046927SAndroid Build Coastguard Worker const VkExtent3D *extent,
452*61046927SAndroid Build Coastguard Worker uint32_t depth,
453*61046927SAndroid Build Coastguard Worker VkFormat format,
454*61046927SAndroid Build Coastguard Worker const VkImageAspectFlags aspect_mask)
455*61046927SAndroid Build Coastguard Worker {
456*61046927SAndroid Build Coastguard Worker if (image->vk.image_type != VK_IMAGE_TYPE_3D) {
457*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(device,
458*61046927SAndroid Build Coastguard Worker surface,
459*61046927SAndroid Build Coastguard Worker rect,
460*61046927SAndroid Build Coastguard Worker image,
461*61046927SAndroid Build Coastguard Worker array_layer + array_offset,
462*61046927SAndroid Build Coastguard Worker mip_level,
463*61046927SAndroid Build Coastguard Worker offset,
464*61046927SAndroid Build Coastguard Worker extent,
465*61046927SAndroid Build Coastguard Worker 0.0f,
466*61046927SAndroid Build Coastguard Worker format,
467*61046927SAndroid Build Coastguard Worker aspect_mask);
468*61046927SAndroid Build Coastguard Worker } else {
469*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(device,
470*61046927SAndroid Build Coastguard Worker surface,
471*61046927SAndroid Build Coastguard Worker rect,
472*61046927SAndroid Build Coastguard Worker image,
473*61046927SAndroid Build Coastguard Worker array_layer,
474*61046927SAndroid Build Coastguard Worker mip_level,
475*61046927SAndroid Build Coastguard Worker offset,
476*61046927SAndroid Build Coastguard Worker extent,
477*61046927SAndroid Build Coastguard Worker (float)depth,
478*61046927SAndroid Build Coastguard Worker format,
479*61046927SAndroid Build Coastguard Worker aspect_mask);
480*61046927SAndroid Build Coastguard Worker }
481*61046927SAndroid Build Coastguard Worker }
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker static VkResult
pvr_copy_or_resolve_image_region(struct pvr_cmd_buffer * cmd_buffer,enum pvr_resolve_op resolve_op,const struct pvr_image * src,const struct pvr_image * dst,const VkImageCopy2 * region)484*61046927SAndroid Build Coastguard Worker pvr_copy_or_resolve_image_region(struct pvr_cmd_buffer *cmd_buffer,
485*61046927SAndroid Build Coastguard Worker enum pvr_resolve_op resolve_op,
486*61046927SAndroid Build Coastguard Worker const struct pvr_image *src,
487*61046927SAndroid Build Coastguard Worker const struct pvr_image *dst,
488*61046927SAndroid Build Coastguard Worker const VkImageCopy2 *region)
489*61046927SAndroid Build Coastguard Worker {
490*61046927SAndroid Build Coastguard Worker enum pipe_format src_pformat = vk_format_to_pipe_format(src->vk.format);
491*61046927SAndroid Build Coastguard Worker enum pipe_format dst_pformat = vk_format_to_pipe_format(dst->vk.format);
492*61046927SAndroid Build Coastguard Worker bool src_block_compressed = util_format_is_compressed(src_pformat);
493*61046927SAndroid Build Coastguard Worker bool dst_block_compressed = util_format_is_compressed(dst_pformat);
494*61046927SAndroid Build Coastguard Worker VkExtent3D src_extent;
495*61046927SAndroid Build Coastguard Worker VkExtent3D dst_extent;
496*61046927SAndroid Build Coastguard Worker VkFormat dst_format;
497*61046927SAndroid Build Coastguard Worker VkFormat src_format;
498*61046927SAndroid Build Coastguard Worker uint32_t dst_layers;
499*61046927SAndroid Build Coastguard Worker uint32_t src_layers;
500*61046927SAndroid Build Coastguard Worker uint32_t max_slices;
501*61046927SAndroid Build Coastguard Worker uint32_t flags = 0U;
502*61046927SAndroid Build Coastguard Worker
503*61046927SAndroid Build Coastguard Worker if (src->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
504*61046927SAndroid Build Coastguard Worker region->srcSubresource.aspectMask !=
505*61046927SAndroid Build Coastguard Worker (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
506*61046927SAndroid Build Coastguard Worker /* Takes the stencil of the source and the depth of the destination and
507*61046927SAndroid Build Coastguard Worker * combines the two interleaved.
508*61046927SAndroid Build Coastguard Worker */
509*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_DSMERGE;
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker if (region->srcSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
512*61046927SAndroid Build Coastguard Worker /* Takes the depth of the source and the stencil of the destination and
513*61046927SAndroid Build Coastguard Worker * combines the two interleaved.
514*61046927SAndroid Build Coastguard Worker */
515*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_PICKD;
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker src_extent = region->extent;
520*61046927SAndroid Build Coastguard Worker dst_extent = region->extent;
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker if (src_block_compressed && !dst_block_compressed) {
523*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(src_pformat);
524*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(src_pformat);
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker dst_extent.width = MAX2(1U, DIV_ROUND_UP(src_extent.width, block_width));
527*61046927SAndroid Build Coastguard Worker dst_extent.height =
528*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(src_extent.height, block_height));
529*61046927SAndroid Build Coastguard Worker } else if (!src_block_compressed && dst_block_compressed) {
530*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(dst_pformat);
531*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(dst_pformat);
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker dst_extent.width = MAX2(1U, src_extent.width * block_width);
534*61046927SAndroid Build Coastguard Worker dst_extent.height = MAX2(1U, src_extent.height * block_height);
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker /* We don't care what format dst is as it's guaranteed to be size compatible
538*61046927SAndroid Build Coastguard Worker * with src.
539*61046927SAndroid Build Coastguard Worker */
540*61046927SAndroid Build Coastguard Worker dst_format = pvr_get_raw_copy_format(src->vk.format);
541*61046927SAndroid Build Coastguard Worker src_format = dst_format;
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker src_layers =
544*61046927SAndroid Build Coastguard Worker vk_image_subresource_layer_count(&src->vk, ®ion->srcSubresource);
545*61046927SAndroid Build Coastguard Worker dst_layers =
546*61046927SAndroid Build Coastguard Worker vk_image_subresource_layer_count(&dst->vk, ®ion->dstSubresource);
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker /* srcSubresource.layerCount must match layerCount of dstSubresource in
549*61046927SAndroid Build Coastguard Worker * copies not involving 3D images. In copies involving 3D images, if there is
550*61046927SAndroid Build Coastguard Worker * a 2D image it's layerCount.
551*61046927SAndroid Build Coastguard Worker */
552*61046927SAndroid Build Coastguard Worker max_slices = MAX3(src_layers, dst_layers, region->extent.depth);
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < max_slices; i++) {
555*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
556*61046927SAndroid Build Coastguard Worker VkResult result;
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
559*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
560*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker transfer_cmd->flags |= flags;
563*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].resolve_op = resolve_op;
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker pvr_setup_surface_for_image(
566*61046927SAndroid Build Coastguard Worker cmd_buffer->device,
567*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].surface,
568*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].mappings[0U].src_rect,
569*61046927SAndroid Build Coastguard Worker src,
570*61046927SAndroid Build Coastguard Worker region->srcSubresource.baseArrayLayer,
571*61046927SAndroid Build Coastguard Worker i,
572*61046927SAndroid Build Coastguard Worker region->srcSubresource.mipLevel,
573*61046927SAndroid Build Coastguard Worker ®ion->srcOffset,
574*61046927SAndroid Build Coastguard Worker &src_extent,
575*61046927SAndroid Build Coastguard Worker region->srcOffset.z + i,
576*61046927SAndroid Build Coastguard Worker src_format,
577*61046927SAndroid Build Coastguard Worker region->srcSubresource.aspectMask);
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker pvr_setup_surface_for_image(cmd_buffer->device,
580*61046927SAndroid Build Coastguard Worker &transfer_cmd->dst,
581*61046927SAndroid Build Coastguard Worker &transfer_cmd->scissor,
582*61046927SAndroid Build Coastguard Worker dst,
583*61046927SAndroid Build Coastguard Worker region->dstSubresource.baseArrayLayer,
584*61046927SAndroid Build Coastguard Worker i,
585*61046927SAndroid Build Coastguard Worker region->dstSubresource.mipLevel,
586*61046927SAndroid Build Coastguard Worker ®ion->dstOffset,
587*61046927SAndroid Build Coastguard Worker &dst_extent,
588*61046927SAndroid Build Coastguard Worker region->dstOffset.z + i,
589*61046927SAndroid Build Coastguard Worker dst_format,
590*61046927SAndroid Build Coastguard Worker region->dstSubresource.aspectMask);
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0U].dst_rect = transfer_cmd->scissor;
593*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mapping_count++;
594*61046927SAndroid Build Coastguard Worker transfer_cmd->source_count = 1;
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
597*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
598*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
599*61046927SAndroid Build Coastguard Worker return result;
600*61046927SAndroid Build Coastguard Worker }
601*61046927SAndroid Build Coastguard Worker }
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
604*61046927SAndroid Build Coastguard Worker }
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker VkResult
pvr_copy_or_resolve_color_image_region(struct pvr_cmd_buffer * cmd_buffer,const struct pvr_image * src,const struct pvr_image * dst,const VkImageCopy2 * region)607*61046927SAndroid Build Coastguard Worker pvr_copy_or_resolve_color_image_region(struct pvr_cmd_buffer *cmd_buffer,
608*61046927SAndroid Build Coastguard Worker const struct pvr_image *src,
609*61046927SAndroid Build Coastguard Worker const struct pvr_image *dst,
610*61046927SAndroid Build Coastguard Worker const VkImageCopy2 *region)
611*61046927SAndroid Build Coastguard Worker {
612*61046927SAndroid Build Coastguard Worker enum pvr_resolve_op resolve_op = PVR_RESOLVE_BLEND;
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker if (src->vk.samples > 1U && dst->vk.samples < 2U) {
615*61046927SAndroid Build Coastguard Worker /* Integer resolve picks a single sample. */
616*61046927SAndroid Build Coastguard Worker if (vk_format_is_int(src->vk.format))
617*61046927SAndroid Build Coastguard Worker resolve_op = PVR_RESOLVE_SAMPLE0;
618*61046927SAndroid Build Coastguard Worker }
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker return pvr_copy_or_resolve_image_region(cmd_buffer,
621*61046927SAndroid Build Coastguard Worker resolve_op,
622*61046927SAndroid Build Coastguard Worker src,
623*61046927SAndroid Build Coastguard Worker dst,
624*61046927SAndroid Build Coastguard Worker region);
625*61046927SAndroid Build Coastguard Worker }
626*61046927SAndroid Build Coastguard Worker
pvr_can_merge_ds_regions(const VkImageCopy2 * pRegionA,const VkImageCopy2 * pRegionB)627*61046927SAndroid Build Coastguard Worker static bool pvr_can_merge_ds_regions(const VkImageCopy2 *pRegionA,
628*61046927SAndroid Build Coastguard Worker const VkImageCopy2 *pRegionB)
629*61046927SAndroid Build Coastguard Worker {
630*61046927SAndroid Build Coastguard Worker assert(pRegionA->srcSubresource.aspectMask != 0U);
631*61046927SAndroid Build Coastguard Worker assert(pRegionB->srcSubresource.aspectMask != 0U);
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker if (!((pRegionA->srcSubresource.aspectMask ^
634*61046927SAndroid Build Coastguard Worker pRegionB->srcSubresource.aspectMask) &
635*61046927SAndroid Build Coastguard Worker (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
636*61046927SAndroid Build Coastguard Worker return false;
637*61046927SAndroid Build Coastguard Worker }
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker /* Assert if aspectMask mismatch between src and dst, given it's a depth and
640*61046927SAndroid Build Coastguard Worker * stencil image so not multi-planar and from the Vulkan 1.0.223 spec:
641*61046927SAndroid Build Coastguard Worker *
642*61046927SAndroid Build Coastguard Worker * If neither srcImage nor dstImage has a multi-planar image format then
643*61046927SAndroid Build Coastguard Worker * for each element of pRegions, srcSubresource.aspectMask and
644*61046927SAndroid Build Coastguard Worker * dstSubresource.aspectMask must match.
645*61046927SAndroid Build Coastguard Worker */
646*61046927SAndroid Build Coastguard Worker assert(pRegionA->srcSubresource.aspectMask ==
647*61046927SAndroid Build Coastguard Worker pRegionA->dstSubresource.aspectMask);
648*61046927SAndroid Build Coastguard Worker assert(pRegionB->srcSubresource.aspectMask ==
649*61046927SAndroid Build Coastguard Worker pRegionB->dstSubresource.aspectMask);
650*61046927SAndroid Build Coastguard Worker
651*61046927SAndroid Build Coastguard Worker if (!(pRegionA->srcSubresource.mipLevel ==
652*61046927SAndroid Build Coastguard Worker pRegionB->srcSubresource.mipLevel &&
653*61046927SAndroid Build Coastguard Worker pRegionA->srcSubresource.baseArrayLayer ==
654*61046927SAndroid Build Coastguard Worker pRegionB->srcSubresource.baseArrayLayer &&
655*61046927SAndroid Build Coastguard Worker pRegionA->srcSubresource.layerCount ==
656*61046927SAndroid Build Coastguard Worker pRegionB->srcSubresource.layerCount)) {
657*61046927SAndroid Build Coastguard Worker return false;
658*61046927SAndroid Build Coastguard Worker }
659*61046927SAndroid Build Coastguard Worker
660*61046927SAndroid Build Coastguard Worker if (!(pRegionA->dstSubresource.mipLevel ==
661*61046927SAndroid Build Coastguard Worker pRegionB->dstSubresource.mipLevel &&
662*61046927SAndroid Build Coastguard Worker pRegionA->dstSubresource.baseArrayLayer ==
663*61046927SAndroid Build Coastguard Worker pRegionB->dstSubresource.baseArrayLayer &&
664*61046927SAndroid Build Coastguard Worker pRegionA->dstSubresource.layerCount ==
665*61046927SAndroid Build Coastguard Worker pRegionB->dstSubresource.layerCount)) {
666*61046927SAndroid Build Coastguard Worker return false;
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker if (!(pRegionA->srcOffset.x == pRegionB->srcOffset.x &&
670*61046927SAndroid Build Coastguard Worker pRegionA->srcOffset.y == pRegionB->srcOffset.y &&
671*61046927SAndroid Build Coastguard Worker pRegionA->srcOffset.z == pRegionB->srcOffset.z)) {
672*61046927SAndroid Build Coastguard Worker return false;
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker if (!(pRegionA->dstOffset.x == pRegionB->dstOffset.x &&
676*61046927SAndroid Build Coastguard Worker pRegionA->dstOffset.y == pRegionB->dstOffset.y &&
677*61046927SAndroid Build Coastguard Worker pRegionA->dstOffset.z == pRegionB->dstOffset.z)) {
678*61046927SAndroid Build Coastguard Worker return false;
679*61046927SAndroid Build Coastguard Worker }
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker if (!(pRegionA->extent.width == pRegionB->extent.width &&
682*61046927SAndroid Build Coastguard Worker pRegionA->extent.height == pRegionB->extent.height &&
683*61046927SAndroid Build Coastguard Worker pRegionA->extent.depth == pRegionB->extent.depth)) {
684*61046927SAndroid Build Coastguard Worker return false;
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker return true;
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker
pvr_CmdCopyImage2(VkCommandBuffer commandBuffer,const VkCopyImageInfo2 * pCopyImageInfo)690*61046927SAndroid Build Coastguard Worker void pvr_CmdCopyImage2(VkCommandBuffer commandBuffer,
691*61046927SAndroid Build Coastguard Worker const VkCopyImageInfo2 *pCopyImageInfo)
692*61046927SAndroid Build Coastguard Worker {
693*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
694*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, src, pCopyImageInfo->srcImage);
695*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, dst, pCopyImageInfo->dstImage);
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker const bool can_merge_ds = src->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
698*61046927SAndroid Build Coastguard Worker dst->vk.format == VK_FORMAT_D24_UNORM_S8_UINT;
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
701*61046927SAndroid Build Coastguard Worker
702*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < pCopyImageInfo->regionCount; i++) {
703*61046927SAndroid Build Coastguard Worker VkResult result;
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker /* If an application has split a copy between D24S8 images into two
706*61046927SAndroid Build Coastguard Worker * separate copy regions (one for the depth aspect and one for the
707*61046927SAndroid Build Coastguard Worker * stencil aspect) attempt to merge the two regions back into one blit.
708*61046927SAndroid Build Coastguard Worker *
709*61046927SAndroid Build Coastguard Worker * This can only be merged if both regions are identical apart from the
710*61046927SAndroid Build Coastguard Worker * aspectMask, one of which has to be depth and the other has to be
711*61046927SAndroid Build Coastguard Worker * stencil.
712*61046927SAndroid Build Coastguard Worker *
713*61046927SAndroid Build Coastguard Worker * Only attempt to merge consecutive regions, ignore the case of merging
714*61046927SAndroid Build Coastguard Worker * non-consecutive regions.
715*61046927SAndroid Build Coastguard Worker */
716*61046927SAndroid Build Coastguard Worker if (can_merge_ds && i != (pCopyImageInfo->regionCount - 1)) {
717*61046927SAndroid Build Coastguard Worker const bool ret =
718*61046927SAndroid Build Coastguard Worker pvr_can_merge_ds_regions(&pCopyImageInfo->pRegions[i],
719*61046927SAndroid Build Coastguard Worker &pCopyImageInfo->pRegions[i + 1]);
720*61046927SAndroid Build Coastguard Worker if (ret) {
721*61046927SAndroid Build Coastguard Worker VkImageCopy2 region = pCopyImageInfo->pRegions[i];
722*61046927SAndroid Build Coastguard Worker
723*61046927SAndroid Build Coastguard Worker region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT |
724*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_STENCIL_BIT;
725*61046927SAndroid Build Coastguard Worker region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT |
726*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_STENCIL_BIT;
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker result = pvr_copy_or_resolve_color_image_region(cmd_buffer,
729*61046927SAndroid Build Coastguard Worker src,
730*61046927SAndroid Build Coastguard Worker dst,
731*61046927SAndroid Build Coastguard Worker ®ion);
732*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
733*61046927SAndroid Build Coastguard Worker return;
734*61046927SAndroid Build Coastguard Worker
735*61046927SAndroid Build Coastguard Worker /* Skip the next region as it has been processed with the last
736*61046927SAndroid Build Coastguard Worker * region.
737*61046927SAndroid Build Coastguard Worker */
738*61046927SAndroid Build Coastguard Worker i++;
739*61046927SAndroid Build Coastguard Worker
740*61046927SAndroid Build Coastguard Worker continue;
741*61046927SAndroid Build Coastguard Worker }
742*61046927SAndroid Build Coastguard Worker }
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker result =
745*61046927SAndroid Build Coastguard Worker pvr_copy_or_resolve_color_image_region(cmd_buffer,
746*61046927SAndroid Build Coastguard Worker src,
747*61046927SAndroid Build Coastguard Worker dst,
748*61046927SAndroid Build Coastguard Worker &pCopyImageInfo->pRegions[i]);
749*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
750*61046927SAndroid Build Coastguard Worker return;
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker }
753*61046927SAndroid Build Coastguard Worker
754*61046927SAndroid Build Coastguard Worker VkResult
pvr_copy_buffer_to_image_region_format(struct pvr_cmd_buffer * const cmd_buffer,const pvr_dev_addr_t buffer_dev_addr,const struct pvr_image * const image,const VkBufferImageCopy2 * const region,const VkFormat src_format,const VkFormat dst_format,const uint32_t flags)755*61046927SAndroid Build Coastguard Worker pvr_copy_buffer_to_image_region_format(struct pvr_cmd_buffer *const cmd_buffer,
756*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t buffer_dev_addr,
757*61046927SAndroid Build Coastguard Worker const struct pvr_image *const image,
758*61046927SAndroid Build Coastguard Worker const VkBufferImageCopy2 *const region,
759*61046927SAndroid Build Coastguard Worker const VkFormat src_format,
760*61046927SAndroid Build Coastguard Worker const VkFormat dst_format,
761*61046927SAndroid Build Coastguard Worker const uint32_t flags)
762*61046927SAndroid Build Coastguard Worker {
763*61046927SAndroid Build Coastguard Worker enum pipe_format pformat = vk_format_to_pipe_format(dst_format);
764*61046927SAndroid Build Coastguard Worker uint32_t row_length_in_texels;
765*61046927SAndroid Build Coastguard Worker uint32_t buffer_slice_size;
766*61046927SAndroid Build Coastguard Worker uint32_t buffer_layer_size;
767*61046927SAndroid Build Coastguard Worker uint32_t height_in_blks;
768*61046927SAndroid Build Coastguard Worker uint32_t row_length;
769*61046927SAndroid Build Coastguard Worker
770*61046927SAndroid Build Coastguard Worker if (region->bufferRowLength == 0)
771*61046927SAndroid Build Coastguard Worker row_length_in_texels = region->imageExtent.width;
772*61046927SAndroid Build Coastguard Worker else
773*61046927SAndroid Build Coastguard Worker row_length_in_texels = region->bufferRowLength;
774*61046927SAndroid Build Coastguard Worker
775*61046927SAndroid Build Coastguard Worker if (region->bufferImageHeight == 0)
776*61046927SAndroid Build Coastguard Worker height_in_blks = region->imageExtent.height;
777*61046927SAndroid Build Coastguard Worker else
778*61046927SAndroid Build Coastguard Worker height_in_blks = region->bufferImageHeight;
779*61046927SAndroid Build Coastguard Worker
780*61046927SAndroid Build Coastguard Worker if (util_format_is_compressed(pformat)) {
781*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(pformat);
782*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(pformat);
783*61046927SAndroid Build Coastguard Worker uint32_t block_size = util_format_get_blocksize(pformat);
784*61046927SAndroid Build Coastguard Worker
785*61046927SAndroid Build Coastguard Worker height_in_blks = DIV_ROUND_UP(height_in_blks, block_height);
786*61046927SAndroid Build Coastguard Worker row_length_in_texels =
787*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(row_length_in_texels, block_width) * block_size;
788*61046927SAndroid Build Coastguard Worker }
789*61046927SAndroid Build Coastguard Worker
790*61046927SAndroid Build Coastguard Worker row_length = row_length_in_texels * vk_format_get_blocksize(src_format);
791*61046927SAndroid Build Coastguard Worker
792*61046927SAndroid Build Coastguard Worker buffer_slice_size = height_in_blks * row_length;
793*61046927SAndroid Build Coastguard Worker buffer_layer_size = buffer_slice_size * region->imageExtent.depth;
794*61046927SAndroid Build Coastguard Worker
795*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < region->imageExtent.depth; i++) {
796*61046927SAndroid Build Coastguard Worker const uint32_t depth = i + (uint32_t)region->imageOffset.z;
797*61046927SAndroid Build Coastguard Worker
798*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < region->imageSubresource.layerCount; j++) {
799*61046927SAndroid Build Coastguard Worker const VkDeviceSize buffer_offset = region->bufferOffset +
800*61046927SAndroid Build Coastguard Worker (j * buffer_layer_size) +
801*61046927SAndroid Build Coastguard Worker (i * buffer_slice_size);
802*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
803*61046927SAndroid Build Coastguard Worker VkResult result;
804*61046927SAndroid Build Coastguard Worker
805*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
806*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
807*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
808*61046927SAndroid Build Coastguard Worker
809*61046927SAndroid Build Coastguard Worker transfer_cmd->flags = flags;
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker pvr_setup_buffer_surface(
812*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].surface,
813*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].mappings[0].src_rect,
814*61046927SAndroid Build Coastguard Worker buffer_dev_addr,
815*61046927SAndroid Build Coastguard Worker buffer_offset,
816*61046927SAndroid Build Coastguard Worker src_format,
817*61046927SAndroid Build Coastguard Worker image->vk.format,
818*61046927SAndroid Build Coastguard Worker region->imageExtent.width,
819*61046927SAndroid Build Coastguard Worker region->imageExtent.height,
820*61046927SAndroid Build Coastguard Worker row_length_in_texels);
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].surface.depth = 1;
823*61046927SAndroid Build Coastguard Worker transfer_cmd->source_count = 1;
824*61046927SAndroid Build Coastguard Worker
825*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(cmd_buffer->device,
826*61046927SAndroid Build Coastguard Worker &transfer_cmd->dst,
827*61046927SAndroid Build Coastguard Worker &transfer_cmd->scissor,
828*61046927SAndroid Build Coastguard Worker image,
829*61046927SAndroid Build Coastguard Worker region->imageSubresource.baseArrayLayer + j,
830*61046927SAndroid Build Coastguard Worker region->imageSubresource.mipLevel,
831*61046927SAndroid Build Coastguard Worker ®ion->imageOffset,
832*61046927SAndroid Build Coastguard Worker ®ion->imageExtent,
833*61046927SAndroid Build Coastguard Worker depth,
834*61046927SAndroid Build Coastguard Worker dst_format,
835*61046927SAndroid Build Coastguard Worker region->imageSubresource.aspectMask);
836*61046927SAndroid Build Coastguard Worker
837*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].dst_rect = transfer_cmd->scissor;
838*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mapping_count++;
839*61046927SAndroid Build Coastguard Worker
840*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
841*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
842*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
843*61046927SAndroid Build Coastguard Worker return result;
844*61046927SAndroid Build Coastguard Worker }
845*61046927SAndroid Build Coastguard Worker }
846*61046927SAndroid Build Coastguard Worker }
847*61046927SAndroid Build Coastguard Worker
848*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker
851*61046927SAndroid Build Coastguard Worker VkResult
pvr_copy_buffer_to_image_region(struct pvr_cmd_buffer * const cmd_buffer,const pvr_dev_addr_t buffer_dev_addr,const struct pvr_image * const image,const VkBufferImageCopy2 * const region)852*61046927SAndroid Build Coastguard Worker pvr_copy_buffer_to_image_region(struct pvr_cmd_buffer *const cmd_buffer,
853*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t buffer_dev_addr,
854*61046927SAndroid Build Coastguard Worker const struct pvr_image *const image,
855*61046927SAndroid Build Coastguard Worker const VkBufferImageCopy2 *const region)
856*61046927SAndroid Build Coastguard Worker {
857*61046927SAndroid Build Coastguard Worker const VkImageAspectFlags aspect_mask = region->imageSubresource.aspectMask;
858*61046927SAndroid Build Coastguard Worker VkFormat src_format;
859*61046927SAndroid Build Coastguard Worker VkFormat dst_format;
860*61046927SAndroid Build Coastguard Worker uint32_t flags = 0;
861*61046927SAndroid Build Coastguard Worker
862*61046927SAndroid Build Coastguard Worker if (vk_format_has_depth(image->vk.format) &&
863*61046927SAndroid Build Coastguard Worker vk_format_has_stencil(image->vk.format)) {
864*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_DSMERGE;
865*61046927SAndroid Build Coastguard Worker
866*61046927SAndroid Build Coastguard Worker if ((aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) {
867*61046927SAndroid Build Coastguard Worker src_format = vk_format_stencil_only(image->vk.format);
868*61046927SAndroid Build Coastguard Worker } else {
869*61046927SAndroid Build Coastguard Worker src_format = vk_format_depth_only(image->vk.format);
870*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_PICKD;
871*61046927SAndroid Build Coastguard Worker }
872*61046927SAndroid Build Coastguard Worker
873*61046927SAndroid Build Coastguard Worker dst_format = image->vk.format;
874*61046927SAndroid Build Coastguard Worker } else {
875*61046927SAndroid Build Coastguard Worker src_format = pvr_get_raw_copy_format(image->vk.format);
876*61046927SAndroid Build Coastguard Worker dst_format = src_format;
877*61046927SAndroid Build Coastguard Worker }
878*61046927SAndroid Build Coastguard Worker
879*61046927SAndroid Build Coastguard Worker return pvr_copy_buffer_to_image_region_format(cmd_buffer,
880*61046927SAndroid Build Coastguard Worker buffer_dev_addr,
881*61046927SAndroid Build Coastguard Worker image,
882*61046927SAndroid Build Coastguard Worker region,
883*61046927SAndroid Build Coastguard Worker src_format,
884*61046927SAndroid Build Coastguard Worker dst_format,
885*61046927SAndroid Build Coastguard Worker flags);
886*61046927SAndroid Build Coastguard Worker }
887*61046927SAndroid Build Coastguard Worker
pvr_CmdCopyBufferToImage2(VkCommandBuffer commandBuffer,const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo)888*61046927SAndroid Build Coastguard Worker void pvr_CmdCopyBufferToImage2(
889*61046927SAndroid Build Coastguard Worker VkCommandBuffer commandBuffer,
890*61046927SAndroid Build Coastguard Worker const VkCopyBufferToImageInfo2 *pCopyBufferToImageInfo)
891*61046927SAndroid Build Coastguard Worker {
892*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, src, pCopyBufferToImageInfo->srcBuffer);
893*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, dst, pCopyBufferToImageInfo->dstImage);
894*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
895*61046927SAndroid Build Coastguard Worker
896*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
897*61046927SAndroid Build Coastguard Worker
898*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCopyBufferToImageInfo->regionCount; i++) {
899*61046927SAndroid Build Coastguard Worker const VkResult result =
900*61046927SAndroid Build Coastguard Worker pvr_copy_buffer_to_image_region(cmd_buffer,
901*61046927SAndroid Build Coastguard Worker src->dev_addr,
902*61046927SAndroid Build Coastguard Worker dst,
903*61046927SAndroid Build Coastguard Worker &pCopyBufferToImageInfo->pRegions[i]);
904*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
905*61046927SAndroid Build Coastguard Worker return;
906*61046927SAndroid Build Coastguard Worker }
907*61046927SAndroid Build Coastguard Worker }
908*61046927SAndroid Build Coastguard Worker
909*61046927SAndroid Build Coastguard Worker VkResult
pvr_copy_image_to_buffer_region_format(struct pvr_cmd_buffer * const cmd_buffer,const struct pvr_image * const image,const pvr_dev_addr_t buffer_dev_addr,const VkBufferImageCopy2 * const region,const VkFormat src_format,const VkFormat dst_format)910*61046927SAndroid Build Coastguard Worker pvr_copy_image_to_buffer_region_format(struct pvr_cmd_buffer *const cmd_buffer,
911*61046927SAndroid Build Coastguard Worker const struct pvr_image *const image,
912*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t buffer_dev_addr,
913*61046927SAndroid Build Coastguard Worker const VkBufferImageCopy2 *const region,
914*61046927SAndroid Build Coastguard Worker const VkFormat src_format,
915*61046927SAndroid Build Coastguard Worker const VkFormat dst_format)
916*61046927SAndroid Build Coastguard Worker {
917*61046927SAndroid Build Coastguard Worker enum pipe_format pformat = vk_format_to_pipe_format(image->vk.format);
918*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface dst_surface = { 0 };
919*61046927SAndroid Build Coastguard Worker VkImageSubresource sub_resource;
920*61046927SAndroid Build Coastguard Worker uint32_t buffer_image_height;
921*61046927SAndroid Build Coastguard Worker uint32_t buffer_row_length;
922*61046927SAndroid Build Coastguard Worker uint32_t buffer_slice_size;
923*61046927SAndroid Build Coastguard Worker uint32_t max_array_layers;
924*61046927SAndroid Build Coastguard Worker VkRect2D dst_rect = { 0 };
925*61046927SAndroid Build Coastguard Worker uint32_t max_depth_slice;
926*61046927SAndroid Build Coastguard Worker VkSubresourceLayout info;
927*61046927SAndroid Build Coastguard Worker
928*61046927SAndroid Build Coastguard Worker /* Only images with VK_SAMPLE_COUNT_1_BIT can be copied to buffer. */
929*61046927SAndroid Build Coastguard Worker assert(image->vk.samples == 1);
930*61046927SAndroid Build Coastguard Worker
931*61046927SAndroid Build Coastguard Worker if (region->bufferRowLength == 0)
932*61046927SAndroid Build Coastguard Worker buffer_row_length = region->imageExtent.width;
933*61046927SAndroid Build Coastguard Worker else
934*61046927SAndroid Build Coastguard Worker buffer_row_length = region->bufferRowLength;
935*61046927SAndroid Build Coastguard Worker
936*61046927SAndroid Build Coastguard Worker if (region->bufferImageHeight == 0)
937*61046927SAndroid Build Coastguard Worker buffer_image_height = region->imageExtent.height;
938*61046927SAndroid Build Coastguard Worker else
939*61046927SAndroid Build Coastguard Worker buffer_image_height = region->bufferImageHeight;
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker max_array_layers =
942*61046927SAndroid Build Coastguard Worker region->imageSubresource.baseArrayLayer +
943*61046927SAndroid Build Coastguard Worker vk_image_subresource_layer_count(&image->vk, ®ion->imageSubresource);
944*61046927SAndroid Build Coastguard Worker
945*61046927SAndroid Build Coastguard Worker buffer_slice_size = buffer_image_height * buffer_row_length *
946*61046927SAndroid Build Coastguard Worker vk_format_get_blocksize(dst_format);
947*61046927SAndroid Build Coastguard Worker
948*61046927SAndroid Build Coastguard Worker max_depth_slice = region->imageExtent.depth + region->imageOffset.z;
949*61046927SAndroid Build Coastguard Worker
950*61046927SAndroid Build Coastguard Worker pvr_setup_buffer_surface(&dst_surface,
951*61046927SAndroid Build Coastguard Worker &dst_rect,
952*61046927SAndroid Build Coastguard Worker buffer_dev_addr,
953*61046927SAndroid Build Coastguard Worker region->bufferOffset,
954*61046927SAndroid Build Coastguard Worker dst_format,
955*61046927SAndroid Build Coastguard Worker image->vk.format,
956*61046927SAndroid Build Coastguard Worker buffer_row_length,
957*61046927SAndroid Build Coastguard Worker buffer_image_height,
958*61046927SAndroid Build Coastguard Worker buffer_row_length);
959*61046927SAndroid Build Coastguard Worker
960*61046927SAndroid Build Coastguard Worker dst_rect.extent.width = region->imageExtent.width;
961*61046927SAndroid Build Coastguard Worker dst_rect.extent.height = region->imageExtent.height;
962*61046927SAndroid Build Coastguard Worker
963*61046927SAndroid Build Coastguard Worker if (util_format_is_compressed(pformat)) {
964*61046927SAndroid Build Coastguard Worker uint32_t block_width = util_format_get_blockwidth(pformat);
965*61046927SAndroid Build Coastguard Worker uint32_t block_height = util_format_get_blockheight(pformat);
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker dst_rect.extent.width =
968*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(dst_rect.extent.width, block_width));
969*61046927SAndroid Build Coastguard Worker dst_rect.extent.height =
970*61046927SAndroid Build Coastguard Worker MAX2(1U, DIV_ROUND_UP(dst_rect.extent.height, block_height));
971*61046927SAndroid Build Coastguard Worker }
972*61046927SAndroid Build Coastguard Worker
973*61046927SAndroid Build Coastguard Worker sub_resource = (VkImageSubresource){
974*61046927SAndroid Build Coastguard Worker .aspectMask = region->imageSubresource.aspectMask,
975*61046927SAndroid Build Coastguard Worker .mipLevel = region->imageSubresource.mipLevel,
976*61046927SAndroid Build Coastguard Worker .arrayLayer = region->imageSubresource.baseArrayLayer,
977*61046927SAndroid Build Coastguard Worker };
978*61046927SAndroid Build Coastguard Worker
979*61046927SAndroid Build Coastguard Worker pvr_get_image_subresource_layout(image, &sub_resource, &info);
980*61046927SAndroid Build Coastguard Worker
981*61046927SAndroid Build Coastguard Worker for (uint32_t i = region->imageSubresource.baseArrayLayer;
982*61046927SAndroid Build Coastguard Worker i < max_array_layers;
983*61046927SAndroid Build Coastguard Worker i++) {
984*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd_surface src_surface = { 0 };
985*61046927SAndroid Build Coastguard Worker VkRect2D src_rect = { 0 };
986*61046927SAndroid Build Coastguard Worker
987*61046927SAndroid Build Coastguard Worker /* Note: Set the depth to the initial depth offset, the memory address (or
988*61046927SAndroid Build Coastguard Worker * the z_position) for the depth slice will be incremented manually in the
989*61046927SAndroid Build Coastguard Worker * loop below.
990*61046927SAndroid Build Coastguard Worker */
991*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(cmd_buffer->device,
992*61046927SAndroid Build Coastguard Worker &src_surface,
993*61046927SAndroid Build Coastguard Worker &src_rect,
994*61046927SAndroid Build Coastguard Worker image,
995*61046927SAndroid Build Coastguard Worker i,
996*61046927SAndroid Build Coastguard Worker region->imageSubresource.mipLevel,
997*61046927SAndroid Build Coastguard Worker ®ion->imageOffset,
998*61046927SAndroid Build Coastguard Worker ®ion->imageExtent,
999*61046927SAndroid Build Coastguard Worker region->imageOffset.z,
1000*61046927SAndroid Build Coastguard Worker src_format,
1001*61046927SAndroid Build Coastguard Worker region->imageSubresource.aspectMask);
1002*61046927SAndroid Build Coastguard Worker
1003*61046927SAndroid Build Coastguard Worker for (uint32_t j = region->imageOffset.z; j < max_depth_slice; j++) {
1004*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
1005*61046927SAndroid Build Coastguard Worker VkResult result;
1006*61046927SAndroid Build Coastguard Worker
1007*61046927SAndroid Build Coastguard Worker /* TODO: See if we can allocate all the transfer cmds in one go. */
1008*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
1009*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
1010*61046927SAndroid Build Coastguard Worker return vk_error(cmd_buffer->device, VK_ERROR_OUT_OF_HOST_MEMORY);
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].src_rect = src_rect;
1013*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].dst_rect = dst_rect;
1014*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mapping_count++;
1015*61046927SAndroid Build Coastguard Worker
1016*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].surface = src_surface;
1017*61046927SAndroid Build Coastguard Worker transfer_cmd->source_count = 1;
1018*61046927SAndroid Build Coastguard Worker
1019*61046927SAndroid Build Coastguard Worker transfer_cmd->dst = dst_surface;
1020*61046927SAndroid Build Coastguard Worker transfer_cmd->scissor = dst_rect;
1021*61046927SAndroid Build Coastguard Worker
1022*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
1023*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1024*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
1025*61046927SAndroid Build Coastguard Worker return result;
1026*61046927SAndroid Build Coastguard Worker }
1027*61046927SAndroid Build Coastguard Worker
1028*61046927SAndroid Build Coastguard Worker dst_surface.dev_addr.addr += buffer_slice_size;
1029*61046927SAndroid Build Coastguard Worker
1030*61046927SAndroid Build Coastguard Worker if (src_surface.mem_layout == PVR_MEMLAYOUT_3DTWIDDLED)
1031*61046927SAndroid Build Coastguard Worker src_surface.z_position += 1.0f;
1032*61046927SAndroid Build Coastguard Worker else
1033*61046927SAndroid Build Coastguard Worker src_surface.dev_addr.addr += info.depthPitch;
1034*61046927SAndroid Build Coastguard Worker }
1035*61046927SAndroid Build Coastguard Worker }
1036*61046927SAndroid Build Coastguard Worker
1037*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1038*61046927SAndroid Build Coastguard Worker }
1039*61046927SAndroid Build Coastguard Worker
1040*61046927SAndroid Build Coastguard Worker VkResult
pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer * const cmd_buffer,const struct pvr_image * const image,const pvr_dev_addr_t buffer_dev_addr,const VkBufferImageCopy2 * const region)1041*61046927SAndroid Build Coastguard Worker pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer *const cmd_buffer,
1042*61046927SAndroid Build Coastguard Worker const struct pvr_image *const image,
1043*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t buffer_dev_addr,
1044*61046927SAndroid Build Coastguard Worker const VkBufferImageCopy2 *const region)
1045*61046927SAndroid Build Coastguard Worker {
1046*61046927SAndroid Build Coastguard Worker const VkImageAspectFlags aspect_mask = region->imageSubresource.aspectMask;
1047*61046927SAndroid Build Coastguard Worker
1048*61046927SAndroid Build Coastguard Worker VkFormat src_format = pvr_get_copy_format(image->vk.format);
1049*61046927SAndroid Build Coastguard Worker VkFormat dst_format;
1050*61046927SAndroid Build Coastguard Worker
1051*61046927SAndroid Build Coastguard Worker /* Color and depth aspect copies can be done using an appropriate raw format.
1052*61046927SAndroid Build Coastguard Worker */
1053*61046927SAndroid Build Coastguard Worker if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) {
1054*61046927SAndroid Build Coastguard Worker src_format = pvr_get_raw_copy_format(src_format);
1055*61046927SAndroid Build Coastguard Worker dst_format = src_format;
1056*61046927SAndroid Build Coastguard Worker } else if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
1057*61046927SAndroid Build Coastguard Worker /* From the Vulkan spec:
1058*61046927SAndroid Build Coastguard Worker *
1059*61046927SAndroid Build Coastguard Worker * Data copied to or from the stencil aspect of any depth/stencil
1060*61046927SAndroid Build Coastguard Worker * format is tightly packed with one VK_FORMAT_S8_UINT value per texel.
1061*61046927SAndroid Build Coastguard Worker */
1062*61046927SAndroid Build Coastguard Worker dst_format = VK_FORMAT_S8_UINT;
1063*61046927SAndroid Build Coastguard Worker } else {
1064*61046927SAndroid Build Coastguard Worker /* YUV Planes require specific formats. */
1065*61046927SAndroid Build Coastguard Worker dst_format = src_format;
1066*61046927SAndroid Build Coastguard Worker }
1067*61046927SAndroid Build Coastguard Worker
1068*61046927SAndroid Build Coastguard Worker return pvr_copy_image_to_buffer_region_format(cmd_buffer,
1069*61046927SAndroid Build Coastguard Worker image,
1070*61046927SAndroid Build Coastguard Worker buffer_dev_addr,
1071*61046927SAndroid Build Coastguard Worker region,
1072*61046927SAndroid Build Coastguard Worker src_format,
1073*61046927SAndroid Build Coastguard Worker dst_format);
1074*61046927SAndroid Build Coastguard Worker }
1075*61046927SAndroid Build Coastguard Worker
pvr_CmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo)1076*61046927SAndroid Build Coastguard Worker void pvr_CmdCopyImageToBuffer2(
1077*61046927SAndroid Build Coastguard Worker VkCommandBuffer commandBuffer,
1078*61046927SAndroid Build Coastguard Worker const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo)
1079*61046927SAndroid Build Coastguard Worker {
1080*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, dst, pCopyImageToBufferInfo->dstBuffer);
1081*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, src, pCopyImageToBufferInfo->srcImage);
1082*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1083*61046927SAndroid Build Coastguard Worker
1084*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
1085*61046927SAndroid Build Coastguard Worker
1086*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < pCopyImageToBufferInfo->regionCount; i++) {
1087*61046927SAndroid Build Coastguard Worker const VkBufferImageCopy2 *region = &pCopyImageToBufferInfo->pRegions[i];
1088*61046927SAndroid Build Coastguard Worker
1089*61046927SAndroid Build Coastguard Worker const VkResult result = pvr_copy_image_to_buffer_region(cmd_buffer,
1090*61046927SAndroid Build Coastguard Worker src,
1091*61046927SAndroid Build Coastguard Worker dst->dev_addr,
1092*61046927SAndroid Build Coastguard Worker region);
1093*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1094*61046927SAndroid Build Coastguard Worker return;
1095*61046927SAndroid Build Coastguard Worker }
1096*61046927SAndroid Build Coastguard Worker }
1097*61046927SAndroid Build Coastguard Worker
pvr_calc_mip_level_extents(const struct pvr_image * image,uint16_t mip_level,VkExtent3D * extent_out)1098*61046927SAndroid Build Coastguard Worker static void pvr_calc_mip_level_extents(const struct pvr_image *image,
1099*61046927SAndroid Build Coastguard Worker uint16_t mip_level,
1100*61046927SAndroid Build Coastguard Worker VkExtent3D *extent_out)
1101*61046927SAndroid Build Coastguard Worker {
1102*61046927SAndroid Build Coastguard Worker /* 3D textures are clamped to 4x4x4. */
1103*61046927SAndroid Build Coastguard Worker const uint32_t clamp = (image->vk.image_type == VK_IMAGE_TYPE_3D) ? 4 : 1;
1104*61046927SAndroid Build Coastguard Worker const VkExtent3D *extent = &image->vk.extent;
1105*61046927SAndroid Build Coastguard Worker
1106*61046927SAndroid Build Coastguard Worker extent_out->width = MAX2(extent->width >> mip_level, clamp);
1107*61046927SAndroid Build Coastguard Worker extent_out->height = MAX2(extent->height >> mip_level, clamp);
1108*61046927SAndroid Build Coastguard Worker extent_out->depth = MAX2(extent->depth >> mip_level, clamp);
1109*61046927SAndroid Build Coastguard Worker }
1110*61046927SAndroid Build Coastguard Worker
pvr_clear_image_range(struct pvr_cmd_buffer * cmd_buffer,const struct pvr_image * image,const VkClearColorValue * pColor,const VkImageSubresourceRange * psRange,uint32_t flags)1111*61046927SAndroid Build Coastguard Worker static VkResult pvr_clear_image_range(struct pvr_cmd_buffer *cmd_buffer,
1112*61046927SAndroid Build Coastguard Worker const struct pvr_image *image,
1113*61046927SAndroid Build Coastguard Worker const VkClearColorValue *pColor,
1114*61046927SAndroid Build Coastguard Worker const VkImageSubresourceRange *psRange,
1115*61046927SAndroid Build Coastguard Worker uint32_t flags)
1116*61046927SAndroid Build Coastguard Worker {
1117*61046927SAndroid Build Coastguard Worker const uint32_t layer_count =
1118*61046927SAndroid Build Coastguard Worker vk_image_subresource_layer_count(&image->vk, psRange);
1119*61046927SAndroid Build Coastguard Worker const uint32_t max_layers = psRange->baseArrayLayer + layer_count;
1120*61046927SAndroid Build Coastguard Worker VkFormat format = image->vk.format;
1121*61046927SAndroid Build Coastguard Worker const VkOffset3D offset = { 0 };
1122*61046927SAndroid Build Coastguard Worker VkExtent3D mip_extent;
1123*61046927SAndroid Build Coastguard Worker
1124*61046927SAndroid Build Coastguard Worker assert((psRange->baseArrayLayer + layer_count) <= image->vk.array_layers);
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker for (uint32_t layer = psRange->baseArrayLayer; layer < max_layers; layer++) {
1127*61046927SAndroid Build Coastguard Worker const uint32_t level_count =
1128*61046927SAndroid Build Coastguard Worker vk_image_subresource_level_count(&image->vk, psRange);
1129*61046927SAndroid Build Coastguard Worker const uint32_t max_level = psRange->baseMipLevel + level_count;
1130*61046927SAndroid Build Coastguard Worker
1131*61046927SAndroid Build Coastguard Worker assert((psRange->baseMipLevel + level_count) <= image->vk.mip_levels);
1132*61046927SAndroid Build Coastguard Worker
1133*61046927SAndroid Build Coastguard Worker for (uint32_t level = psRange->baseMipLevel; level < max_level; level++) {
1134*61046927SAndroid Build Coastguard Worker pvr_calc_mip_level_extents(image, level, &mip_extent);
1135*61046927SAndroid Build Coastguard Worker
1136*61046927SAndroid Build Coastguard Worker for (uint32_t depth = 0; depth < mip_extent.depth; depth++) {
1137*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
1138*61046927SAndroid Build Coastguard Worker VkResult result;
1139*61046927SAndroid Build Coastguard Worker
1140*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
1141*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
1142*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
1143*61046927SAndroid Build Coastguard Worker
1144*61046927SAndroid Build Coastguard Worker transfer_cmd->flags |= flags;
1145*61046927SAndroid Build Coastguard Worker transfer_cmd->flags |= PVR_TRANSFER_CMD_FLAGS_FILL;
1146*61046927SAndroid Build Coastguard Worker
1147*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(transfer_cmd->clear_color); i++)
1148*61046927SAndroid Build Coastguard Worker transfer_cmd->clear_color[i].ui = pColor->uint32[i];
1149*61046927SAndroid Build Coastguard Worker
1150*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(cmd_buffer->device,
1151*61046927SAndroid Build Coastguard Worker &transfer_cmd->dst,
1152*61046927SAndroid Build Coastguard Worker &transfer_cmd->scissor,
1153*61046927SAndroid Build Coastguard Worker image,
1154*61046927SAndroid Build Coastguard Worker layer,
1155*61046927SAndroid Build Coastguard Worker level,
1156*61046927SAndroid Build Coastguard Worker &offset,
1157*61046927SAndroid Build Coastguard Worker &mip_extent,
1158*61046927SAndroid Build Coastguard Worker depth,
1159*61046927SAndroid Build Coastguard Worker format,
1160*61046927SAndroid Build Coastguard Worker psRange->aspectMask);
1161*61046927SAndroid Build Coastguard Worker
1162*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
1163*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1164*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
1165*61046927SAndroid Build Coastguard Worker return result;
1166*61046927SAndroid Build Coastguard Worker }
1167*61046927SAndroid Build Coastguard Worker }
1168*61046927SAndroid Build Coastguard Worker }
1169*61046927SAndroid Build Coastguard Worker }
1170*61046927SAndroid Build Coastguard Worker
1171*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1172*61046927SAndroid Build Coastguard Worker }
1173*61046927SAndroid Build Coastguard Worker
pvr_CmdClearColorImage(VkCommandBuffer commandBuffer,VkImage _image,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1174*61046927SAndroid Build Coastguard Worker void pvr_CmdClearColorImage(VkCommandBuffer commandBuffer,
1175*61046927SAndroid Build Coastguard Worker VkImage _image,
1176*61046927SAndroid Build Coastguard Worker VkImageLayout imageLayout,
1177*61046927SAndroid Build Coastguard Worker const VkClearColorValue *pColor,
1178*61046927SAndroid Build Coastguard Worker uint32_t rangeCount,
1179*61046927SAndroid Build Coastguard Worker const VkImageSubresourceRange *pRanges)
1180*61046927SAndroid Build Coastguard Worker {
1181*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1182*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, image, _image);
1183*61046927SAndroid Build Coastguard Worker
1184*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rangeCount; i++) {
1185*61046927SAndroid Build Coastguard Worker const VkResult result =
1186*61046927SAndroid Build Coastguard Worker pvr_clear_image_range(cmd_buffer, image, pColor, &pRanges[i], 0);
1187*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1188*61046927SAndroid Build Coastguard Worker return;
1189*61046927SAndroid Build Coastguard Worker }
1190*61046927SAndroid Build Coastguard Worker }
1191*61046927SAndroid Build Coastguard Worker
pvr_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,VkImage _image,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1192*61046927SAndroid Build Coastguard Worker void pvr_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
1193*61046927SAndroid Build Coastguard Worker VkImage _image,
1194*61046927SAndroid Build Coastguard Worker VkImageLayout imageLayout,
1195*61046927SAndroid Build Coastguard Worker const VkClearDepthStencilValue *pDepthStencil,
1196*61046927SAndroid Build Coastguard Worker uint32_t rangeCount,
1197*61046927SAndroid Build Coastguard Worker const VkImageSubresourceRange *pRanges)
1198*61046927SAndroid Build Coastguard Worker {
1199*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1200*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, image, _image);
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rangeCount; i++) {
1203*61046927SAndroid Build Coastguard Worker const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT |
1204*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_STENCIL_BIT;
1205*61046927SAndroid Build Coastguard Worker VkClearColorValue clear_ds = { 0 };
1206*61046927SAndroid Build Coastguard Worker uint32_t flags = 0U;
1207*61046927SAndroid Build Coastguard Worker VkResult result;
1208*61046927SAndroid Build Coastguard Worker
1209*61046927SAndroid Build Coastguard Worker if (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
1210*61046927SAndroid Build Coastguard Worker pRanges[i].aspectMask != ds_aspect) {
1211*61046927SAndroid Build Coastguard Worker /* A depth or stencil blit to a packed_depth_stencil requires a merge
1212*61046927SAndroid Build Coastguard Worker * operation.
1213*61046927SAndroid Build Coastguard Worker */
1214*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_DSMERGE;
1215*61046927SAndroid Build Coastguard Worker
1216*61046927SAndroid Build Coastguard Worker if (pRanges[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
1217*61046927SAndroid Build Coastguard Worker flags |= PVR_TRANSFER_CMD_FLAGS_PICKD;
1218*61046927SAndroid Build Coastguard Worker }
1219*61046927SAndroid Build Coastguard Worker
1220*61046927SAndroid Build Coastguard Worker clear_ds.float32[0] = pDepthStencil->depth;
1221*61046927SAndroid Build Coastguard Worker clear_ds.uint32[1] = pDepthStencil->stencil;
1222*61046927SAndroid Build Coastguard Worker
1223*61046927SAndroid Build Coastguard Worker result =
1224*61046927SAndroid Build Coastguard Worker pvr_clear_image_range(cmd_buffer, image, &clear_ds, pRanges + i, flags);
1225*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1226*61046927SAndroid Build Coastguard Worker return;
1227*61046927SAndroid Build Coastguard Worker }
1228*61046927SAndroid Build Coastguard Worker }
1229*61046927SAndroid Build Coastguard Worker
pvr_cmd_copy_buffer_region(struct pvr_cmd_buffer * cmd_buffer,pvr_dev_addr_t src_addr,VkDeviceSize src_offset,pvr_dev_addr_t dst_addr,VkDeviceSize dst_offset,VkDeviceSize size,uint32_t fill_data,bool is_fill)1230*61046927SAndroid Build Coastguard Worker static VkResult pvr_cmd_copy_buffer_region(struct pvr_cmd_buffer *cmd_buffer,
1231*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t src_addr,
1232*61046927SAndroid Build Coastguard Worker VkDeviceSize src_offset,
1233*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t dst_addr,
1234*61046927SAndroid Build Coastguard Worker VkDeviceSize dst_offset,
1235*61046927SAndroid Build Coastguard Worker VkDeviceSize size,
1236*61046927SAndroid Build Coastguard Worker uint32_t fill_data,
1237*61046927SAndroid Build Coastguard Worker bool is_fill)
1238*61046927SAndroid Build Coastguard Worker {
1239*61046927SAndroid Build Coastguard Worker VkDeviceSize offset = 0;
1240*61046927SAndroid Build Coastguard Worker
1241*61046927SAndroid Build Coastguard Worker while (offset < size) {
1242*61046927SAndroid Build Coastguard Worker const VkDeviceSize remaining_size = size - offset;
1243*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd;
1244*61046927SAndroid Build Coastguard Worker uint32_t texel_width;
1245*61046927SAndroid Build Coastguard Worker VkDeviceSize texels;
1246*61046927SAndroid Build Coastguard Worker VkFormat vk_format;
1247*61046927SAndroid Build Coastguard Worker VkResult result;
1248*61046927SAndroid Build Coastguard Worker uint32_t height;
1249*61046927SAndroid Build Coastguard Worker uint32_t width;
1250*61046927SAndroid Build Coastguard Worker
1251*61046927SAndroid Build Coastguard Worker if (is_fill) {
1252*61046927SAndroid Build Coastguard Worker vk_format = VK_FORMAT_R32_UINT;
1253*61046927SAndroid Build Coastguard Worker texel_width = 4U;
1254*61046927SAndroid Build Coastguard Worker } else if (remaining_size >= 16U) {
1255*61046927SAndroid Build Coastguard Worker vk_format = VK_FORMAT_R32G32B32A32_UINT;
1256*61046927SAndroid Build Coastguard Worker texel_width = 16U;
1257*61046927SAndroid Build Coastguard Worker } else if (remaining_size >= 4U) {
1258*61046927SAndroid Build Coastguard Worker vk_format = VK_FORMAT_R32_UINT;
1259*61046927SAndroid Build Coastguard Worker texel_width = 4U;
1260*61046927SAndroid Build Coastguard Worker } else {
1261*61046927SAndroid Build Coastguard Worker vk_format = VK_FORMAT_R8_UINT;
1262*61046927SAndroid Build Coastguard Worker texel_width = 1U;
1263*61046927SAndroid Build Coastguard Worker }
1264*61046927SAndroid Build Coastguard Worker
1265*61046927SAndroid Build Coastguard Worker texels = remaining_size / texel_width;
1266*61046927SAndroid Build Coastguard Worker
1267*61046927SAndroid Build Coastguard Worker /* Try to do max-width rects, fall back to a 1-height rect for the
1268*61046927SAndroid Build Coastguard Worker * remainder.
1269*61046927SAndroid Build Coastguard Worker */
1270*61046927SAndroid Build Coastguard Worker if (texels > PVR_MAX_TRANSFER_SIZE_IN_TEXELS) {
1271*61046927SAndroid Build Coastguard Worker width = PVR_MAX_TRANSFER_SIZE_IN_TEXELS;
1272*61046927SAndroid Build Coastguard Worker height = texels / PVR_MAX_TRANSFER_SIZE_IN_TEXELS;
1273*61046927SAndroid Build Coastguard Worker height = MIN2(height, PVR_MAX_TRANSFER_SIZE_IN_TEXELS);
1274*61046927SAndroid Build Coastguard Worker } else {
1275*61046927SAndroid Build Coastguard Worker width = texels;
1276*61046927SAndroid Build Coastguard Worker height = 1;
1277*61046927SAndroid Build Coastguard Worker }
1278*61046927SAndroid Build Coastguard Worker
1279*61046927SAndroid Build Coastguard Worker transfer_cmd = pvr_transfer_cmd_alloc(cmd_buffer);
1280*61046927SAndroid Build Coastguard Worker if (!transfer_cmd)
1281*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
1282*61046927SAndroid Build Coastguard Worker
1283*61046927SAndroid Build Coastguard Worker if (!is_fill) {
1284*61046927SAndroid Build Coastguard Worker pvr_setup_buffer_surface(
1285*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].surface,
1286*61046927SAndroid Build Coastguard Worker &transfer_cmd->sources[0].mappings[0].src_rect,
1287*61046927SAndroid Build Coastguard Worker src_addr,
1288*61046927SAndroid Build Coastguard Worker offset + src_offset,
1289*61046927SAndroid Build Coastguard Worker vk_format,
1290*61046927SAndroid Build Coastguard Worker vk_format,
1291*61046927SAndroid Build Coastguard Worker width,
1292*61046927SAndroid Build Coastguard Worker height,
1293*61046927SAndroid Build Coastguard Worker width);
1294*61046927SAndroid Build Coastguard Worker transfer_cmd->source_count = 1;
1295*61046927SAndroid Build Coastguard Worker } else {
1296*61046927SAndroid Build Coastguard Worker transfer_cmd->flags |= PVR_TRANSFER_CMD_FLAGS_FILL;
1297*61046927SAndroid Build Coastguard Worker
1298*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(transfer_cmd->clear_color); i++)
1299*61046927SAndroid Build Coastguard Worker transfer_cmd->clear_color[i].ui = fill_data;
1300*61046927SAndroid Build Coastguard Worker }
1301*61046927SAndroid Build Coastguard Worker
1302*61046927SAndroid Build Coastguard Worker pvr_setup_buffer_surface(&transfer_cmd->dst,
1303*61046927SAndroid Build Coastguard Worker &transfer_cmd->scissor,
1304*61046927SAndroid Build Coastguard Worker dst_addr,
1305*61046927SAndroid Build Coastguard Worker offset + dst_offset,
1306*61046927SAndroid Build Coastguard Worker vk_format,
1307*61046927SAndroid Build Coastguard Worker vk_format,
1308*61046927SAndroid Build Coastguard Worker width,
1309*61046927SAndroid Build Coastguard Worker height,
1310*61046927SAndroid Build Coastguard Worker width);
1311*61046927SAndroid Build Coastguard Worker
1312*61046927SAndroid Build Coastguard Worker if (transfer_cmd->source_count > 0) {
1313*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mappings[0].dst_rect = transfer_cmd->scissor;
1314*61046927SAndroid Build Coastguard Worker
1315*61046927SAndroid Build Coastguard Worker transfer_cmd->sources[0].mapping_count++;
1316*61046927SAndroid Build Coastguard Worker }
1317*61046927SAndroid Build Coastguard Worker
1318*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
1319*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1320*61046927SAndroid Build Coastguard Worker vk_free(&cmd_buffer->vk.pool->alloc, transfer_cmd);
1321*61046927SAndroid Build Coastguard Worker return result;
1322*61046927SAndroid Build Coastguard Worker }
1323*61046927SAndroid Build Coastguard Worker
1324*61046927SAndroid Build Coastguard Worker offset += width * height * texel_width;
1325*61046927SAndroid Build Coastguard Worker }
1326*61046927SAndroid Build Coastguard Worker
1327*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1328*61046927SAndroid Build Coastguard Worker }
1329*61046927SAndroid Build Coastguard Worker
pvr_CmdUpdateBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize dataSize,const void * pData)1330*61046927SAndroid Build Coastguard Worker void pvr_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
1331*61046927SAndroid Build Coastguard Worker VkBuffer dstBuffer,
1332*61046927SAndroid Build Coastguard Worker VkDeviceSize dstOffset,
1333*61046927SAndroid Build Coastguard Worker VkDeviceSize dataSize,
1334*61046927SAndroid Build Coastguard Worker const void *pData)
1335*61046927SAndroid Build Coastguard Worker {
1336*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1337*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, dst, dstBuffer);
1338*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *pvr_bo;
1339*61046927SAndroid Build Coastguard Worker VkResult result;
1340*61046927SAndroid Build Coastguard Worker
1341*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
1342*61046927SAndroid Build Coastguard Worker
1343*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_upload_general(cmd_buffer, pData, dataSize, &pvr_bo);
1344*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1345*61046927SAndroid Build Coastguard Worker return;
1346*61046927SAndroid Build Coastguard Worker
1347*61046927SAndroid Build Coastguard Worker pvr_cmd_copy_buffer_region(cmd_buffer,
1348*61046927SAndroid Build Coastguard Worker pvr_bo->dev_addr,
1349*61046927SAndroid Build Coastguard Worker 0,
1350*61046927SAndroid Build Coastguard Worker dst->dev_addr,
1351*61046927SAndroid Build Coastguard Worker dstOffset,
1352*61046927SAndroid Build Coastguard Worker dataSize,
1353*61046927SAndroid Build Coastguard Worker 0U,
1354*61046927SAndroid Build Coastguard Worker false);
1355*61046927SAndroid Build Coastguard Worker }
1356*61046927SAndroid Build Coastguard Worker
pvr_CmdCopyBuffer2(VkCommandBuffer commandBuffer,const VkCopyBufferInfo2 * pCopyBufferInfo)1357*61046927SAndroid Build Coastguard Worker void pvr_CmdCopyBuffer2(VkCommandBuffer commandBuffer,
1358*61046927SAndroid Build Coastguard Worker const VkCopyBufferInfo2 *pCopyBufferInfo)
1359*61046927SAndroid Build Coastguard Worker {
1360*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, src, pCopyBufferInfo->srcBuffer);
1361*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, dst, pCopyBufferInfo->dstBuffer);
1362*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1363*61046927SAndroid Build Coastguard Worker
1364*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
1365*61046927SAndroid Build Coastguard Worker
1366*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCopyBufferInfo->regionCount; i++) {
1367*61046927SAndroid Build Coastguard Worker const VkResult result =
1368*61046927SAndroid Build Coastguard Worker pvr_cmd_copy_buffer_region(cmd_buffer,
1369*61046927SAndroid Build Coastguard Worker src->dev_addr,
1370*61046927SAndroid Build Coastguard Worker pCopyBufferInfo->pRegions[i].srcOffset,
1371*61046927SAndroid Build Coastguard Worker dst->dev_addr,
1372*61046927SAndroid Build Coastguard Worker pCopyBufferInfo->pRegions[i].dstOffset,
1373*61046927SAndroid Build Coastguard Worker pCopyBufferInfo->pRegions[i].size,
1374*61046927SAndroid Build Coastguard Worker 0U,
1375*61046927SAndroid Build Coastguard Worker false);
1376*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1377*61046927SAndroid Build Coastguard Worker return;
1378*61046927SAndroid Build Coastguard Worker }
1379*61046927SAndroid Build Coastguard Worker }
1380*61046927SAndroid Build Coastguard Worker
pvr_CmdFillBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize fillSize,uint32_t data)1381*61046927SAndroid Build Coastguard Worker void pvr_CmdFillBuffer(VkCommandBuffer commandBuffer,
1382*61046927SAndroid Build Coastguard Worker VkBuffer dstBuffer,
1383*61046927SAndroid Build Coastguard Worker VkDeviceSize dstOffset,
1384*61046927SAndroid Build Coastguard Worker VkDeviceSize fillSize,
1385*61046927SAndroid Build Coastguard Worker uint32_t data)
1386*61046927SAndroid Build Coastguard Worker {
1387*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
1388*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_buffer, dst, dstBuffer);
1389*61046927SAndroid Build Coastguard Worker
1390*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
1391*61046927SAndroid Build Coastguard Worker
1392*61046927SAndroid Build Coastguard Worker fillSize = vk_buffer_range(&dst->vk, dstOffset, fillSize);
1393*61046927SAndroid Build Coastguard Worker
1394*61046927SAndroid Build Coastguard Worker /* From the Vulkan spec:
1395*61046927SAndroid Build Coastguard Worker *
1396*61046927SAndroid Build Coastguard Worker * "size is the number of bytes to fill, and must be either a multiple
1397*61046927SAndroid Build Coastguard Worker * of 4, or VK_WHOLE_SIZE to fill the range from offset to the end of
1398*61046927SAndroid Build Coastguard Worker * the buffer. If VK_WHOLE_SIZE is used and the remaining size of the
1399*61046927SAndroid Build Coastguard Worker * buffer is not a multiple of 4, then the nearest smaller multiple is
1400*61046927SAndroid Build Coastguard Worker * used."
1401*61046927SAndroid Build Coastguard Worker */
1402*61046927SAndroid Build Coastguard Worker fillSize &= ~3ULL;
1403*61046927SAndroid Build Coastguard Worker
1404*61046927SAndroid Build Coastguard Worker pvr_cmd_copy_buffer_region(cmd_buffer,
1405*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_INVALID,
1406*61046927SAndroid Build Coastguard Worker 0,
1407*61046927SAndroid Build Coastguard Worker dst->dev_addr,
1408*61046927SAndroid Build Coastguard Worker dstOffset,
1409*61046927SAndroid Build Coastguard Worker fillSize,
1410*61046927SAndroid Build Coastguard Worker data,
1411*61046927SAndroid Build Coastguard Worker true);
1412*61046927SAndroid Build Coastguard Worker }
1413*61046927SAndroid Build Coastguard Worker
1414*61046927SAndroid Build Coastguard Worker /**
1415*61046927SAndroid Build Coastguard Worker * \brief Returns the maximum number of layers to clear starting from base_layer
1416*61046927SAndroid Build Coastguard Worker * that contain or match the target rectangle.
1417*61046927SAndroid Build Coastguard Worker *
1418*61046927SAndroid Build Coastguard Worker * \param[in] target_rect The region which the clear should contain or
1419*61046927SAndroid Build Coastguard Worker * match.
1420*61046927SAndroid Build Coastguard Worker * \param[in] base_layer The layer index to start at.
1421*61046927SAndroid Build Coastguard Worker * \param[in] clear_rect_count Amount of clear_rects
1422*61046927SAndroid Build Coastguard Worker * \param[in] clear_rects Array of clear rects.
1423*61046927SAndroid Build Coastguard Worker *
1424*61046927SAndroid Build Coastguard Worker * \return Max number of layers that cover or match the target region.
1425*61046927SAndroid Build Coastguard Worker */
1426*61046927SAndroid Build Coastguard Worker static uint32_t
pvr_get_max_layers_covering_target(VkRect2D target_rect,uint32_t base_layer,uint32_t clear_rect_count,const VkClearRect * clear_rects)1427*61046927SAndroid Build Coastguard Worker pvr_get_max_layers_covering_target(VkRect2D target_rect,
1428*61046927SAndroid Build Coastguard Worker uint32_t base_layer,
1429*61046927SAndroid Build Coastguard Worker uint32_t clear_rect_count,
1430*61046927SAndroid Build Coastguard Worker const VkClearRect *clear_rects)
1431*61046927SAndroid Build Coastguard Worker {
1432*61046927SAndroid Build Coastguard Worker const int32_t target_x0 = target_rect.offset.x;
1433*61046927SAndroid Build Coastguard Worker const int32_t target_x1 = target_x0 + (int32_t)target_rect.extent.width;
1434*61046927SAndroid Build Coastguard Worker const int32_t target_y0 = target_rect.offset.y;
1435*61046927SAndroid Build Coastguard Worker const int32_t target_y1 = target_y0 + (int32_t)target_rect.extent.height;
1436*61046927SAndroid Build Coastguard Worker
1437*61046927SAndroid Build Coastguard Worker uint32_t layer_count = 0;
1438*61046927SAndroid Build Coastguard Worker
1439*61046927SAndroid Build Coastguard Worker assert((int64_t)target_x0 + (int64_t)target_rect.extent.width <= INT32_MAX);
1440*61046927SAndroid Build Coastguard Worker assert((int64_t)target_y0 + (int64_t)target_rect.extent.height <= INT32_MAX);
1441*61046927SAndroid Build Coastguard Worker
1442*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < clear_rect_count; i++) {
1443*61046927SAndroid Build Coastguard Worker const VkClearRect *clear_rect = &clear_rects[i];
1444*61046927SAndroid Build Coastguard Worker const uint32_t max_layer =
1445*61046927SAndroid Build Coastguard Worker clear_rect->baseArrayLayer + clear_rect->layerCount;
1446*61046927SAndroid Build Coastguard Worker bool target_is_covered;
1447*61046927SAndroid Build Coastguard Worker int32_t x0, x1;
1448*61046927SAndroid Build Coastguard Worker int32_t y0, y1;
1449*61046927SAndroid Build Coastguard Worker
1450*61046927SAndroid Build Coastguard Worker if (clear_rect->baseArrayLayer == 0)
1451*61046927SAndroid Build Coastguard Worker continue;
1452*61046927SAndroid Build Coastguard Worker
1453*61046927SAndroid Build Coastguard Worker assert((uint64_t)clear_rect->baseArrayLayer + clear_rect->layerCount <=
1454*61046927SAndroid Build Coastguard Worker UINT32_MAX);
1455*61046927SAndroid Build Coastguard Worker
1456*61046927SAndroid Build Coastguard Worker /* Check for layer intersection. */
1457*61046927SAndroid Build Coastguard Worker if (clear_rect->baseArrayLayer > base_layer || max_layer <= base_layer)
1458*61046927SAndroid Build Coastguard Worker continue;
1459*61046927SAndroid Build Coastguard Worker
1460*61046927SAndroid Build Coastguard Worker x0 = clear_rect->rect.offset.x;
1461*61046927SAndroid Build Coastguard Worker x1 = x0 + (int32_t)clear_rect->rect.extent.width;
1462*61046927SAndroid Build Coastguard Worker y0 = clear_rect->rect.offset.y;
1463*61046927SAndroid Build Coastguard Worker y1 = y0 + (int32_t)clear_rect->rect.extent.height;
1464*61046927SAndroid Build Coastguard Worker
1465*61046927SAndroid Build Coastguard Worker assert((int64_t)x0 + (int64_t)clear_rect->rect.extent.width <= INT32_MAX);
1466*61046927SAndroid Build Coastguard Worker assert((int64_t)y0 + (int64_t)clear_rect->rect.extent.height <=
1467*61046927SAndroid Build Coastguard Worker INT32_MAX);
1468*61046927SAndroid Build Coastguard Worker
1469*61046927SAndroid Build Coastguard Worker target_is_covered = x0 <= target_x0 && x1 >= target_x1;
1470*61046927SAndroid Build Coastguard Worker target_is_covered &= y0 <= target_y0 && y1 >= target_y1;
1471*61046927SAndroid Build Coastguard Worker
1472*61046927SAndroid Build Coastguard Worker if (target_is_covered)
1473*61046927SAndroid Build Coastguard Worker layer_count = MAX2(layer_count, max_layer - base_layer);
1474*61046927SAndroid Build Coastguard Worker }
1475*61046927SAndroid Build Coastguard Worker
1476*61046927SAndroid Build Coastguard Worker return layer_count;
1477*61046927SAndroid Build Coastguard Worker }
1478*61046927SAndroid Build Coastguard Worker
1479*61046927SAndroid Build Coastguard Worker /* Return true if vertex shader is required to output render target id to pick
1480*61046927SAndroid Build Coastguard Worker * the texture array layer.
1481*61046927SAndroid Build Coastguard Worker */
1482*61046927SAndroid Build Coastguard Worker static inline bool
pvr_clear_needs_rt_id_output(struct pvr_device_info * dev_info,uint32_t rect_count,const VkClearRect * rects)1483*61046927SAndroid Build Coastguard Worker pvr_clear_needs_rt_id_output(struct pvr_device_info *dev_info,
1484*61046927SAndroid Build Coastguard Worker uint32_t rect_count,
1485*61046927SAndroid Build Coastguard Worker const VkClearRect *rects)
1486*61046927SAndroid Build Coastguard Worker {
1487*61046927SAndroid Build Coastguard Worker if (!PVR_HAS_FEATURE(dev_info, gs_rta_support))
1488*61046927SAndroid Build Coastguard Worker return false;
1489*61046927SAndroid Build Coastguard Worker
1490*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rect_count; i++) {
1491*61046927SAndroid Build Coastguard Worker if (rects[i].baseArrayLayer != 0 || rects[i].layerCount > 1)
1492*61046927SAndroid Build Coastguard Worker return true;
1493*61046927SAndroid Build Coastguard Worker }
1494*61046927SAndroid Build Coastguard Worker
1495*61046927SAndroid Build Coastguard Worker return false;
1496*61046927SAndroid Build Coastguard Worker }
1497*61046927SAndroid Build Coastguard Worker
pvr_clear_color_attachment_static_create_consts_buffer(struct pvr_cmd_buffer * cmd_buffer,const struct pvr_shader_factory_info * shader_info,const uint32_t clear_color[static const PVR_CLEAR_COLOR_ARRAY_SIZE],ASSERTED bool uses_tile_buffer,uint32_t tile_buffer_idx,struct pvr_suballoc_bo ** const const_shareds_buffer_out)1498*61046927SAndroid Build Coastguard Worker static VkResult pvr_clear_color_attachment_static_create_consts_buffer(
1499*61046927SAndroid Build Coastguard Worker struct pvr_cmd_buffer *cmd_buffer,
1500*61046927SAndroid Build Coastguard Worker const struct pvr_shader_factory_info *shader_info,
1501*61046927SAndroid Build Coastguard Worker const uint32_t clear_color[static const PVR_CLEAR_COLOR_ARRAY_SIZE],
1502*61046927SAndroid Build Coastguard Worker ASSERTED bool uses_tile_buffer,
1503*61046927SAndroid Build Coastguard Worker uint32_t tile_buffer_idx,
1504*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo **const const_shareds_buffer_out)
1505*61046927SAndroid Build Coastguard Worker {
1506*61046927SAndroid Build Coastguard Worker struct pvr_device *device = cmd_buffer->device;
1507*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *const_shareds_buffer;
1508*61046927SAndroid Build Coastguard Worker struct pvr_bo *tile_buffer;
1509*61046927SAndroid Build Coastguard Worker uint64_t tile_dev_addr;
1510*61046927SAndroid Build Coastguard Worker uint32_t *buffer;
1511*61046927SAndroid Build Coastguard Worker VkResult result;
1512*61046927SAndroid Build Coastguard Worker
1513*61046927SAndroid Build Coastguard Worker /* TODO: This doesn't need to be aligned to slc size. Alignment to 4 is fine.
1514*61046927SAndroid Build Coastguard Worker * Change pvr_cmd_buffer_alloc_mem() to take in an alignment?
1515*61046927SAndroid Build Coastguard Worker */
1516*61046927SAndroid Build Coastguard Worker result =
1517*61046927SAndroid Build Coastguard Worker pvr_cmd_buffer_alloc_mem(cmd_buffer,
1518*61046927SAndroid Build Coastguard Worker device->heaps.general_heap,
1519*61046927SAndroid Build Coastguard Worker PVR_DW_TO_BYTES(shader_info->const_shared_regs),
1520*61046927SAndroid Build Coastguard Worker &const_shareds_buffer);
1521*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1522*61046927SAndroid Build Coastguard Worker return result;
1523*61046927SAndroid Build Coastguard Worker
1524*61046927SAndroid Build Coastguard Worker buffer = pvr_bo_suballoc_get_map_addr(const_shareds_buffer);
1525*61046927SAndroid Build Coastguard Worker
1526*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_CLEAR_ATTACHMENT_CONST_COUNT; i++) {
1527*61046927SAndroid Build Coastguard Worker uint32_t dest_idx = shader_info->driver_const_location_map[i];
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker if (dest_idx == PVR_CLEAR_ATTACHMENT_DEST_ID_UNUSED)
1530*61046927SAndroid Build Coastguard Worker continue;
1531*61046927SAndroid Build Coastguard Worker
1532*61046927SAndroid Build Coastguard Worker assert(dest_idx < shader_info->const_shared_regs);
1533*61046927SAndroid Build Coastguard Worker
1534*61046927SAndroid Build Coastguard Worker switch (i) {
1535*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_COMPONENT_0:
1536*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_COMPONENT_1:
1537*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_COMPONENT_2:
1538*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_COMPONENT_3:
1539*61046927SAndroid Build Coastguard Worker buffer[dest_idx] = clear_color[i];
1540*61046927SAndroid Build Coastguard Worker break;
1541*61046927SAndroid Build Coastguard Worker
1542*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_TILE_BUFFER_UPPER:
1543*61046927SAndroid Build Coastguard Worker assert(uses_tile_buffer);
1544*61046927SAndroid Build Coastguard Worker tile_buffer = device->tile_buffer_state.buffers[tile_buffer_idx];
1545*61046927SAndroid Build Coastguard Worker tile_dev_addr = tile_buffer->vma->dev_addr.addr;
1546*61046927SAndroid Build Coastguard Worker buffer[dest_idx] = (uint32_t)(tile_dev_addr >> 32);
1547*61046927SAndroid Build Coastguard Worker break;
1548*61046927SAndroid Build Coastguard Worker
1549*61046927SAndroid Build Coastguard Worker case PVR_CLEAR_ATTACHMENT_CONST_TILE_BUFFER_LOWER:
1550*61046927SAndroid Build Coastguard Worker assert(uses_tile_buffer);
1551*61046927SAndroid Build Coastguard Worker tile_buffer = device->tile_buffer_state.buffers[tile_buffer_idx];
1552*61046927SAndroid Build Coastguard Worker tile_dev_addr = tile_buffer->vma->dev_addr.addr;
1553*61046927SAndroid Build Coastguard Worker buffer[dest_idx] = (uint32_t)tile_dev_addr;
1554*61046927SAndroid Build Coastguard Worker break;
1555*61046927SAndroid Build Coastguard Worker
1556*61046927SAndroid Build Coastguard Worker default:
1557*61046927SAndroid Build Coastguard Worker unreachable("Unsupported clear attachment const type.");
1558*61046927SAndroid Build Coastguard Worker }
1559*61046927SAndroid Build Coastguard Worker }
1560*61046927SAndroid Build Coastguard Worker
1561*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < shader_info->num_static_const; i++) {
1562*61046927SAndroid Build Coastguard Worker const struct pvr_static_buffer *static_buff =
1563*61046927SAndroid Build Coastguard Worker &shader_info->static_const_buffer[i];
1564*61046927SAndroid Build Coastguard Worker
1565*61046927SAndroid Build Coastguard Worker assert(static_buff->dst_idx < shader_info->const_shared_regs);
1566*61046927SAndroid Build Coastguard Worker
1567*61046927SAndroid Build Coastguard Worker buffer[static_buff->dst_idx] = static_buff->value;
1568*61046927SAndroid Build Coastguard Worker }
1569*61046927SAndroid Build Coastguard Worker
1570*61046927SAndroid Build Coastguard Worker *const_shareds_buffer_out = const_shareds_buffer;
1571*61046927SAndroid Build Coastguard Worker
1572*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1573*61046927SAndroid Build Coastguard Worker }
1574*61046927SAndroid Build Coastguard Worker
pvr_clear_color_attachment_static(struct pvr_cmd_buffer * cmd_buffer,const struct usc_mrt_resource * mrt_resource,VkFormat format,uint32_t clear_color[static const PVR_CLEAR_COLOR_ARRAY_SIZE],uint32_t template_idx,uint32_t stencil,bool vs_has_rt_id_output)1575*61046927SAndroid Build Coastguard Worker static VkResult pvr_clear_color_attachment_static(
1576*61046927SAndroid Build Coastguard Worker struct pvr_cmd_buffer *cmd_buffer,
1577*61046927SAndroid Build Coastguard Worker const struct usc_mrt_resource *mrt_resource,
1578*61046927SAndroid Build Coastguard Worker VkFormat format,
1579*61046927SAndroid Build Coastguard Worker uint32_t clear_color[static const PVR_CLEAR_COLOR_ARRAY_SIZE],
1580*61046927SAndroid Build Coastguard Worker uint32_t template_idx,
1581*61046927SAndroid Build Coastguard Worker uint32_t stencil,
1582*61046927SAndroid Build Coastguard Worker bool vs_has_rt_id_output)
1583*61046927SAndroid Build Coastguard Worker {
1584*61046927SAndroid Build Coastguard Worker struct pvr_device *device = cmd_buffer->device;
1585*61046927SAndroid Build Coastguard Worker ASSERTED const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1586*61046927SAndroid Build Coastguard Worker ASSERTED const bool has_eight_output_registers =
1587*61046927SAndroid Build Coastguard Worker PVR_HAS_FEATURE(dev_info, eight_output_registers);
1588*61046927SAndroid Build Coastguard Worker const struct pvr_device_static_clear_state *dev_clear_state =
1589*61046927SAndroid Build Coastguard Worker &device->static_clear_state;
1590*61046927SAndroid Build Coastguard Worker const bool uses_tile_buffer = mrt_resource->type ==
1591*61046927SAndroid Build Coastguard Worker USC_MRT_RESOURCE_TYPE_MEMORY;
1592*61046927SAndroid Build Coastguard Worker const struct pvr_pds_clear_attachment_program_info *clear_attachment_program;
1593*61046927SAndroid Build Coastguard Worker struct pvr_pds_pixel_shader_sa_program texture_program;
1594*61046927SAndroid Build Coastguard Worker uint32_t pds_state[PVR_STATIC_CLEAR_PDS_STATE_COUNT];
1595*61046927SAndroid Build Coastguard Worker const struct pvr_shader_factory_info *shader_info;
1596*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *pds_texture_program_bo;
1597*61046927SAndroid Build Coastguard Worker struct pvr_static_clear_ppp_template template;
1598*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *const_shareds_buffer;
1599*61046927SAndroid Build Coastguard Worker uint64_t pds_texture_program_addr;
1600*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *pvr_bo;
1601*61046927SAndroid Build Coastguard Worker uint32_t tile_buffer_idx = 0;
1602*61046927SAndroid Build Coastguard Worker uint32_t out_reg_count;
1603*61046927SAndroid Build Coastguard Worker uint32_t output_offset;
1604*61046927SAndroid Build Coastguard Worker uint32_t program_idx;
1605*61046927SAndroid Build Coastguard Worker uint32_t *buffer;
1606*61046927SAndroid Build Coastguard Worker VkResult result;
1607*61046927SAndroid Build Coastguard Worker
1608*61046927SAndroid Build Coastguard Worker out_reg_count =
1609*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(pvr_get_pbe_accum_format_size_in_bytes(format), 4U);
1610*61046927SAndroid Build Coastguard Worker
1611*61046927SAndroid Build Coastguard Worker if (uses_tile_buffer) {
1612*61046927SAndroid Build Coastguard Worker tile_buffer_idx = mrt_resource->mem.tile_buffer;
1613*61046927SAndroid Build Coastguard Worker output_offset = mrt_resource->mem.offset_dw;
1614*61046927SAndroid Build Coastguard Worker } else {
1615*61046927SAndroid Build Coastguard Worker output_offset = mrt_resource->reg.output_reg;
1616*61046927SAndroid Build Coastguard Worker }
1617*61046927SAndroid Build Coastguard Worker
1618*61046927SAndroid Build Coastguard Worker assert(has_eight_output_registers || out_reg_count + output_offset <= 4);
1619*61046927SAndroid Build Coastguard Worker
1620*61046927SAndroid Build Coastguard Worker program_idx = pvr_get_clear_attachment_program_index(out_reg_count,
1621*61046927SAndroid Build Coastguard Worker output_offset,
1622*61046927SAndroid Build Coastguard Worker uses_tile_buffer);
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker shader_info = clear_attachment_collection[program_idx].info;
1625*61046927SAndroid Build Coastguard Worker
1626*61046927SAndroid Build Coastguard Worker result = pvr_clear_color_attachment_static_create_consts_buffer(
1627*61046927SAndroid Build Coastguard Worker cmd_buffer,
1628*61046927SAndroid Build Coastguard Worker shader_info,
1629*61046927SAndroid Build Coastguard Worker clear_color,
1630*61046927SAndroid Build Coastguard Worker uses_tile_buffer,
1631*61046927SAndroid Build Coastguard Worker tile_buffer_idx,
1632*61046927SAndroid Build Coastguard Worker &const_shareds_buffer);
1633*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1634*61046927SAndroid Build Coastguard Worker return result;
1635*61046927SAndroid Build Coastguard Worker
1636*61046927SAndroid Build Coastguard Worker /* clang-format off */
1637*61046927SAndroid Build Coastguard Worker texture_program = (struct pvr_pds_pixel_shader_sa_program){
1638*61046927SAndroid Build Coastguard Worker .num_texture_dma_kicks = 1,
1639*61046927SAndroid Build Coastguard Worker .texture_dma_address = {
1640*61046927SAndroid Build Coastguard Worker [0] = const_shareds_buffer->dev_addr.addr,
1641*61046927SAndroid Build Coastguard Worker }
1642*61046927SAndroid Build Coastguard Worker };
1643*61046927SAndroid Build Coastguard Worker /* clang-format on */
1644*61046927SAndroid Build Coastguard Worker
1645*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&texture_program.texture_dma_control[0],
1646*61046927SAndroid Build Coastguard Worker PDSINST_DOUT_FIELDS_DOUTD_SRC1,
1647*61046927SAndroid Build Coastguard Worker doutd_src1) {
1648*61046927SAndroid Build Coastguard Worker doutd_src1.dest = PVRX(PDSINST_DOUTD_DEST_COMMON_STORE);
1649*61046927SAndroid Build Coastguard Worker doutd_src1.bsize = shader_info->const_shared_regs;
1650*61046927SAndroid Build Coastguard Worker }
1651*61046927SAndroid Build Coastguard Worker
1652*61046927SAndroid Build Coastguard Worker clear_attachment_program =
1653*61046927SAndroid Build Coastguard Worker &dev_clear_state->pds_clear_attachment_program_info[program_idx];
1654*61046927SAndroid Build Coastguard Worker
1655*61046927SAndroid Build Coastguard Worker /* TODO: This doesn't need to be aligned to slc size. Alignment to 4 is fine.
1656*61046927SAndroid Build Coastguard Worker * Change pvr_cmd_buffer_alloc_mem() to take in an alignment?
1657*61046927SAndroid Build Coastguard Worker */
1658*61046927SAndroid Build Coastguard Worker result = pvr_cmd_buffer_alloc_mem(
1659*61046927SAndroid Build Coastguard Worker cmd_buffer,
1660*61046927SAndroid Build Coastguard Worker device->heaps.pds_heap,
1661*61046927SAndroid Build Coastguard Worker clear_attachment_program->texture_program_data_size,
1662*61046927SAndroid Build Coastguard Worker &pds_texture_program_bo);
1663*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1664*61046927SAndroid Build Coastguard Worker list_del(&const_shareds_buffer->link);
1665*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(const_shareds_buffer);
1666*61046927SAndroid Build Coastguard Worker
1667*61046927SAndroid Build Coastguard Worker return result;
1668*61046927SAndroid Build Coastguard Worker }
1669*61046927SAndroid Build Coastguard Worker
1670*61046927SAndroid Build Coastguard Worker buffer = pvr_bo_suballoc_get_map_addr(pds_texture_program_bo);
1671*61046927SAndroid Build Coastguard Worker pds_texture_program_addr = pds_texture_program_bo->dev_addr.addr -
1672*61046927SAndroid Build Coastguard Worker device->heaps.pds_heap->base_addr.addr;
1673*61046927SAndroid Build Coastguard Worker
1674*61046927SAndroid Build Coastguard Worker pvr_pds_generate_pixel_shader_sa_texture_state_data(
1675*61046927SAndroid Build Coastguard Worker &texture_program,
1676*61046927SAndroid Build Coastguard Worker buffer,
1677*61046927SAndroid Build Coastguard Worker &device->pdevice->dev_info);
1678*61046927SAndroid Build Coastguard Worker
1679*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_SHADERBASE],
1680*61046927SAndroid Build Coastguard Worker TA_STATE_PDS_SHADERBASE,
1681*61046927SAndroid Build Coastguard Worker shaderbase) {
1682*61046927SAndroid Build Coastguard Worker shaderbase.addr = clear_attachment_program->pixel_program_offset;
1683*61046927SAndroid Build Coastguard Worker }
1684*61046927SAndroid Build Coastguard Worker
1685*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXUNICODEBASE],
1686*61046927SAndroid Build Coastguard Worker TA_STATE_PDS_TEXUNICODEBASE,
1687*61046927SAndroid Build Coastguard Worker texunicodebase) {
1688*61046927SAndroid Build Coastguard Worker texunicodebase.addr = clear_attachment_program->texture_program_offset;
1689*61046927SAndroid Build Coastguard Worker }
1690*61046927SAndroid Build Coastguard Worker
1691*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO1],
1692*61046927SAndroid Build Coastguard Worker TA_STATE_PDS_SIZEINFO1,
1693*61046927SAndroid Build Coastguard Worker sizeinfo1) {
1694*61046927SAndroid Build Coastguard Worker sizeinfo1.pds_texturestatesize = DIV_ROUND_UP(
1695*61046927SAndroid Build Coastguard Worker clear_attachment_program->texture_program_data_size,
1696*61046927SAndroid Build Coastguard Worker PVRX(TA_STATE_PDS_SIZEINFO1_PDS_TEXTURESTATESIZE_UNIT_SIZE));
1697*61046927SAndroid Build Coastguard Worker
1698*61046927SAndroid Build Coastguard Worker sizeinfo1.pds_tempsize =
1699*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(clear_attachment_program->texture_program_pds_temps_count,
1700*61046927SAndroid Build Coastguard Worker PVRX(TA_STATE_PDS_SIZEINFO1_PDS_TEMPSIZE_UNIT_SIZE));
1701*61046927SAndroid Build Coastguard Worker }
1702*61046927SAndroid Build Coastguard Worker
1703*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_SIZEINFO2],
1704*61046927SAndroid Build Coastguard Worker TA_STATE_PDS_SIZEINFO2,
1705*61046927SAndroid Build Coastguard Worker sizeinfo2) {
1706*61046927SAndroid Build Coastguard Worker sizeinfo2.usc_sharedsize =
1707*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(shader_info->const_shared_regs,
1708*61046927SAndroid Build Coastguard Worker PVRX(TA_STATE_PDS_SIZEINFO2_USC_SHAREDSIZE_UNIT_SIZE));
1709*61046927SAndroid Build Coastguard Worker }
1710*61046927SAndroid Build Coastguard Worker
1711*61046927SAndroid Build Coastguard Worker /* Dummy coefficient loading program. */
1712*61046927SAndroid Build Coastguard Worker pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_VARYINGBASE] = 0;
1713*61046927SAndroid Build Coastguard Worker
1714*61046927SAndroid Build Coastguard Worker pvr_csb_pack (&pds_state[PVR_STATIC_CLEAR_PPP_PDS_TYPE_TEXTUREDATABASE],
1715*61046927SAndroid Build Coastguard Worker TA_STATE_PDS_TEXTUREDATABASE,
1716*61046927SAndroid Build Coastguard Worker texturedatabase) {
1717*61046927SAndroid Build Coastguard Worker texturedatabase.addr = PVR_DEV_ADDR(pds_texture_program_addr);
1718*61046927SAndroid Build Coastguard Worker }
1719*61046927SAndroid Build Coastguard Worker
1720*61046927SAndroid Build Coastguard Worker assert(template_idx < PVR_STATIC_CLEAR_VARIANT_COUNT);
1721*61046927SAndroid Build Coastguard Worker template =
1722*61046927SAndroid Build Coastguard Worker cmd_buffer->device->static_clear_state.ppp_templates[template_idx];
1723*61046927SAndroid Build Coastguard Worker
1724*61046927SAndroid Build Coastguard Worker template.config.pds_state = &pds_state;
1725*61046927SAndroid Build Coastguard Worker
1726*61046927SAndroid Build Coastguard Worker template.config.ispctl.upass =
1727*61046927SAndroid Build Coastguard Worker cmd_buffer->state.render_pass_info.isp_userpass;
1728*61046927SAndroid Build Coastguard Worker
1729*61046927SAndroid Build Coastguard Worker if (template_idx & VK_IMAGE_ASPECT_STENCIL_BIT)
1730*61046927SAndroid Build Coastguard Worker template.config.ispa.sref = stencil;
1731*61046927SAndroid Build Coastguard Worker
1732*61046927SAndroid Build Coastguard Worker if (vs_has_rt_id_output) {
1733*61046927SAndroid Build Coastguard Worker template.config.output_sel.rhw_pres = true;
1734*61046927SAndroid Build Coastguard Worker template.config.output_sel.render_tgt_pres = true;
1735*61046927SAndroid Build Coastguard Worker template.config.output_sel.vtxsize = 4 + 1;
1736*61046927SAndroid Build Coastguard Worker }
1737*61046927SAndroid Build Coastguard Worker
1738*61046927SAndroid Build Coastguard Worker result = pvr_emit_ppp_from_template(
1739*61046927SAndroid Build Coastguard Worker &cmd_buffer->state.current_sub_cmd->gfx.control_stream,
1740*61046927SAndroid Build Coastguard Worker &template,
1741*61046927SAndroid Build Coastguard Worker &pvr_bo);
1742*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1743*61046927SAndroid Build Coastguard Worker list_del(&pds_texture_program_bo->link);
1744*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(pds_texture_program_bo);
1745*61046927SAndroid Build Coastguard Worker
1746*61046927SAndroid Build Coastguard Worker list_del(&const_shareds_buffer->link);
1747*61046927SAndroid Build Coastguard Worker pvr_bo_suballoc_free(const_shareds_buffer);
1748*61046927SAndroid Build Coastguard Worker
1749*61046927SAndroid Build Coastguard Worker return pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result);
1750*61046927SAndroid Build Coastguard Worker }
1751*61046927SAndroid Build Coastguard Worker
1752*61046927SAndroid Build Coastguard Worker list_add(&pvr_bo->link, &cmd_buffer->bo_list);
1753*61046927SAndroid Build Coastguard Worker
1754*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1755*61046927SAndroid Build Coastguard Worker }
1756*61046927SAndroid Build Coastguard Worker
1757*61046927SAndroid Build Coastguard Worker /**
1758*61046927SAndroid Build Coastguard Worker * \brief Record a deferred clear operation into the command buffer.
1759*61046927SAndroid Build Coastguard Worker *
1760*61046927SAndroid Build Coastguard Worker * Devices which don't have gs_rta_support require extra handling for RTA
1761*61046927SAndroid Build Coastguard Worker * clears. We setup a list of deferred clear transfer commands which will be
1762*61046927SAndroid Build Coastguard Worker * processed at the end of the graphics sub command to account for the missing
1763*61046927SAndroid Build Coastguard Worker * feature.
1764*61046927SAndroid Build Coastguard Worker */
pvr_add_deferred_rta_clear(struct pvr_cmd_buffer * cmd_buffer,const VkClearAttachment * attachment,const VkClearRect * rect,bool is_render_init)1765*61046927SAndroid Build Coastguard Worker static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer,
1766*61046927SAndroid Build Coastguard Worker const VkClearAttachment *attachment,
1767*61046927SAndroid Build Coastguard Worker const VkClearRect *rect,
1768*61046927SAndroid Build Coastguard Worker bool is_render_init)
1769*61046927SAndroid Build Coastguard Worker {
1770*61046927SAndroid Build Coastguard Worker struct pvr_render_pass_info *pass_info = &cmd_buffer->state.render_pass_info;
1771*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_gfx *sub_cmd = &cmd_buffer->state.current_sub_cmd->gfx;
1772*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_render *hw_render =
1773*61046927SAndroid Build Coastguard Worker &pass_info->pass->hw_setup->renders[sub_cmd->hw_render_idx];
1774*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd_list;
1775*61046927SAndroid Build Coastguard Worker const struct pvr_image_view *image_view;
1776*61046927SAndroid Build Coastguard Worker const struct pvr_image *image;
1777*61046927SAndroid Build Coastguard Worker uint32_t base_layer;
1778*61046927SAndroid Build Coastguard Worker
1779*61046927SAndroid Build Coastguard Worker const VkOffset3D offset = {
1780*61046927SAndroid Build Coastguard Worker .x = rect->rect.offset.x,
1781*61046927SAndroid Build Coastguard Worker .y = rect->rect.offset.y,
1782*61046927SAndroid Build Coastguard Worker .z = 1,
1783*61046927SAndroid Build Coastguard Worker };
1784*61046927SAndroid Build Coastguard Worker const VkExtent3D extent = {
1785*61046927SAndroid Build Coastguard Worker .width = rect->rect.extent.width,
1786*61046927SAndroid Build Coastguard Worker .height = rect->rect.extent.height,
1787*61046927SAndroid Build Coastguard Worker .depth = 1,
1788*61046927SAndroid Build Coastguard Worker };
1789*61046927SAndroid Build Coastguard Worker
1790*61046927SAndroid Build Coastguard Worker assert(
1791*61046927SAndroid Build Coastguard Worker !PVR_HAS_FEATURE(&cmd_buffer->device->pdevice->dev_info, gs_rta_support));
1792*61046927SAndroid Build Coastguard Worker
1793*61046927SAndroid Build Coastguard Worker transfer_cmd_list = util_dynarray_grow(&cmd_buffer->deferred_clears,
1794*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd,
1795*61046927SAndroid Build Coastguard Worker rect->layerCount);
1796*61046927SAndroid Build Coastguard Worker if (!transfer_cmd_list) {
1797*61046927SAndroid Build Coastguard Worker return vk_command_buffer_set_error(&cmd_buffer->vk,
1798*61046927SAndroid Build Coastguard Worker VK_ERROR_OUT_OF_HOST_MEMORY);
1799*61046927SAndroid Build Coastguard Worker }
1800*61046927SAndroid Build Coastguard Worker
1801*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.3.229 spec VUID-VkClearAttachment-aspectMask-00019:
1802*61046927SAndroid Build Coastguard Worker *
1803*61046927SAndroid Build Coastguard Worker * "If aspectMask includes VK_IMAGE_ASPECT_COLOR_BIT, it must not
1804*61046927SAndroid Build Coastguard Worker * include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT"
1805*61046927SAndroid Build Coastguard Worker *
1806*61046927SAndroid Build Coastguard Worker */
1807*61046927SAndroid Build Coastguard Worker if (attachment->aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) {
1808*61046927SAndroid Build Coastguard Worker assert(attachment->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
1809*61046927SAndroid Build Coastguard Worker attachment->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT ||
1810*61046927SAndroid Build Coastguard Worker attachment->aspectMask ==
1811*61046927SAndroid Build Coastguard Worker (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1812*61046927SAndroid Build Coastguard Worker
1813*61046927SAndroid Build Coastguard Worker image_view = pass_info->attachments[hw_render->ds_attach_idx];
1814*61046927SAndroid Build Coastguard Worker } else if (is_render_init) {
1815*61046927SAndroid Build Coastguard Worker uint32_t index;
1816*61046927SAndroid Build Coastguard Worker
1817*61046927SAndroid Build Coastguard Worker assert(attachment->colorAttachment < hw_render->color_init_count);
1818*61046927SAndroid Build Coastguard Worker index = hw_render->color_init[attachment->colorAttachment].index;
1819*61046927SAndroid Build Coastguard Worker
1820*61046927SAndroid Build Coastguard Worker image_view = pass_info->attachments[index];
1821*61046927SAndroid Build Coastguard Worker } else {
1822*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_subpass *hw_pass =
1823*61046927SAndroid Build Coastguard Worker pvr_get_hw_subpass(pass_info->pass, pass_info->subpass_idx);
1824*61046927SAndroid Build Coastguard Worker const struct pvr_render_subpass *sub_pass =
1825*61046927SAndroid Build Coastguard Worker &pass_info->pass->subpasses[hw_pass->index];
1826*61046927SAndroid Build Coastguard Worker const uint32_t attachment_idx =
1827*61046927SAndroid Build Coastguard Worker sub_pass->color_attachments[attachment->colorAttachment];
1828*61046927SAndroid Build Coastguard Worker
1829*61046927SAndroid Build Coastguard Worker assert(attachment->colorAttachment < sub_pass->color_count);
1830*61046927SAndroid Build Coastguard Worker
1831*61046927SAndroid Build Coastguard Worker image_view = pass_info->attachments[attachment_idx];
1832*61046927SAndroid Build Coastguard Worker }
1833*61046927SAndroid Build Coastguard Worker
1834*61046927SAndroid Build Coastguard Worker base_layer = image_view->vk.base_array_layer + rect->baseArrayLayer;
1835*61046927SAndroid Build Coastguard Worker image = vk_to_pvr_image(image_view->vk.image);
1836*61046927SAndroid Build Coastguard Worker
1837*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rect->layerCount; i++) {
1838*61046927SAndroid Build Coastguard Worker struct pvr_transfer_cmd *transfer_cmd = &transfer_cmd_list[i];
1839*61046927SAndroid Build Coastguard Worker
1840*61046927SAndroid Build Coastguard Worker /* TODO: Add an init function for when we don't want to use
1841*61046927SAndroid Build Coastguard Worker * pvr_transfer_cmd_alloc()? And use it here.
1842*61046927SAndroid Build Coastguard Worker */
1843*61046927SAndroid Build Coastguard Worker *transfer_cmd = (struct pvr_transfer_cmd){
1844*61046927SAndroid Build Coastguard Worker .flags = PVR_TRANSFER_CMD_FLAGS_FILL,
1845*61046927SAndroid Build Coastguard Worker .cmd_buffer = cmd_buffer,
1846*61046927SAndroid Build Coastguard Worker .is_deferred_clear = true,
1847*61046927SAndroid Build Coastguard Worker };
1848*61046927SAndroid Build Coastguard Worker
1849*61046927SAndroid Build Coastguard Worker if (attachment->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
1850*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < ARRAY_SIZE(transfer_cmd->clear_color); j++) {
1851*61046927SAndroid Build Coastguard Worker transfer_cmd->clear_color[j].ui =
1852*61046927SAndroid Build Coastguard Worker attachment->clearValue.color.uint32[j];
1853*61046927SAndroid Build Coastguard Worker }
1854*61046927SAndroid Build Coastguard Worker } else {
1855*61046927SAndroid Build Coastguard Worker transfer_cmd->clear_color[0].f =
1856*61046927SAndroid Build Coastguard Worker attachment->clearValue.depthStencil.depth;
1857*61046927SAndroid Build Coastguard Worker transfer_cmd->clear_color[1].ui =
1858*61046927SAndroid Build Coastguard Worker attachment->clearValue.depthStencil.stencil;
1859*61046927SAndroid Build Coastguard Worker }
1860*61046927SAndroid Build Coastguard Worker
1861*61046927SAndroid Build Coastguard Worker pvr_setup_transfer_surface(cmd_buffer->device,
1862*61046927SAndroid Build Coastguard Worker &transfer_cmd->dst,
1863*61046927SAndroid Build Coastguard Worker &transfer_cmd->scissor,
1864*61046927SAndroid Build Coastguard Worker image,
1865*61046927SAndroid Build Coastguard Worker base_layer + i,
1866*61046927SAndroid Build Coastguard Worker 0,
1867*61046927SAndroid Build Coastguard Worker &offset,
1868*61046927SAndroid Build Coastguard Worker &extent,
1869*61046927SAndroid Build Coastguard Worker 0.0f,
1870*61046927SAndroid Build Coastguard Worker image->vk.format,
1871*61046927SAndroid Build Coastguard Worker attachment->aspectMask);
1872*61046927SAndroid Build Coastguard Worker }
1873*61046927SAndroid Build Coastguard Worker
1874*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1875*61046927SAndroid Build Coastguard Worker }
1876*61046927SAndroid Build Coastguard Worker
pvr_clear_attachments(struct pvr_cmd_buffer * cmd_buffer,uint32_t attachment_count,const VkClearAttachment * attachments,uint32_t rect_count,const VkClearRect * rects,bool is_render_init)1877*61046927SAndroid Build Coastguard Worker static void pvr_clear_attachments(struct pvr_cmd_buffer *cmd_buffer,
1878*61046927SAndroid Build Coastguard Worker uint32_t attachment_count,
1879*61046927SAndroid Build Coastguard Worker const VkClearAttachment *attachments,
1880*61046927SAndroid Build Coastguard Worker uint32_t rect_count,
1881*61046927SAndroid Build Coastguard Worker const VkClearRect *rects,
1882*61046927SAndroid Build Coastguard Worker bool is_render_init)
1883*61046927SAndroid Build Coastguard Worker {
1884*61046927SAndroid Build Coastguard Worker const struct pvr_render_pass *pass = cmd_buffer->state.render_pass_info.pass;
1885*61046927SAndroid Build Coastguard Worker struct pvr_render_pass_info *pass_info = &cmd_buffer->state.render_pass_info;
1886*61046927SAndroid Build Coastguard Worker const struct pvr_renderpass_hwsetup_subpass *hw_pass =
1887*61046927SAndroid Build Coastguard Worker pvr_get_hw_subpass(pass, pass_info->subpass_idx);
1888*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_gfx *sub_cmd = &cmd_buffer->state.current_sub_cmd->gfx;
1889*61046927SAndroid Build Coastguard Worker struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info;
1890*61046927SAndroid Build Coastguard Worker struct pvr_render_subpass *sub_pass = &pass->subpasses[hw_pass->index];
1891*61046927SAndroid Build Coastguard Worker uint32_t vs_output_size_in_bytes;
1892*61046927SAndroid Build Coastguard Worker bool vs_has_rt_id_output;
1893*61046927SAndroid Build Coastguard Worker
1894*61046927SAndroid Build Coastguard Worker /* TODO: This function can be optimized so that most of the device memory
1895*61046927SAndroid Build Coastguard Worker * gets allocated together in one go and then filled as needed. There might
1896*61046927SAndroid Build Coastguard Worker * also be opportunities to reuse pds code and data segments.
1897*61046927SAndroid Build Coastguard Worker */
1898*61046927SAndroid Build Coastguard Worker
1899*61046927SAndroid Build Coastguard Worker assert(cmd_buffer->state.current_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
1900*61046927SAndroid Build Coastguard Worker
1901*61046927SAndroid Build Coastguard Worker pvr_reset_graphics_dirty_state(cmd_buffer, false);
1902*61046927SAndroid Build Coastguard Worker
1903*61046927SAndroid Build Coastguard Worker /* We'll be emitting to the control stream. */
1904*61046927SAndroid Build Coastguard Worker sub_cmd->empty_cmd = false;
1905*61046927SAndroid Build Coastguard Worker
1906*61046927SAndroid Build Coastguard Worker vs_has_rt_id_output =
1907*61046927SAndroid Build Coastguard Worker pvr_clear_needs_rt_id_output(dev_info, rect_count, rects);
1908*61046927SAndroid Build Coastguard Worker
1909*61046927SAndroid Build Coastguard Worker /* 4 because we're expecting the USC to output X, Y, Z, and W. */
1910*61046927SAndroid Build Coastguard Worker vs_output_size_in_bytes = PVR_DW_TO_BYTES(4);
1911*61046927SAndroid Build Coastguard Worker if (vs_has_rt_id_output)
1912*61046927SAndroid Build Coastguard Worker vs_output_size_in_bytes += PVR_DW_TO_BYTES(1);
1913*61046927SAndroid Build Coastguard Worker
1914*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < attachment_count; i++) {
1915*61046927SAndroid Build Coastguard Worker const VkClearAttachment *attachment = &attachments[i];
1916*61046927SAndroid Build Coastguard Worker struct pvr_pds_vertex_shader_program pds_program;
1917*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload pds_program_upload = { 0 };
1918*61046927SAndroid Build Coastguard Worker uint64_t current_base_array_layer = ~0;
1919*61046927SAndroid Build Coastguard Worker VkResult result;
1920*61046927SAndroid Build Coastguard Worker float depth;
1921*61046927SAndroid Build Coastguard Worker
1922*61046927SAndroid Build Coastguard Worker if (attachment->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
1923*61046927SAndroid Build Coastguard Worker uint32_t packed_clear_color[PVR_CLEAR_COLOR_ARRAY_SIZE];
1924*61046927SAndroid Build Coastguard Worker const struct usc_mrt_resource *mrt_resource;
1925*61046927SAndroid Build Coastguard Worker uint32_t global_attachment_idx;
1926*61046927SAndroid Build Coastguard Worker uint32_t local_attachment_idx;
1927*61046927SAndroid Build Coastguard Worker VkFormat format;
1928*61046927SAndroid Build Coastguard Worker
1929*61046927SAndroid Build Coastguard Worker local_attachment_idx = attachment->colorAttachment;
1930*61046927SAndroid Build Coastguard Worker
1931*61046927SAndroid Build Coastguard Worker if (is_render_init) {
1932*61046927SAndroid Build Coastguard Worker struct pvr_renderpass_hwsetup_render *hw_render;
1933*61046927SAndroid Build Coastguard Worker
1934*61046927SAndroid Build Coastguard Worker assert(pass->hw_setup->render_count > 0);
1935*61046927SAndroid Build Coastguard Worker hw_render = &pass->hw_setup->renders[0];
1936*61046927SAndroid Build Coastguard Worker
1937*61046927SAndroid Build Coastguard Worker mrt_resource =
1938*61046927SAndroid Build Coastguard Worker &hw_render->init_setup.mrt_resources[local_attachment_idx];
1939*61046927SAndroid Build Coastguard Worker
1940*61046927SAndroid Build Coastguard Worker assert(local_attachment_idx < hw_render->color_init_count);
1941*61046927SAndroid Build Coastguard Worker global_attachment_idx =
1942*61046927SAndroid Build Coastguard Worker hw_render->color_init[local_attachment_idx].index;
1943*61046927SAndroid Build Coastguard Worker } else {
1944*61046927SAndroid Build Coastguard Worker mrt_resource = &hw_pass->setup.mrt_resources[local_attachment_idx];
1945*61046927SAndroid Build Coastguard Worker
1946*61046927SAndroid Build Coastguard Worker assert(local_attachment_idx < sub_pass->color_count);
1947*61046927SAndroid Build Coastguard Worker global_attachment_idx =
1948*61046927SAndroid Build Coastguard Worker sub_pass->color_attachments[local_attachment_idx];
1949*61046927SAndroid Build Coastguard Worker }
1950*61046927SAndroid Build Coastguard Worker
1951*61046927SAndroid Build Coastguard Worker if (global_attachment_idx == VK_ATTACHMENT_UNUSED)
1952*61046927SAndroid Build Coastguard Worker continue;
1953*61046927SAndroid Build Coastguard Worker
1954*61046927SAndroid Build Coastguard Worker assert(global_attachment_idx < pass->attachment_count);
1955*61046927SAndroid Build Coastguard Worker format = pass->attachments[global_attachment_idx].vk_format;
1956*61046927SAndroid Build Coastguard Worker
1957*61046927SAndroid Build Coastguard Worker assert(format != VK_FORMAT_UNDEFINED);
1958*61046927SAndroid Build Coastguard Worker
1959*61046927SAndroid Build Coastguard Worker pvr_get_hw_clear_color(format,
1960*61046927SAndroid Build Coastguard Worker attachment->clearValue.color,
1961*61046927SAndroid Build Coastguard Worker packed_clear_color);
1962*61046927SAndroid Build Coastguard Worker
1963*61046927SAndroid Build Coastguard Worker result = pvr_clear_color_attachment_static(cmd_buffer,
1964*61046927SAndroid Build Coastguard Worker mrt_resource,
1965*61046927SAndroid Build Coastguard Worker format,
1966*61046927SAndroid Build Coastguard Worker packed_clear_color,
1967*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT,
1968*61046927SAndroid Build Coastguard Worker 0,
1969*61046927SAndroid Build Coastguard Worker vs_has_rt_id_output);
1970*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1971*61046927SAndroid Build Coastguard Worker return;
1972*61046927SAndroid Build Coastguard Worker } else if (hw_pass->z_replicate != -1 &&
1973*61046927SAndroid Build Coastguard Worker attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
1974*61046927SAndroid Build Coastguard Worker const VkClearColorValue clear_color = {
1975*61046927SAndroid Build Coastguard Worker .float32 = { [0] = attachment->clearValue.depthStencil.depth, },
1976*61046927SAndroid Build Coastguard Worker };
1977*61046927SAndroid Build Coastguard Worker const uint32_t template_idx = attachment->aspectMask |
1978*61046927SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT;
1979*61046927SAndroid Build Coastguard Worker const uint32_t stencil = attachment->clearValue.depthStencil.stencil;
1980*61046927SAndroid Build Coastguard Worker uint32_t packed_clear_color[PVR_CLEAR_COLOR_ARRAY_SIZE];
1981*61046927SAndroid Build Coastguard Worker const struct usc_mrt_resource *mrt_resource;
1982*61046927SAndroid Build Coastguard Worker
1983*61046927SAndroid Build Coastguard Worker mrt_resource = &hw_pass->setup.mrt_resources[hw_pass->z_replicate];
1984*61046927SAndroid Build Coastguard Worker
1985*61046927SAndroid Build Coastguard Worker pvr_get_hw_clear_color(VK_FORMAT_R32_SFLOAT,
1986*61046927SAndroid Build Coastguard Worker clear_color,
1987*61046927SAndroid Build Coastguard Worker packed_clear_color);
1988*61046927SAndroid Build Coastguard Worker
1989*61046927SAndroid Build Coastguard Worker result = pvr_clear_color_attachment_static(cmd_buffer,
1990*61046927SAndroid Build Coastguard Worker mrt_resource,
1991*61046927SAndroid Build Coastguard Worker VK_FORMAT_R32_SFLOAT,
1992*61046927SAndroid Build Coastguard Worker packed_clear_color,
1993*61046927SAndroid Build Coastguard Worker template_idx,
1994*61046927SAndroid Build Coastguard Worker stencil,
1995*61046927SAndroid Build Coastguard Worker vs_has_rt_id_output);
1996*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1997*61046927SAndroid Build Coastguard Worker return;
1998*61046927SAndroid Build Coastguard Worker } else {
1999*61046927SAndroid Build Coastguard Worker const uint32_t template_idx = attachment->aspectMask;
2000*61046927SAndroid Build Coastguard Worker struct pvr_static_clear_ppp_template template;
2001*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *pvr_bo;
2002*61046927SAndroid Build Coastguard Worker
2003*61046927SAndroid Build Coastguard Worker assert(template_idx < PVR_STATIC_CLEAR_VARIANT_COUNT);
2004*61046927SAndroid Build Coastguard Worker template =
2005*61046927SAndroid Build Coastguard Worker cmd_buffer->device->static_clear_state.ppp_templates[template_idx];
2006*61046927SAndroid Build Coastguard Worker
2007*61046927SAndroid Build Coastguard Worker if (attachment->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2008*61046927SAndroid Build Coastguard Worker template.config.ispa.sref =
2009*61046927SAndroid Build Coastguard Worker attachment->clearValue.depthStencil.stencil;
2010*61046927SAndroid Build Coastguard Worker }
2011*61046927SAndroid Build Coastguard Worker
2012*61046927SAndroid Build Coastguard Worker if (vs_has_rt_id_output) {
2013*61046927SAndroid Build Coastguard Worker template.config.output_sel.rhw_pres = true;
2014*61046927SAndroid Build Coastguard Worker template.config.output_sel.render_tgt_pres = true;
2015*61046927SAndroid Build Coastguard Worker template.config.output_sel.vtxsize = 4 + 1;
2016*61046927SAndroid Build Coastguard Worker }
2017*61046927SAndroid Build Coastguard Worker
2018*61046927SAndroid Build Coastguard Worker result = pvr_emit_ppp_from_template(&sub_cmd->control_stream,
2019*61046927SAndroid Build Coastguard Worker &template,
2020*61046927SAndroid Build Coastguard Worker &pvr_bo);
2021*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2022*61046927SAndroid Build Coastguard Worker pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result);
2023*61046927SAndroid Build Coastguard Worker return;
2024*61046927SAndroid Build Coastguard Worker }
2025*61046927SAndroid Build Coastguard Worker
2026*61046927SAndroid Build Coastguard Worker list_add(&pvr_bo->link, &cmd_buffer->bo_list);
2027*61046927SAndroid Build Coastguard Worker }
2028*61046927SAndroid Build Coastguard Worker
2029*61046927SAndroid Build Coastguard Worker if (attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
2030*61046927SAndroid Build Coastguard Worker depth = attachment->clearValue.depthStencil.depth;
2031*61046927SAndroid Build Coastguard Worker else
2032*61046927SAndroid Build Coastguard Worker depth = 1.0f;
2033*61046927SAndroid Build Coastguard Worker
2034*61046927SAndroid Build Coastguard Worker if (vs_has_rt_id_output) {
2035*61046927SAndroid Build Coastguard Worker const struct pvr_device_static_clear_state *dev_clear_state =
2036*61046927SAndroid Build Coastguard Worker &cmd_buffer->device->static_clear_state;
2037*61046927SAndroid Build Coastguard Worker const struct pvr_suballoc_bo *multi_layer_vert_bo =
2038*61046927SAndroid Build Coastguard Worker dev_clear_state->usc_multi_layer_vertex_shader_bo;
2039*61046927SAndroid Build Coastguard Worker
2040*61046927SAndroid Build Coastguard Worker /* We can't use the device's passthrough pds program since it doesn't
2041*61046927SAndroid Build Coastguard Worker * have iterate_instance_id enabled. We'll be uploading code sections
2042*61046927SAndroid Build Coastguard Worker * per each clear rect.
2043*61046927SAndroid Build Coastguard Worker */
2044*61046927SAndroid Build Coastguard Worker
2045*61046927SAndroid Build Coastguard Worker /* TODO: See if we can allocate all the code section memory in one go.
2046*61046927SAndroid Build Coastguard Worker * We'd need to make sure that changing instance_id_modifier doesn't
2047*61046927SAndroid Build Coastguard Worker * change the code section size.
2048*61046927SAndroid Build Coastguard Worker * Also check if we can reuse the same code segment for each rect.
2049*61046927SAndroid Build Coastguard Worker * Seems like the instance_id_modifier is written into the data section
2050*61046927SAndroid Build Coastguard Worker * and used by the pds ADD instruction that way instead of it being
2051*61046927SAndroid Build Coastguard Worker * embedded into the code section.
2052*61046927SAndroid Build Coastguard Worker */
2053*61046927SAndroid Build Coastguard Worker
2054*61046927SAndroid Build Coastguard Worker pvr_pds_clear_rta_vertex_shader_program_init_base(&pds_program,
2055*61046927SAndroid Build Coastguard Worker multi_layer_vert_bo);
2056*61046927SAndroid Build Coastguard Worker } else {
2057*61046927SAndroid Build Coastguard Worker /* We can reuse the device's code section but we'll need to upload data
2058*61046927SAndroid Build Coastguard Worker * sections so initialize the program.
2059*61046927SAndroid Build Coastguard Worker */
2060*61046927SAndroid Build Coastguard Worker pvr_pds_clear_vertex_shader_program_init_base(
2061*61046927SAndroid Build Coastguard Worker &pds_program,
2062*61046927SAndroid Build Coastguard Worker cmd_buffer->device->static_clear_state.usc_vertex_shader_bo);
2063*61046927SAndroid Build Coastguard Worker
2064*61046927SAndroid Build Coastguard Worker pds_program_upload.code_offset =
2065*61046927SAndroid Build Coastguard Worker cmd_buffer->device->static_clear_state.pds.code_offset;
2066*61046927SAndroid Build Coastguard Worker /* TODO: The code size doesn't get used by pvr_clear_vdm_state() maybe
2067*61046927SAndroid Build Coastguard Worker * let's change its interface to make that clear and not set this?
2068*61046927SAndroid Build Coastguard Worker */
2069*61046927SAndroid Build Coastguard Worker pds_program_upload.code_size =
2070*61046927SAndroid Build Coastguard Worker cmd_buffer->device->static_clear_state.pds.code_size;
2071*61046927SAndroid Build Coastguard Worker }
2072*61046927SAndroid Build Coastguard Worker
2073*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < rect_count; j++) {
2074*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload pds_program_data_upload;
2075*61046927SAndroid Build Coastguard Worker const VkClearRect *clear_rect = &rects[j];
2076*61046927SAndroid Build Coastguard Worker struct pvr_suballoc_bo *vertices_bo;
2077*61046927SAndroid Build Coastguard Worker uint32_t vdm_cs_size_in_dw;
2078*61046927SAndroid Build Coastguard Worker uint32_t *vdm_cs_buffer;
2079*61046927SAndroid Build Coastguard Worker VkResult result;
2080*61046927SAndroid Build Coastguard Worker
2081*61046927SAndroid Build Coastguard Worker if (!PVR_HAS_FEATURE(dev_info, gs_rta_support) &&
2082*61046927SAndroid Build Coastguard Worker (clear_rect->baseArrayLayer != 0 || clear_rect->layerCount > 1)) {
2083*61046927SAndroid Build Coastguard Worker result = pvr_add_deferred_rta_clear(cmd_buffer,
2084*61046927SAndroid Build Coastguard Worker attachment,
2085*61046927SAndroid Build Coastguard Worker clear_rect,
2086*61046927SAndroid Build Coastguard Worker is_render_init);
2087*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2088*61046927SAndroid Build Coastguard Worker return;
2089*61046927SAndroid Build Coastguard Worker
2090*61046927SAndroid Build Coastguard Worker if (clear_rect->baseArrayLayer != 0)
2091*61046927SAndroid Build Coastguard Worker continue;
2092*61046927SAndroid Build Coastguard Worker }
2093*61046927SAndroid Build Coastguard Worker
2094*61046927SAndroid Build Coastguard Worker /* TODO: Allocate all the buffers in one go before the loop, and add
2095*61046927SAndroid Build Coastguard Worker * support to multi-alloc bo.
2096*61046927SAndroid Build Coastguard Worker */
2097*61046927SAndroid Build Coastguard Worker result = pvr_clear_vertices_upload(cmd_buffer->device,
2098*61046927SAndroid Build Coastguard Worker &clear_rect->rect,
2099*61046927SAndroid Build Coastguard Worker depth,
2100*61046927SAndroid Build Coastguard Worker &vertices_bo);
2101*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2102*61046927SAndroid Build Coastguard Worker pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result);
2103*61046927SAndroid Build Coastguard Worker return;
2104*61046927SAndroid Build Coastguard Worker }
2105*61046927SAndroid Build Coastguard Worker
2106*61046927SAndroid Build Coastguard Worker list_add(&vertices_bo->link, &cmd_buffer->bo_list);
2107*61046927SAndroid Build Coastguard Worker
2108*61046927SAndroid Build Coastguard Worker if (vs_has_rt_id_output) {
2109*61046927SAndroid Build Coastguard Worker if (current_base_array_layer != clear_rect->baseArrayLayer) {
2110*61046927SAndroid Build Coastguard Worker const uint32_t base_array_layer = clear_rect->baseArrayLayer;
2111*61046927SAndroid Build Coastguard Worker struct pvr_pds_upload pds_program_code_upload;
2112*61046927SAndroid Build Coastguard Worker
2113*61046927SAndroid Build Coastguard Worker result =
2114*61046927SAndroid Build Coastguard Worker pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code(
2115*61046927SAndroid Build Coastguard Worker &pds_program,
2116*61046927SAndroid Build Coastguard Worker cmd_buffer,
2117*61046927SAndroid Build Coastguard Worker base_array_layer,
2118*61046927SAndroid Build Coastguard Worker &pds_program_code_upload);
2119*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2120*61046927SAndroid Build Coastguard Worker pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result);
2121*61046927SAndroid Build Coastguard Worker return;
2122*61046927SAndroid Build Coastguard Worker }
2123*61046927SAndroid Build Coastguard Worker
2124*61046927SAndroid Build Coastguard Worker pds_program_upload.code_offset =
2125*61046927SAndroid Build Coastguard Worker pds_program_code_upload.code_offset;
2126*61046927SAndroid Build Coastguard Worker /* TODO: The code size doesn't get used by pvr_clear_vdm_state()
2127*61046927SAndroid Build Coastguard Worker * maybe let's change its interface to make that clear and not
2128*61046927SAndroid Build Coastguard Worker * set this?
2129*61046927SAndroid Build Coastguard Worker */
2130*61046927SAndroid Build Coastguard Worker pds_program_upload.code_size = pds_program_code_upload.code_size;
2131*61046927SAndroid Build Coastguard Worker
2132*61046927SAndroid Build Coastguard Worker current_base_array_layer = base_array_layer;
2133*61046927SAndroid Build Coastguard Worker }
2134*61046927SAndroid Build Coastguard Worker
2135*61046927SAndroid Build Coastguard Worker result =
2136*61046927SAndroid Build Coastguard Worker pvr_pds_clear_rta_vertex_shader_program_create_and_upload_data(
2137*61046927SAndroid Build Coastguard Worker &pds_program,
2138*61046927SAndroid Build Coastguard Worker cmd_buffer,
2139*61046927SAndroid Build Coastguard Worker vertices_bo,
2140*61046927SAndroid Build Coastguard Worker &pds_program_data_upload);
2141*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2142*61046927SAndroid Build Coastguard Worker return;
2143*61046927SAndroid Build Coastguard Worker } else {
2144*61046927SAndroid Build Coastguard Worker result = pvr_pds_clear_vertex_shader_program_create_and_upload_data(
2145*61046927SAndroid Build Coastguard Worker &pds_program,
2146*61046927SAndroid Build Coastguard Worker cmd_buffer,
2147*61046927SAndroid Build Coastguard Worker vertices_bo,
2148*61046927SAndroid Build Coastguard Worker &pds_program_data_upload);
2149*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2150*61046927SAndroid Build Coastguard Worker return;
2151*61046927SAndroid Build Coastguard Worker }
2152*61046927SAndroid Build Coastguard Worker
2153*61046927SAndroid Build Coastguard Worker pds_program_upload.data_offset = pds_program_data_upload.data_offset;
2154*61046927SAndroid Build Coastguard Worker pds_program_upload.data_size = pds_program_data_upload.data_size;
2155*61046927SAndroid Build Coastguard Worker
2156*61046927SAndroid Build Coastguard Worker vdm_cs_size_in_dw =
2157*61046927SAndroid Build Coastguard Worker pvr_clear_vdm_state_get_size_in_dw(dev_info,
2158*61046927SAndroid Build Coastguard Worker clear_rect->layerCount);
2159*61046927SAndroid Build Coastguard Worker
2160*61046927SAndroid Build Coastguard Worker pvr_csb_set_relocation_mark(&sub_cmd->control_stream);
2161*61046927SAndroid Build Coastguard Worker
2162*61046927SAndroid Build Coastguard Worker vdm_cs_buffer =
2163*61046927SAndroid Build Coastguard Worker pvr_csb_alloc_dwords(&sub_cmd->control_stream, vdm_cs_size_in_dw);
2164*61046927SAndroid Build Coastguard Worker if (!vdm_cs_buffer) {
2165*61046927SAndroid Build Coastguard Worker pvr_cmd_buffer_set_error_unwarned(cmd_buffer,
2166*61046927SAndroid Build Coastguard Worker sub_cmd->control_stream.status);
2167*61046927SAndroid Build Coastguard Worker return;
2168*61046927SAndroid Build Coastguard Worker }
2169*61046927SAndroid Build Coastguard Worker
2170*61046927SAndroid Build Coastguard Worker pvr_pack_clear_vdm_state(dev_info,
2171*61046927SAndroid Build Coastguard Worker &pds_program_upload,
2172*61046927SAndroid Build Coastguard Worker pds_program.temps_used,
2173*61046927SAndroid Build Coastguard Worker 4,
2174*61046927SAndroid Build Coastguard Worker vs_output_size_in_bytes,
2175*61046927SAndroid Build Coastguard Worker clear_rect->layerCount,
2176*61046927SAndroid Build Coastguard Worker vdm_cs_buffer);
2177*61046927SAndroid Build Coastguard Worker
2178*61046927SAndroid Build Coastguard Worker pvr_csb_clear_relocation_mark(&sub_cmd->control_stream);
2179*61046927SAndroid Build Coastguard Worker }
2180*61046927SAndroid Build Coastguard Worker }
2181*61046927SAndroid Build Coastguard Worker }
2182*61046927SAndroid Build Coastguard Worker
pvr_clear_attachments_render_init(struct pvr_cmd_buffer * cmd_buffer,const VkClearAttachment * attachment,const VkClearRect * rect)2183*61046927SAndroid Build Coastguard Worker void pvr_clear_attachments_render_init(struct pvr_cmd_buffer *cmd_buffer,
2184*61046927SAndroid Build Coastguard Worker const VkClearAttachment *attachment,
2185*61046927SAndroid Build Coastguard Worker const VkClearRect *rect)
2186*61046927SAndroid Build Coastguard Worker {
2187*61046927SAndroid Build Coastguard Worker pvr_clear_attachments(cmd_buffer, 1, attachment, 1, rect, true);
2188*61046927SAndroid Build Coastguard Worker }
2189*61046927SAndroid Build Coastguard Worker
pvr_CmdClearAttachments(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)2190*61046927SAndroid Build Coastguard Worker void pvr_CmdClearAttachments(VkCommandBuffer commandBuffer,
2191*61046927SAndroid Build Coastguard Worker uint32_t attachmentCount,
2192*61046927SAndroid Build Coastguard Worker const VkClearAttachment *pAttachments,
2193*61046927SAndroid Build Coastguard Worker uint32_t rectCount,
2194*61046927SAndroid Build Coastguard Worker const VkClearRect *pRects)
2195*61046927SAndroid Build Coastguard Worker {
2196*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
2197*61046927SAndroid Build Coastguard Worker struct pvr_cmd_buffer_state *state = &cmd_buffer->state;
2198*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_gfx *sub_cmd = &state->current_sub_cmd->gfx;
2199*61046927SAndroid Build Coastguard Worker
2200*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
2201*61046927SAndroid Build Coastguard Worker assert(state->current_sub_cmd->type == PVR_SUB_CMD_TYPE_GRAPHICS);
2202*61046927SAndroid Build Coastguard Worker
2203*61046927SAndroid Build Coastguard Worker /* TODO: There are some optimizations that can be made here:
2204*61046927SAndroid Build Coastguard Worker * - For a full screen clear, update the clear values for the corresponding
2205*61046927SAndroid Build Coastguard Worker * attachment index.
2206*61046927SAndroid Build Coastguard Worker * - For a full screen color attachment clear, add its index to a load op
2207*61046927SAndroid Build Coastguard Worker * override to add it to the background shader. This will elide any load
2208*61046927SAndroid Build Coastguard Worker * op loads currently in the background shader as well as the usual
2209*61046927SAndroid Build Coastguard Worker * frag kick for geometry clear.
2210*61046927SAndroid Build Coastguard Worker */
2211*61046927SAndroid Build Coastguard Worker
2212*61046927SAndroid Build Coastguard Worker /* If we have any depth/stencil clears, update the sub command depth/stencil
2213*61046927SAndroid Build Coastguard Worker * modification and usage flags.
2214*61046927SAndroid Build Coastguard Worker */
2215*61046927SAndroid Build Coastguard Worker if (state->depth_format != VK_FORMAT_UNDEFINED) {
2216*61046927SAndroid Build Coastguard Worker uint32_t full_screen_clear_count;
2217*61046927SAndroid Build Coastguard Worker bool has_stencil_clear = false;
2218*61046927SAndroid Build Coastguard Worker bool has_depth_clear = false;
2219*61046927SAndroid Build Coastguard Worker
2220*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < attachmentCount; i++) {
2221*61046927SAndroid Build Coastguard Worker const VkImageAspectFlags aspect_mask = pAttachments[i].aspectMask;
2222*61046927SAndroid Build Coastguard Worker
2223*61046927SAndroid Build Coastguard Worker if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
2224*61046927SAndroid Build Coastguard Worker has_stencil_clear = true;
2225*61046927SAndroid Build Coastguard Worker
2226*61046927SAndroid Build Coastguard Worker if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
2227*61046927SAndroid Build Coastguard Worker has_depth_clear = true;
2228*61046927SAndroid Build Coastguard Worker
2229*61046927SAndroid Build Coastguard Worker if (has_stencil_clear && has_depth_clear)
2230*61046927SAndroid Build Coastguard Worker break;
2231*61046927SAndroid Build Coastguard Worker }
2232*61046927SAndroid Build Coastguard Worker
2233*61046927SAndroid Build Coastguard Worker sub_cmd->modifies_stencil |= has_stencil_clear;
2234*61046927SAndroid Build Coastguard Worker sub_cmd->modifies_depth |= has_depth_clear;
2235*61046927SAndroid Build Coastguard Worker
2236*61046927SAndroid Build Coastguard Worker /* We only care about clears that have a baseArrayLayer of 0 as any
2237*61046927SAndroid Build Coastguard Worker * attachment clears we move to the background shader must apply to all of
2238*61046927SAndroid Build Coastguard Worker * the attachment's sub resources.
2239*61046927SAndroid Build Coastguard Worker */
2240*61046927SAndroid Build Coastguard Worker full_screen_clear_count =
2241*61046927SAndroid Build Coastguard Worker pvr_get_max_layers_covering_target(state->render_pass_info.render_area,
2242*61046927SAndroid Build Coastguard Worker 0,
2243*61046927SAndroid Build Coastguard Worker rectCount,
2244*61046927SAndroid Build Coastguard Worker pRects);
2245*61046927SAndroid Build Coastguard Worker
2246*61046927SAndroid Build Coastguard Worker if (full_screen_clear_count > 0) {
2247*61046927SAndroid Build Coastguard Worker if (has_stencil_clear &&
2248*61046927SAndroid Build Coastguard Worker sub_cmd->stencil_usage == PVR_DEPTH_STENCIL_USAGE_UNDEFINED) {
2249*61046927SAndroid Build Coastguard Worker sub_cmd->stencil_usage = PVR_DEPTH_STENCIL_USAGE_NEVER;
2250*61046927SAndroid Build Coastguard Worker }
2251*61046927SAndroid Build Coastguard Worker
2252*61046927SAndroid Build Coastguard Worker if (has_depth_clear &&
2253*61046927SAndroid Build Coastguard Worker sub_cmd->depth_usage == PVR_DEPTH_STENCIL_USAGE_UNDEFINED) {
2254*61046927SAndroid Build Coastguard Worker sub_cmd->depth_usage = PVR_DEPTH_STENCIL_USAGE_NEVER;
2255*61046927SAndroid Build Coastguard Worker }
2256*61046927SAndroid Build Coastguard Worker }
2257*61046927SAndroid Build Coastguard Worker }
2258*61046927SAndroid Build Coastguard Worker
2259*61046927SAndroid Build Coastguard Worker pvr_clear_attachments(cmd_buffer,
2260*61046927SAndroid Build Coastguard Worker attachmentCount,
2261*61046927SAndroid Build Coastguard Worker pAttachments,
2262*61046927SAndroid Build Coastguard Worker rectCount,
2263*61046927SAndroid Build Coastguard Worker pRects,
2264*61046927SAndroid Build Coastguard Worker false);
2265*61046927SAndroid Build Coastguard Worker }
2266*61046927SAndroid Build Coastguard Worker
pvr_CmdResolveImage2(VkCommandBuffer commandBuffer,const VkResolveImageInfo2 * pResolveImageInfo)2267*61046927SAndroid Build Coastguard Worker void pvr_CmdResolveImage2(VkCommandBuffer commandBuffer,
2268*61046927SAndroid Build Coastguard Worker const VkResolveImageInfo2 *pResolveImageInfo)
2269*61046927SAndroid Build Coastguard Worker {
2270*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, src, pResolveImageInfo->srcImage);
2271*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_image, dst, pResolveImageInfo->dstImage);
2272*61046927SAndroid Build Coastguard Worker PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
2273*61046927SAndroid Build Coastguard Worker
2274*61046927SAndroid Build Coastguard Worker PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
2275*61046927SAndroid Build Coastguard Worker
2276*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < pResolveImageInfo->regionCount; i++) {
2277*61046927SAndroid Build Coastguard Worker VkImageCopy2 region = {
2278*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
2279*61046927SAndroid Build Coastguard Worker .srcSubresource = pResolveImageInfo->pRegions[i].srcSubresource,
2280*61046927SAndroid Build Coastguard Worker .srcOffset = pResolveImageInfo->pRegions[i].srcOffset,
2281*61046927SAndroid Build Coastguard Worker .dstSubresource = pResolveImageInfo->pRegions[i].dstSubresource,
2282*61046927SAndroid Build Coastguard Worker .dstOffset = pResolveImageInfo->pRegions[i].dstOffset,
2283*61046927SAndroid Build Coastguard Worker .extent = pResolveImageInfo->pRegions[i].extent,
2284*61046927SAndroid Build Coastguard Worker };
2285*61046927SAndroid Build Coastguard Worker
2286*61046927SAndroid Build Coastguard Worker VkResult result =
2287*61046927SAndroid Build Coastguard Worker pvr_copy_or_resolve_color_image_region(cmd_buffer, src, dst, ®ion);
2288*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2289*61046927SAndroid Build Coastguard Worker return;
2290*61046927SAndroid Build Coastguard Worker }
2291*61046927SAndroid Build Coastguard Worker }
2292