5f5fe44c6764cce907640fa6da9a59eccbaa05b2
[mesa.git] / src / freedreno / vulkan / tu_meta_clear.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "tu_private.h"
25 #include "tu_blit.h"
26 #include "tu_cs.h"
27
28 static void
29 clear_image(struct tu_cmd_buffer *cmdbuf,
30 struct tu_image *image,
31 uint32_t clear_value[4],
32 const VkImageSubresourceRange *range)
33 {
34 uint32_t level_count = tu_get_levelCount(image, range);
35 uint32_t layer_count = tu_get_layerCount(image, range);
36
37 if (image->type == VK_IMAGE_TYPE_3D) {
38 assert(layer_count == 1);
39 assert(range->baseArrayLayer == 0);
40 }
41
42 for (unsigned j = 0; j < level_count; j++) {
43 if (image->type == VK_IMAGE_TYPE_3D)
44 layer_count = u_minify(image->extent.depth, range->baseMipLevel + j);
45
46 tu_blit(cmdbuf, &(struct tu_blit) {
47 .dst = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
48 .src = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
49 .layers = layer_count,
50 .clear_value = {clear_value[0], clear_value[1], clear_value[2], clear_value[3]},
51 .type = TU_BLIT_CLEAR,
52 });
53 }
54 }
55
56 void
57 tu_CmdClearColorImage(VkCommandBuffer commandBuffer,
58 VkImage image_h,
59 VkImageLayout imageLayout,
60 const VkClearColorValue *pColor,
61 uint32_t rangeCount,
62 const VkImageSubresourceRange *pRanges)
63 {
64 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
65 TU_FROM_HANDLE(tu_image, image, image_h);
66 uint32_t clear_value[4] = {};
67
68 tu_2d_clear_color(pColor, image->vk_format, clear_value);
69
70 tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
71
72 for (unsigned i = 0; i < rangeCount; i++)
73 clear_image(cmdbuf, image, clear_value, pRanges + i);
74 }
75
76 void
77 tu_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
78 VkImage image_h,
79 VkImageLayout imageLayout,
80 const VkClearDepthStencilValue *pDepthStencil,
81 uint32_t rangeCount,
82 const VkImageSubresourceRange *pRanges)
83 {
84 TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
85 TU_FROM_HANDLE(tu_image, image, image_h);
86 uint32_t clear_value[4] = {};
87
88 tu_2d_clear_zs(pDepthStencil, image->vk_format, clear_value);
89
90 tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
91
92 for (unsigned i = 0; i < rangeCount; i++)
93 clear_image(cmdbuf, image, clear_value, pRanges + i);
94 }
95
96 void
97 tu_CmdClearAttachments(VkCommandBuffer commandBuffer,
98 uint32_t attachmentCount,
99 const VkClearAttachment *pAttachments,
100 uint32_t rectCount,
101 const VkClearRect *pRects)
102 {
103 TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
104 const struct tu_subpass *subpass = cmd->state.subpass;
105 struct tu_cs *cs = &cmd->draw_cs;
106
107 VkResult result = tu_cs_reserve_space(cmd->device, cs,
108 rectCount * (3 + 15 * attachmentCount));
109 if (result != VK_SUCCESS) {
110 cmd->record_result = result;
111 return;
112 }
113
114 /* TODO: deal with layered rendering (when layered rendering is implemented)
115 * TODO: disable bypass rendering for subpass (when bypass is implemented)
116 */
117
118 for (unsigned i = 0; i < rectCount; i++) {
119 unsigned x1 = pRects[i].rect.offset.x;
120 unsigned y1 = pRects[i].rect.offset.y;
121 unsigned x2 = x1 + pRects[i].rect.extent.width - 1;
122 unsigned y2 = y1 + pRects[i].rect.extent.height - 1;
123
124 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
125 tu_cs_emit(cs, A6XX_RB_BLIT_SCISSOR_TL_X(x1) | A6XX_RB_BLIT_SCISSOR_TL_Y(y1));
126 tu_cs_emit(cs, A6XX_RB_BLIT_SCISSOR_BR_X(x2) | A6XX_RB_BLIT_SCISSOR_BR_Y(y2));
127
128 for (unsigned j = 0; j < attachmentCount; j++) {
129 uint32_t a;
130 unsigned clear_mask = 0;
131 if (pAttachments[j].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
132 clear_mask = 0xf;
133 a = subpass->color_attachments[pAttachments[j].colorAttachment].attachment;
134 } else {
135 a = subpass->depth_stencil_attachment.attachment;
136 if (pAttachments[j].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
137 clear_mask |= 1;
138 if (pAttachments[j].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
139 clear_mask |= 2;
140 }
141
142 if (a == VK_ATTACHMENT_UNUSED)
143 continue;
144
145 VkFormat fmt = cmd->state.pass->attachments[a].format;
146 const struct tu_native_format *format = tu6_get_native_format(fmt);
147 assert(format && format->rb >= 0);
148
149 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1);
150 tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb));
151
152 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1);
153 tu_cs_emit(cs, A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(clear_mask));
154
155 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
156 tu_cs_emit(cs, cmd->state.tiling_config.gmem_offsets[a]);
157
158 tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_88D0, 1);
159 tu_cs_emit(cs, 0);
160
161 uint32_t clear_vals[4] = { 0 };
162 tu_pack_clear_value(&pAttachments[j].clearValue, fmt, clear_vals);
163
164 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 4);
165 tu_cs_emit(cs, clear_vals[0]);
166 tu_cs_emit(cs, clear_vals[1]);
167 tu_cs_emit(cs, clear_vals[2]);
168 tu_cs_emit(cs, clear_vals[3]);
169
170 tu6_emit_event_write(cmd, cs, BLIT, false);
171 }
172 }
173 }