1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * based on anv driver:
5bf215546Sopenharmony_ci * Copyright © 2016 Intel Corporation
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
16bf215546Sopenharmony_ci * Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24bf215546Sopenharmony_ci * IN THE SOFTWARE.
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include "nir/nir_builder.h"
28bf215546Sopenharmony_ci#include "radv_meta.h"
29bf215546Sopenharmony_ci#include "vk_format.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_cienum blit2d_src_type {
32bf215546Sopenharmony_ci   BLIT2D_SRC_TYPE_IMAGE,
33bf215546Sopenharmony_ci   BLIT2D_SRC_TYPE_IMAGE_3D,
34bf215546Sopenharmony_ci   BLIT2D_SRC_TYPE_BUFFER,
35bf215546Sopenharmony_ci   BLIT2D_NUM_SRC_TYPES,
36bf215546Sopenharmony_ci};
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistatic VkResult blit2d_init_color_pipeline(struct radv_device *device,
39bf215546Sopenharmony_ci                                           enum blit2d_src_type src_type, VkFormat format,
40bf215546Sopenharmony_ci                                           uint32_t log2_samples);
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_cistatic VkResult blit2d_init_depth_only_pipeline(struct radv_device *device,
43bf215546Sopenharmony_ci                                                enum blit2d_src_type src_type,
44bf215546Sopenharmony_ci                                                uint32_t log2_samples);
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_cistatic VkResult blit2d_init_stencil_only_pipeline(struct radv_device *device,
47bf215546Sopenharmony_ci                                                  enum blit2d_src_type src_type,
48bf215546Sopenharmony_ci                                                  uint32_t log2_samples);
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cistatic void
51bf215546Sopenharmony_cicreate_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf,
52bf215546Sopenharmony_ci             struct radv_image_view *iview, VkFormat depth_format, VkImageAspectFlagBits aspects)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   VkFormat format;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   if (depth_format)
57bf215546Sopenharmony_ci      format = depth_format;
58bf215546Sopenharmony_ci   else
59bf215546Sopenharmony_ci      format = surf->format;
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   radv_image_view_init(iview, cmd_buffer->device,
62bf215546Sopenharmony_ci                        &(VkImageViewCreateInfo){
63bf215546Sopenharmony_ci                           .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
64bf215546Sopenharmony_ci                           .image = radv_image_to_handle(surf->image),
65bf215546Sopenharmony_ci                           .viewType = radv_meta_get_view_type(surf->image),
66bf215546Sopenharmony_ci                           .format = format,
67bf215546Sopenharmony_ci                           .subresourceRange = {.aspectMask = aspects,
68bf215546Sopenharmony_ci                                                .baseMipLevel = surf->level,
69bf215546Sopenharmony_ci                                                .levelCount = 1,
70bf215546Sopenharmony_ci                                                .baseArrayLayer = surf->layer,
71bf215546Sopenharmony_ci                                                .layerCount = 1},
72bf215546Sopenharmony_ci                        },
73bf215546Sopenharmony_ci                        0, &(struct radv_image_view_extra_create_info){
74bf215546Sopenharmony_ci                           .disable_dcc_mrt = surf->disable_compression
75bf215546Sopenharmony_ci                        });
76bf215546Sopenharmony_ci}
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistatic void
79bf215546Sopenharmony_cicreate_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src,
80bf215546Sopenharmony_ci             struct radv_buffer_view *bview, VkFormat depth_format)
81bf215546Sopenharmony_ci{
82bf215546Sopenharmony_ci   VkFormat format;
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   if (depth_format)
85bf215546Sopenharmony_ci      format = depth_format;
86bf215546Sopenharmony_ci   else
87bf215546Sopenharmony_ci      format = src->format;
88bf215546Sopenharmony_ci   radv_buffer_view_init(bview, cmd_buffer->device,
89bf215546Sopenharmony_ci                         &(VkBufferViewCreateInfo){
90bf215546Sopenharmony_ci                            .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
91bf215546Sopenharmony_ci                            .flags = 0,
92bf215546Sopenharmony_ci                            .buffer = radv_buffer_to_handle(src->buffer),
93bf215546Sopenharmony_ci                            .format = format,
94bf215546Sopenharmony_ci                            .offset = src->offset,
95bf215546Sopenharmony_ci                            .range = VK_WHOLE_SIZE,
96bf215546Sopenharmony_ci                         });
97bf215546Sopenharmony_ci}
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_cistruct blit2d_src_temps {
100bf215546Sopenharmony_ci   struct radv_image_view iview;
101bf215546Sopenharmony_ci   struct radv_buffer_view bview;
102bf215546Sopenharmony_ci};
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_cistatic void
105bf215546Sopenharmony_ciblit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
106bf215546Sopenharmony_ci                struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp,
107bf215546Sopenharmony_ci                enum blit2d_src_type src_type, VkFormat depth_format, VkImageAspectFlagBits aspects,
108bf215546Sopenharmony_ci                uint32_t log2_samples)
109bf215546Sopenharmony_ci{
110bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   if (src_type == BLIT2D_SRC_TYPE_BUFFER) {
113bf215546Sopenharmony_ci      create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format);
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci      radv_meta_push_descriptor_set(
116bf215546Sopenharmony_ci         cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
117bf215546Sopenharmony_ci         device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
118bf215546Sopenharmony_ci         1,                                                              /* descriptorWriteCount */
119bf215546Sopenharmony_ci         (VkWriteDescriptorSet[]){
120bf215546Sopenharmony_ci            {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
121bf215546Sopenharmony_ci             .dstBinding = 0,
122bf215546Sopenharmony_ci             .dstArrayElement = 0,
123bf215546Sopenharmony_ci             .descriptorCount = 1,
124bf215546Sopenharmony_ci             .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
125bf215546Sopenharmony_ci             .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(&tmp->bview)}}});
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
128bf215546Sopenharmony_ci                            device->meta_state.blit2d[log2_samples].p_layouts[src_type],
129bf215546Sopenharmony_ci                            VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch);
130bf215546Sopenharmony_ci   } else {
131bf215546Sopenharmony_ci      create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects);
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci      if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
134bf215546Sopenharmony_ci         radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
135bf215546Sopenharmony_ci                               device->meta_state.blit2d[log2_samples].p_layouts[src_type],
136bf215546Sopenharmony_ci                               VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_img->layer);
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci      radv_meta_push_descriptor_set(
139bf215546Sopenharmony_ci         cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
140bf215546Sopenharmony_ci         device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
141bf215546Sopenharmony_ci         1,                                                              /* descriptorWriteCount */
142bf215546Sopenharmony_ci         (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
143bf215546Sopenharmony_ci                                   .dstBinding = 0,
144bf215546Sopenharmony_ci                                   .dstArrayElement = 0,
145bf215546Sopenharmony_ci                                   .descriptorCount = 1,
146bf215546Sopenharmony_ci                                   .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
147bf215546Sopenharmony_ci                                   .pImageInfo = (VkDescriptorImageInfo[]){
148bf215546Sopenharmony_ci                                      {
149bf215546Sopenharmony_ci                                         .sampler = VK_NULL_HANDLE,
150bf215546Sopenharmony_ci                                         .imageView = radv_image_view_to_handle(&tmp->iview),
151bf215546Sopenharmony_ci                                         .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
152bf215546Sopenharmony_ci                                      },
153bf215546Sopenharmony_ci                                   }}});
154bf215546Sopenharmony_ci   }
155bf215546Sopenharmony_ci}
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_cistruct blit2d_dst_temps {
158bf215546Sopenharmony_ci   VkImage image;
159bf215546Sopenharmony_ci   struct radv_image_view iview;
160bf215546Sopenharmony_ci   VkFramebuffer fb;
161bf215546Sopenharmony_ci};
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_cistatic void
164bf215546Sopenharmony_cibind_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type, unsigned fs_key,
165bf215546Sopenharmony_ci              uint32_t log2_samples)
166bf215546Sopenharmony_ci{
167bf215546Sopenharmony_ci   VkPipeline pipeline =
168bf215546Sopenharmony_ci      cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key];
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
171bf215546Sopenharmony_ci                        pipeline);
172bf215546Sopenharmony_ci}
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_cistatic void
175bf215546Sopenharmony_cibind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
176bf215546Sopenharmony_ci                    uint32_t log2_samples)
177bf215546Sopenharmony_ci{
178bf215546Sopenharmony_ci   VkPipeline pipeline =
179bf215546Sopenharmony_ci      cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type];
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
182bf215546Sopenharmony_ci                        pipeline);
183bf215546Sopenharmony_ci}
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_cistatic void
186bf215546Sopenharmony_cibind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
187bf215546Sopenharmony_ci                      uint32_t log2_samples)
188bf215546Sopenharmony_ci{
189bf215546Sopenharmony_ci   VkPipeline pipeline =
190bf215546Sopenharmony_ci      cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type];
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
193bf215546Sopenharmony_ci                        pipeline);
194bf215546Sopenharmony_ci}
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_cistatic void
197bf215546Sopenharmony_ciradv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer,
198bf215546Sopenharmony_ci                            struct radv_meta_blit2d_surf *src_img,
199bf215546Sopenharmony_ci                            struct radv_meta_blit2d_buffer *src_buf,
200bf215546Sopenharmony_ci                            struct radv_meta_blit2d_surf *dst, unsigned num_rects,
201bf215546Sopenharmony_ci                            struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type,
202bf215546Sopenharmony_ci                            uint32_t log2_samples)
203bf215546Sopenharmony_ci{
204bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ci   for (unsigned r = 0; r < num_rects; ++r) {
207bf215546Sopenharmony_ci      u_foreach_bit(i, dst->aspect_mask)
208bf215546Sopenharmony_ci      {
209bf215546Sopenharmony_ci         unsigned aspect_mask = 1u << i;
210bf215546Sopenharmony_ci         unsigned src_aspect_mask = aspect_mask;
211bf215546Sopenharmony_ci         VkFormat depth_format = 0;
212bf215546Sopenharmony_ci         if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
213bf215546Sopenharmony_ci            depth_format = vk_format_stencil_only(dst->image->vk.format);
214bf215546Sopenharmony_ci         else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
215bf215546Sopenharmony_ci            depth_format = vk_format_depth_only(dst->image->vk.format);
216bf215546Sopenharmony_ci         else if (src_img)
217bf215546Sopenharmony_ci            src_aspect_mask = src_img->aspect_mask;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci         struct blit2d_src_temps src_temps;
220bf215546Sopenharmony_ci         blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format,
221bf215546Sopenharmony_ci                         src_aspect_mask, log2_samples);
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci         struct blit2d_dst_temps dst_temps;
224bf215546Sopenharmony_ci         create_iview(cmd_buffer, dst, &dst_temps.iview, depth_format, aspect_mask);
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci         float vertex_push_constants[4] = {
227bf215546Sopenharmony_ci            rects[r].src_x,
228bf215546Sopenharmony_ci            rects[r].src_y,
229bf215546Sopenharmony_ci            rects[r].src_x + rects[r].width,
230bf215546Sopenharmony_ci            rects[r].src_y + rects[r].height,
231bf215546Sopenharmony_ci         };
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci         radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
234bf215546Sopenharmony_ci                               device->meta_state.blit2d[log2_samples].p_layouts[src_type],
235bf215546Sopenharmony_ci                               VK_SHADER_STAGE_VERTEX_BIT, 0, 16, vertex_push_constants);
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci         if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT ||
238bf215546Sopenharmony_ci             aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
239bf215546Sopenharmony_ci             aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT ||
240bf215546Sopenharmony_ci             aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
241bf215546Sopenharmony_ci            unsigned fs_key = radv_format_meta_fs_key(device, dst_temps.iview.vk.format);
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci            if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] ==
244bf215546Sopenharmony_ci                VK_NULL_HANDLE) {
245bf215546Sopenharmony_ci               VkResult ret = blit2d_init_color_pipeline(
246bf215546Sopenharmony_ci                  device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples);
247bf215546Sopenharmony_ci               if (ret != VK_SUCCESS) {
248bf215546Sopenharmony_ci                  cmd_buffer->record_result = ret;
249bf215546Sopenharmony_ci                  goto fail_pipeline;
250bf215546Sopenharmony_ci               }
251bf215546Sopenharmony_ci            }
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci            const VkRenderingAttachmentInfo color_att_info = {
254bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
255bf215546Sopenharmony_ci               .imageView = radv_image_view_to_handle(&dst_temps.iview),
256bf215546Sopenharmony_ci               .imageLayout = dst->current_layout,
257bf215546Sopenharmony_ci               .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
258bf215546Sopenharmony_ci               .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
259bf215546Sopenharmony_ci            };
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci            const VkRenderingInfo rendering_info = {
262bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
263bf215546Sopenharmony_ci               .renderArea = {
264bf215546Sopenharmony_ci                  .offset = { rects[r].dst_x, rects[r].dst_y },
265bf215546Sopenharmony_ci                  .extent = { rects[r].width, rects[r].height },
266bf215546Sopenharmony_ci               },
267bf215546Sopenharmony_ci               .layerCount = 1,
268bf215546Sopenharmony_ci               .colorAttachmentCount = 1,
269bf215546Sopenharmony_ci               .pColorAttachments = &color_att_info,
270bf215546Sopenharmony_ci            };
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci            radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci            bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples);
275bf215546Sopenharmony_ci         } else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
276bf215546Sopenharmony_ci            if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] ==
277bf215546Sopenharmony_ci                VK_NULL_HANDLE) {
278bf215546Sopenharmony_ci               VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples);
279bf215546Sopenharmony_ci               if (ret != VK_SUCCESS) {
280bf215546Sopenharmony_ci                  cmd_buffer->record_result = ret;
281bf215546Sopenharmony_ci                  goto fail_pipeline;
282bf215546Sopenharmony_ci               }
283bf215546Sopenharmony_ci            }
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci            const VkRenderingAttachmentInfo depth_att_info = {
286bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
287bf215546Sopenharmony_ci               .imageView = radv_image_view_to_handle(&dst_temps.iview),
288bf215546Sopenharmony_ci               .imageLayout = dst->current_layout,
289bf215546Sopenharmony_ci               .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
290bf215546Sopenharmony_ci               .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
291bf215546Sopenharmony_ci            };
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci            const VkRenderingInfo rendering_info = {
294bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
295bf215546Sopenharmony_ci               .renderArea = {
296bf215546Sopenharmony_ci                  .offset = { rects[r].dst_x, rects[r].dst_y },
297bf215546Sopenharmony_ci                  .extent = { rects[r].width, rects[r].height },
298bf215546Sopenharmony_ci               },
299bf215546Sopenharmony_ci               .layerCount = 1,
300bf215546Sopenharmony_ci               .pDepthAttachment = &depth_att_info,
301bf215546Sopenharmony_ci               .pStencilAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ?
302bf215546Sopenharmony_ci                                     &depth_att_info : NULL,
303bf215546Sopenharmony_ci            };
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci            radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci            bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci         } else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
310bf215546Sopenharmony_ci            if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] ==
311bf215546Sopenharmony_ci                VK_NULL_HANDLE) {
312bf215546Sopenharmony_ci               VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples);
313bf215546Sopenharmony_ci               if (ret != VK_SUCCESS) {
314bf215546Sopenharmony_ci                  cmd_buffer->record_result = ret;
315bf215546Sopenharmony_ci                  goto fail_pipeline;
316bf215546Sopenharmony_ci               }
317bf215546Sopenharmony_ci            }
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci            const VkRenderingAttachmentInfo stencil_att_info = {
320bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
321bf215546Sopenharmony_ci               .imageView = radv_image_view_to_handle(&dst_temps.iview),
322bf215546Sopenharmony_ci               .imageLayout = dst->current_layout,
323bf215546Sopenharmony_ci               .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
324bf215546Sopenharmony_ci               .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
325bf215546Sopenharmony_ci            };
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci            const VkRenderingInfo rendering_info = {
328bf215546Sopenharmony_ci               .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
329bf215546Sopenharmony_ci               .renderArea = {
330bf215546Sopenharmony_ci                  .offset = { rects[r].dst_x, rects[r].dst_y },
331bf215546Sopenharmony_ci                  .extent = { rects[r].width, rects[r].height },
332bf215546Sopenharmony_ci               },
333bf215546Sopenharmony_ci               .layerCount = 1,
334bf215546Sopenharmony_ci               .pDepthAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ?
335bf215546Sopenharmony_ci                                   &stencil_att_info : NULL,
336bf215546Sopenharmony_ci               .pStencilAttachment = &stencil_att_info,
337bf215546Sopenharmony_ci            };
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci            radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci            bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
342bf215546Sopenharmony_ci         } else
343bf215546Sopenharmony_ci            unreachable("Processing blit2d with multiple aspects.");
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci         radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
346bf215546Sopenharmony_ci                             &(VkViewport){.x = rects[r].dst_x,
347bf215546Sopenharmony_ci                                           .y = rects[r].dst_y,
348bf215546Sopenharmony_ci                                           .width = rects[r].width,
349bf215546Sopenharmony_ci                                           .height = rects[r].height,
350bf215546Sopenharmony_ci                                           .minDepth = 0.0f,
351bf215546Sopenharmony_ci                                           .maxDepth = 1.0f});
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci         radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
354bf215546Sopenharmony_ci                            &(VkRect2D){
355bf215546Sopenharmony_ci                               .offset = (VkOffset2D){rects[r].dst_x, rects[r].dst_y},
356bf215546Sopenharmony_ci                               .extent = (VkExtent2D){rects[r].width, rects[r].height},
357bf215546Sopenharmony_ci                            });
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci         radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci         radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci      fail_pipeline:
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci         if (src_type == BLIT2D_SRC_TYPE_BUFFER)
366bf215546Sopenharmony_ci            radv_buffer_view_finish(&src_temps.bview);
367bf215546Sopenharmony_ci         else
368bf215546Sopenharmony_ci            radv_image_view_finish(&src_temps.iview);
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci         radv_image_view_finish(&dst_temps.iview);
371bf215546Sopenharmony_ci      }
372bf215546Sopenharmony_ci   }
373bf215546Sopenharmony_ci}
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_civoid
376bf215546Sopenharmony_ciradv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
377bf215546Sopenharmony_ci                 struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
378bf215546Sopenharmony_ci                 unsigned num_rects, struct radv_meta_blit2d_rect *rects)
379bf215546Sopenharmony_ci{
380bf215546Sopenharmony_ci   bool use_3d = (src_img && src_img->image->vk.image_type == VK_IMAGE_TYPE_3D);
381bf215546Sopenharmony_ci   enum blit2d_src_type src_type = src_buf  ? BLIT2D_SRC_TYPE_BUFFER
382bf215546Sopenharmony_ci                                   : use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D
383bf215546Sopenharmony_ci                                            : BLIT2D_SRC_TYPE_IMAGE;
384bf215546Sopenharmony_ci   radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, num_rects, rects, src_type,
385bf215546Sopenharmony_ci                               src_img ? util_logbase2(src_img->image->info.samples) : 0);
386bf215546Sopenharmony_ci}
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_cistatic nir_shader *
389bf215546Sopenharmony_cibuild_nir_vertex_shader(struct radv_device *device)
390bf215546Sopenharmony_ci{
391bf215546Sopenharmony_ci   const struct glsl_type *vec4 = glsl_vec4_type();
392bf215546Sopenharmony_ci   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
393bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(device, MESA_SHADER_VERTEX, "meta_blit2d_vs");
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci   nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
396bf215546Sopenharmony_ci   pos_out->data.location = VARYING_SLOT_POS;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos");
399bf215546Sopenharmony_ci   tex_pos_out->data.location = VARYING_SLOT_VAR0;
400bf215546Sopenharmony_ci   tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   nir_ssa_def *outvec = nir_gen_rect_vertices(&b, NULL, NULL);
403bf215546Sopenharmony_ci   nir_store_var(&b, pos_out, outvec, 0xf);
404bf215546Sopenharmony_ci
405bf215546Sopenharmony_ci   nir_ssa_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
406bf215546Sopenharmony_ci   nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(&b);
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci   /* vertex 0 - src_x, src_y */
409bf215546Sopenharmony_ci   /* vertex 1 - src_x, src_y+h */
410bf215546Sopenharmony_ci   /* vertex 2 - src_x+w, src_y */
411bf215546Sopenharmony_ci   /* so channel 0 is vertex_id != 2 ? src_x : src_x + w
412bf215546Sopenharmony_ci      channel 1 is vertex id != 1 ? src_y : src_y + w */
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci   nir_ssa_def *c0cmp = nir_ine_imm(&b, vertex_id, 2);
415bf215546Sopenharmony_ci   nir_ssa_def *c1cmp = nir_ine_imm(&b, vertex_id, 1);
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   nir_ssa_def *comp[2];
418bf215546Sopenharmony_ci   comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
421bf215546Sopenharmony_ci   nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 2);
422bf215546Sopenharmony_ci   nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3);
423bf215546Sopenharmony_ci   return b.shader;
424bf215546Sopenharmony_ci}
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_citypedef nir_ssa_def *(*texel_fetch_build_func)(struct nir_builder *, struct radv_device *,
427bf215546Sopenharmony_ci                                               nir_ssa_def *, bool, bool);
428bf215546Sopenharmony_ci
429bf215546Sopenharmony_cistatic nir_ssa_def *
430bf215546Sopenharmony_cibuild_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
431bf215546Sopenharmony_ci                      bool is_3d, bool is_multisampled)
432bf215546Sopenharmony_ci{
433bf215546Sopenharmony_ci   enum glsl_sampler_dim dim = is_3d             ? GLSL_SAMPLER_DIM_3D
434bf215546Sopenharmony_ci                               : is_multisampled ? GLSL_SAMPLER_DIM_MS
435bf215546Sopenharmony_ci                                                 : GLSL_SAMPLER_DIM_2D;
436bf215546Sopenharmony_ci   const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT);
437bf215546Sopenharmony_ci   nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
438bf215546Sopenharmony_ci   sampler->data.descriptor_set = 0;
439bf215546Sopenharmony_ci   sampler->data.binding = 0;
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci   nir_ssa_def *tex_pos_3d = NULL;
442bf215546Sopenharmony_ci   nir_ssa_def *sample_idx = NULL;
443bf215546Sopenharmony_ci   if (is_3d) {
444bf215546Sopenharmony_ci      nir_ssa_def *layer =
445bf215546Sopenharmony_ci         nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci      nir_ssa_def *chans[3];
448bf215546Sopenharmony_ci      chans[0] = nir_channel(b, tex_pos, 0);
449bf215546Sopenharmony_ci      chans[1] = nir_channel(b, tex_pos, 1);
450bf215546Sopenharmony_ci      chans[2] = layer;
451bf215546Sopenharmony_ci      tex_pos_3d = nir_vec(b, chans, 3);
452bf215546Sopenharmony_ci   }
453bf215546Sopenharmony_ci   if (is_multisampled) {
454bf215546Sopenharmony_ci      sample_idx = nir_load_sample_id(b);
455bf215546Sopenharmony_ci   }
456bf215546Sopenharmony_ci
457bf215546Sopenharmony_ci   nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b->shader, is_multisampled ? 4 : 3);
460bf215546Sopenharmony_ci   tex->sampler_dim = dim;
461bf215546Sopenharmony_ci   tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
462bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
463bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : tex_pos);
464bf215546Sopenharmony_ci   tex->src[1].src_type = is_multisampled ? nir_tex_src_ms_index : nir_tex_src_lod;
465bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(is_multisampled ? sample_idx : nir_imm_int(b, 0));
466bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
467bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(tex_deref);
468bf215546Sopenharmony_ci   if (is_multisampled) {
469bf215546Sopenharmony_ci      tex->src[3].src_type = nir_tex_src_lod;
470bf215546Sopenharmony_ci      tex->src[3].src = nir_src_for_ssa(nir_imm_int(b, 0));
471bf215546Sopenharmony_ci   }
472bf215546Sopenharmony_ci   tex->dest_type = nir_type_uint32;
473bf215546Sopenharmony_ci   tex->is_array = false;
474bf215546Sopenharmony_ci   tex->coord_components = is_3d ? 3 : 2;
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
477bf215546Sopenharmony_ci   nir_builder_instr_insert(b, &tex->instr);
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci   return &tex->dest.ssa;
480bf215546Sopenharmony_ci}
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_cistatic nir_ssa_def *
483bf215546Sopenharmony_cibuild_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
484bf215546Sopenharmony_ci                       bool is_3d, bool is_multisampled)
485bf215546Sopenharmony_ci{
486bf215546Sopenharmony_ci   const struct glsl_type *sampler_type =
487bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT);
488bf215546Sopenharmony_ci   nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
489bf215546Sopenharmony_ci   sampler->data.descriptor_set = 0;
490bf215546Sopenharmony_ci   sampler->data.binding = 0;
491bf215546Sopenharmony_ci
492bf215546Sopenharmony_ci   nir_ssa_def *width = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci   nir_ssa_def *pos_x = nir_channel(b, tex_pos, 0);
495bf215546Sopenharmony_ci   nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1);
496bf215546Sopenharmony_ci   pos_y = nir_imul(b, pos_y, width);
497bf215546Sopenharmony_ci   pos_x = nir_iadd(b, pos_x, pos_y);
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci   nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2);
502bf215546Sopenharmony_ci   tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
503bf215546Sopenharmony_ci   tex->op = nir_texop_txf;
504bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
505bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(pos_x);
506bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_texture_deref;
507bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(tex_deref);
508bf215546Sopenharmony_ci   tex->dest_type = nir_type_uint32;
509bf215546Sopenharmony_ci   tex->is_array = false;
510bf215546Sopenharmony_ci   tex->coord_components = 1;
511bf215546Sopenharmony_ci
512bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
513bf215546Sopenharmony_ci   nir_builder_instr_insert(b, &tex->instr);
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_ci   return &tex->dest.ssa;
516bf215546Sopenharmony_ci}
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_cistatic const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
519bf215546Sopenharmony_ci   .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
520bf215546Sopenharmony_ci   .vertexBindingDescriptionCount = 0,
521bf215546Sopenharmony_ci   .vertexAttributeDescriptionCount = 0,
522bf215546Sopenharmony_ci};
523bf215546Sopenharmony_ci
524bf215546Sopenharmony_cistatic nir_shader *
525bf215546Sopenharmony_cibuild_nir_copy_fragment_shader(struct radv_device *device, texel_fetch_build_func txf_func,
526bf215546Sopenharmony_ci                               const char *name, bool is_3d, bool is_multisampled)
527bf215546Sopenharmony_ci{
528bf215546Sopenharmony_ci   const struct glsl_type *vec4 = glsl_vec4_type();
529bf215546Sopenharmony_ci   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
530bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
531bf215546Sopenharmony_ci
532bf215546Sopenharmony_ci   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
533bf215546Sopenharmony_ci   tex_pos_in->data.location = VARYING_SLOT_VAR0;
534bf215546Sopenharmony_ci
535bf215546Sopenharmony_ci   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
536bf215546Sopenharmony_ci   color_out->data.location = FRAG_RESULT_DATA0;
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
539bf215546Sopenharmony_ci   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
540bf215546Sopenharmony_ci
541bf215546Sopenharmony_ci   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
542bf215546Sopenharmony_ci   nir_store_var(&b, color_out, color, 0xf);
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ci   b.shader->info.fs.uses_sample_shading = is_multisampled;
545bf215546Sopenharmony_ci
546bf215546Sopenharmony_ci   return b.shader;
547bf215546Sopenharmony_ci}
548bf215546Sopenharmony_ci
549bf215546Sopenharmony_cistatic nir_shader *
550bf215546Sopenharmony_cibuild_nir_copy_fragment_shader_depth(struct radv_device *device, texel_fetch_build_func txf_func,
551bf215546Sopenharmony_ci                                     const char *name, bool is_3d, bool is_multisampled)
552bf215546Sopenharmony_ci{
553bf215546Sopenharmony_ci   const struct glsl_type *vec4 = glsl_vec4_type();
554bf215546Sopenharmony_ci   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
555bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
556bf215546Sopenharmony_ci
557bf215546Sopenharmony_ci   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
558bf215546Sopenharmony_ci   tex_pos_in->data.location = VARYING_SLOT_VAR0;
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_ci   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
561bf215546Sopenharmony_ci   color_out->data.location = FRAG_RESULT_DEPTH;
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_ci   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
564bf215546Sopenharmony_ci   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
565bf215546Sopenharmony_ci
566bf215546Sopenharmony_ci   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
567bf215546Sopenharmony_ci   nir_store_var(&b, color_out, color, 0x1);
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci   b.shader->info.fs.uses_sample_shading = is_multisampled;
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ci   return b.shader;
572bf215546Sopenharmony_ci}
573bf215546Sopenharmony_ci
574bf215546Sopenharmony_cistatic nir_shader *
575bf215546Sopenharmony_cibuild_nir_copy_fragment_shader_stencil(struct radv_device *device, texel_fetch_build_func txf_func,
576bf215546Sopenharmony_ci                                       const char *name, bool is_3d, bool is_multisampled)
577bf215546Sopenharmony_ci{
578bf215546Sopenharmony_ci   const struct glsl_type *vec4 = glsl_vec4_type();
579bf215546Sopenharmony_ci   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
580bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
581bf215546Sopenharmony_ci
582bf215546Sopenharmony_ci   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
583bf215546Sopenharmony_ci   tex_pos_in->data.location = VARYING_SLOT_VAR0;
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
586bf215546Sopenharmony_ci   color_out->data.location = FRAG_RESULT_STENCIL;
587bf215546Sopenharmony_ci
588bf215546Sopenharmony_ci   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
589bf215546Sopenharmony_ci   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
592bf215546Sopenharmony_ci   nir_store_var(&b, color_out, color, 0x1);
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci   b.shader->info.fs.uses_sample_shading = is_multisampled;
595bf215546Sopenharmony_ci
596bf215546Sopenharmony_ci   return b.shader;
597bf215546Sopenharmony_ci}
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_civoid
600bf215546Sopenharmony_ciradv_device_finish_meta_blit2d_state(struct radv_device *device)
601bf215546Sopenharmony_ci{
602bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
603bf215546Sopenharmony_ci
604bf215546Sopenharmony_ci   for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; ++log2_samples) {
605bf215546Sopenharmony_ci      for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
606bf215546Sopenharmony_ci         radv_DestroyPipelineLayout(radv_device_to_handle(device),
607bf215546Sopenharmony_ci                                    state->blit2d[log2_samples].p_layouts[src], &state->alloc);
608bf215546Sopenharmony_ci         device->vk.dispatch_table.DestroyDescriptorSetLayout(
609bf215546Sopenharmony_ci            radv_device_to_handle(device), state->blit2d[log2_samples].ds_layouts[src],
610bf215546Sopenharmony_ci            &state->alloc);
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci         for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
613bf215546Sopenharmony_ci            radv_DestroyPipeline(radv_device_to_handle(device),
614bf215546Sopenharmony_ci                                 state->blit2d[log2_samples].pipelines[src][j], &state->alloc);
615bf215546Sopenharmony_ci         }
616bf215546Sopenharmony_ci
617bf215546Sopenharmony_ci         radv_DestroyPipeline(radv_device_to_handle(device),
618bf215546Sopenharmony_ci                              state->blit2d[log2_samples].depth_only_pipeline[src], &state->alloc);
619bf215546Sopenharmony_ci         radv_DestroyPipeline(radv_device_to_handle(device),
620bf215546Sopenharmony_ci                              state->blit2d[log2_samples].stencil_only_pipeline[src],
621bf215546Sopenharmony_ci                              &state->alloc);
622bf215546Sopenharmony_ci      }
623bf215546Sopenharmony_ci   }
624bf215546Sopenharmony_ci}
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_cistatic VkResult
627bf215546Sopenharmony_ciblit2d_init_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
628bf215546Sopenharmony_ci                           VkFormat format, uint32_t log2_samples)
629bf215546Sopenharmony_ci{
630bf215546Sopenharmony_ci   VkResult result;
631bf215546Sopenharmony_ci   unsigned fs_key = radv_format_meta_fs_key(device, format);
632bf215546Sopenharmony_ci   const char *name;
633bf215546Sopenharmony_ci
634bf215546Sopenharmony_ci   mtx_lock(&device->meta_state.mtx);
635bf215546Sopenharmony_ci   if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) {
636bf215546Sopenharmony_ci      mtx_unlock(&device->meta_state.mtx);
637bf215546Sopenharmony_ci      return VK_SUCCESS;
638bf215546Sopenharmony_ci   }
639bf215546Sopenharmony_ci
640bf215546Sopenharmony_ci   texel_fetch_build_func src_func;
641bf215546Sopenharmony_ci   switch (src_type) {
642bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE:
643bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
644bf215546Sopenharmony_ci      name = "meta_blit2d_image_fs";
645bf215546Sopenharmony_ci      break;
646bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE_3D:
647bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
648bf215546Sopenharmony_ci      name = "meta_blit3d_image_fs";
649bf215546Sopenharmony_ci      break;
650bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_BUFFER:
651bf215546Sopenharmony_ci      src_func = build_nir_buffer_fetch;
652bf215546Sopenharmony_ci      name = "meta_blit2d_buffer_fs";
653bf215546Sopenharmony_ci      break;
654bf215546Sopenharmony_ci   default:
655bf215546Sopenharmony_ci      unreachable("unknown blit src type\n");
656bf215546Sopenharmony_ci      break;
657bf215546Sopenharmony_ci   }
658bf215546Sopenharmony_ci
659bf215546Sopenharmony_ci   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
660bf215546Sopenharmony_ci   nir_shader *fs = build_nir_copy_fragment_shader(
661bf215546Sopenharmony_ci      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
662bf215546Sopenharmony_ci   nir_shader *vs = build_nir_vertex_shader(device);
663bf215546Sopenharmony_ci
664bf215546Sopenharmony_ci   vi_create_info = &normal_vi_create_info;
665bf215546Sopenharmony_ci
666bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
667bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
668bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_VERTEX_BIT,
669bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(vs),
670bf215546Sopenharmony_ci       .pName = "main",
671bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
672bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
673bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
674bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(fs),
675bf215546Sopenharmony_ci       .pName = "main",
676bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
677bf215546Sopenharmony_ci   };
678bf215546Sopenharmony_ci
679bf215546Sopenharmony_ci   const VkPipelineRenderingCreateInfo rendering_create_info = {
680bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
681bf215546Sopenharmony_ci      .colorAttachmentCount = 1,
682bf215546Sopenharmony_ci      .pColorAttachmentFormats = &format,
683bf215546Sopenharmony_ci   };
684bf215546Sopenharmony_ci
685bf215546Sopenharmony_ci   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
686bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
687bf215546Sopenharmony_ci      .pNext = &rendering_create_info,
688bf215546Sopenharmony_ci      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
689bf215546Sopenharmony_ci      .pStages = pipeline_shader_stages,
690bf215546Sopenharmony_ci      .pVertexInputState = vi_create_info,
691bf215546Sopenharmony_ci      .pInputAssemblyState =
692bf215546Sopenharmony_ci         &(VkPipelineInputAssemblyStateCreateInfo){
693bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
694bf215546Sopenharmony_ci            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
695bf215546Sopenharmony_ci            .primitiveRestartEnable = false,
696bf215546Sopenharmony_ci         },
697bf215546Sopenharmony_ci      .pViewportState =
698bf215546Sopenharmony_ci         &(VkPipelineViewportStateCreateInfo){
699bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
700bf215546Sopenharmony_ci            .viewportCount = 1,
701bf215546Sopenharmony_ci            .scissorCount = 1,
702bf215546Sopenharmony_ci         },
703bf215546Sopenharmony_ci      .pRasterizationState =
704bf215546Sopenharmony_ci         &(VkPipelineRasterizationStateCreateInfo){
705bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
706bf215546Sopenharmony_ci            .rasterizerDiscardEnable = false,
707bf215546Sopenharmony_ci            .polygonMode = VK_POLYGON_MODE_FILL,
708bf215546Sopenharmony_ci            .cullMode = VK_CULL_MODE_NONE,
709bf215546Sopenharmony_ci            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
710bf215546Sopenharmony_ci            .depthBiasConstantFactor = 0.0f,
711bf215546Sopenharmony_ci            .depthBiasClamp = 0.0f,
712bf215546Sopenharmony_ci            .depthBiasSlopeFactor = 0.0f,
713bf215546Sopenharmony_ci            .lineWidth = 1.0f},
714bf215546Sopenharmony_ci      .pMultisampleState =
715bf215546Sopenharmony_ci         &(VkPipelineMultisampleStateCreateInfo){
716bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
717bf215546Sopenharmony_ci            .rasterizationSamples = 1 << log2_samples,
718bf215546Sopenharmony_ci            .sampleShadingEnable = log2_samples > 1,
719bf215546Sopenharmony_ci            .minSampleShading = 1.0,
720bf215546Sopenharmony_ci            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
721bf215546Sopenharmony_ci         },
722bf215546Sopenharmony_ci      .pColorBlendState =
723bf215546Sopenharmony_ci         &(VkPipelineColorBlendStateCreateInfo){
724bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
725bf215546Sopenharmony_ci            .attachmentCount = 1,
726bf215546Sopenharmony_ci            .pAttachments =
727bf215546Sopenharmony_ci               (VkPipelineColorBlendAttachmentState[]){
728bf215546Sopenharmony_ci                  {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |
729bf215546Sopenharmony_ci                                     VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},
730bf215546Sopenharmony_ci               },
731bf215546Sopenharmony_ci            .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }},
732bf215546Sopenharmony_ci      .pDynamicState =
733bf215546Sopenharmony_ci         &(VkPipelineDynamicStateCreateInfo){
734bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
735bf215546Sopenharmony_ci            .dynamicStateCount = 2,
736bf215546Sopenharmony_ci            .pDynamicStates =
737bf215546Sopenharmony_ci               (VkDynamicState[]){
738bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_VIEWPORT,
739bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_SCISSOR,
740bf215546Sopenharmony_ci               },
741bf215546Sopenharmony_ci         },
742bf215546Sopenharmony_ci      .flags = 0,
743bf215546Sopenharmony_ci      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
744bf215546Sopenharmony_ci      .renderPass = VK_NULL_HANDLE,
745bf215546Sopenharmony_ci      .subpass = 0,
746bf215546Sopenharmony_ci   };
747bf215546Sopenharmony_ci
748bf215546Sopenharmony_ci   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
749bf215546Sopenharmony_ci
750bf215546Sopenharmony_ci   result = radv_graphics_pipeline_create(
751bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
752bf215546Sopenharmony_ci      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
753bf215546Sopenharmony_ci      &device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]);
754bf215546Sopenharmony_ci
755bf215546Sopenharmony_ci   ralloc_free(vs);
756bf215546Sopenharmony_ci   ralloc_free(fs);
757bf215546Sopenharmony_ci
758bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
759bf215546Sopenharmony_ci   return result;
760bf215546Sopenharmony_ci}
761bf215546Sopenharmony_ci
762bf215546Sopenharmony_cistatic VkResult
763bf215546Sopenharmony_ciblit2d_init_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
764bf215546Sopenharmony_ci                                uint32_t log2_samples)
765bf215546Sopenharmony_ci{
766bf215546Sopenharmony_ci   VkResult result;
767bf215546Sopenharmony_ci   const char *name;
768bf215546Sopenharmony_ci
769bf215546Sopenharmony_ci   mtx_lock(&device->meta_state.mtx);
770bf215546Sopenharmony_ci   if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) {
771bf215546Sopenharmony_ci      mtx_unlock(&device->meta_state.mtx);
772bf215546Sopenharmony_ci      return VK_SUCCESS;
773bf215546Sopenharmony_ci   }
774bf215546Sopenharmony_ci
775bf215546Sopenharmony_ci   texel_fetch_build_func src_func;
776bf215546Sopenharmony_ci   switch (src_type) {
777bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE:
778bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
779bf215546Sopenharmony_ci      name = "meta_blit2d_depth_image_fs";
780bf215546Sopenharmony_ci      break;
781bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE_3D:
782bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
783bf215546Sopenharmony_ci      name = "meta_blit3d_depth_image_fs";
784bf215546Sopenharmony_ci      break;
785bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_BUFFER:
786bf215546Sopenharmony_ci      src_func = build_nir_buffer_fetch;
787bf215546Sopenharmony_ci      name = "meta_blit2d_depth_buffer_fs";
788bf215546Sopenharmony_ci      break;
789bf215546Sopenharmony_ci   default:
790bf215546Sopenharmony_ci      unreachable("unknown blit src type\n");
791bf215546Sopenharmony_ci      break;
792bf215546Sopenharmony_ci   }
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_ci   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
795bf215546Sopenharmony_ci   nir_shader *fs = build_nir_copy_fragment_shader_depth(
796bf215546Sopenharmony_ci      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
797bf215546Sopenharmony_ci   nir_shader *vs = build_nir_vertex_shader(device);
798bf215546Sopenharmony_ci
799bf215546Sopenharmony_ci   vi_create_info = &normal_vi_create_info;
800bf215546Sopenharmony_ci
801bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
802bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
803bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_VERTEX_BIT,
804bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(vs),
805bf215546Sopenharmony_ci       .pName = "main",
806bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
807bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
808bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
809bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(fs),
810bf215546Sopenharmony_ci       .pName = "main",
811bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
812bf215546Sopenharmony_ci   };
813bf215546Sopenharmony_ci
814bf215546Sopenharmony_ci   const VkPipelineRenderingCreateInfo rendering_create_info = {
815bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
816bf215546Sopenharmony_ci      .depthAttachmentFormat = VK_FORMAT_D32_SFLOAT,
817bf215546Sopenharmony_ci   };
818bf215546Sopenharmony_ci
819bf215546Sopenharmony_ci   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
820bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
821bf215546Sopenharmony_ci      .pNext = &rendering_create_info,
822bf215546Sopenharmony_ci      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
823bf215546Sopenharmony_ci      .pStages = pipeline_shader_stages,
824bf215546Sopenharmony_ci      .pVertexInputState = vi_create_info,
825bf215546Sopenharmony_ci      .pInputAssemblyState =
826bf215546Sopenharmony_ci         &(VkPipelineInputAssemblyStateCreateInfo){
827bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
828bf215546Sopenharmony_ci            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
829bf215546Sopenharmony_ci            .primitiveRestartEnable = false,
830bf215546Sopenharmony_ci         },
831bf215546Sopenharmony_ci      .pViewportState =
832bf215546Sopenharmony_ci         &(VkPipelineViewportStateCreateInfo){
833bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
834bf215546Sopenharmony_ci            .viewportCount = 1,
835bf215546Sopenharmony_ci            .scissorCount = 1,
836bf215546Sopenharmony_ci         },
837bf215546Sopenharmony_ci      .pRasterizationState =
838bf215546Sopenharmony_ci         &(VkPipelineRasterizationStateCreateInfo){
839bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
840bf215546Sopenharmony_ci            .rasterizerDiscardEnable = false,
841bf215546Sopenharmony_ci            .polygonMode = VK_POLYGON_MODE_FILL,
842bf215546Sopenharmony_ci            .cullMode = VK_CULL_MODE_NONE,
843bf215546Sopenharmony_ci            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
844bf215546Sopenharmony_ci            .depthBiasConstantFactor = 0.0f,
845bf215546Sopenharmony_ci            .depthBiasClamp = 0.0f,
846bf215546Sopenharmony_ci            .depthBiasSlopeFactor = 0.0f,
847bf215546Sopenharmony_ci            .lineWidth = 1.0f},
848bf215546Sopenharmony_ci      .pMultisampleState =
849bf215546Sopenharmony_ci         &(VkPipelineMultisampleStateCreateInfo){
850bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
851bf215546Sopenharmony_ci            .rasterizationSamples = 1 << log2_samples,
852bf215546Sopenharmony_ci            .sampleShadingEnable = false,
853bf215546Sopenharmony_ci            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
854bf215546Sopenharmony_ci         },
855bf215546Sopenharmony_ci      .pColorBlendState =
856bf215546Sopenharmony_ci         &(VkPipelineColorBlendStateCreateInfo){
857bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
858bf215546Sopenharmony_ci            .attachmentCount = 0,
859bf215546Sopenharmony_ci            .pAttachments = NULL,
860bf215546Sopenharmony_ci            .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
861bf215546Sopenharmony_ci         },
862bf215546Sopenharmony_ci      .pDepthStencilState =
863bf215546Sopenharmony_ci         &(VkPipelineDepthStencilStateCreateInfo){
864bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
865bf215546Sopenharmony_ci            .depthTestEnable = true,
866bf215546Sopenharmony_ci            .depthWriteEnable = true,
867bf215546Sopenharmony_ci            .depthCompareOp = VK_COMPARE_OP_ALWAYS,
868bf215546Sopenharmony_ci            .front = {
869bf215546Sopenharmony_ci               .failOp = VK_STENCIL_OP_KEEP,
870bf215546Sopenharmony_ci               .passOp = VK_STENCIL_OP_KEEP,
871bf215546Sopenharmony_ci               .depthFailOp = VK_STENCIL_OP_KEEP,
872bf215546Sopenharmony_ci               .compareOp = VK_COMPARE_OP_NEVER,
873bf215546Sopenharmony_ci               .compareMask = UINT32_MAX,
874bf215546Sopenharmony_ci               .writeMask = UINT32_MAX,
875bf215546Sopenharmony_ci               .reference = 0u,
876bf215546Sopenharmony_ci            },
877bf215546Sopenharmony_ci            .back = {
878bf215546Sopenharmony_ci               .failOp = VK_STENCIL_OP_KEEP,
879bf215546Sopenharmony_ci               .passOp = VK_STENCIL_OP_KEEP,
880bf215546Sopenharmony_ci               .depthFailOp = VK_STENCIL_OP_KEEP,
881bf215546Sopenharmony_ci               .compareOp = VK_COMPARE_OP_NEVER,
882bf215546Sopenharmony_ci               .compareMask = UINT32_MAX,
883bf215546Sopenharmony_ci               .writeMask = UINT32_MAX,
884bf215546Sopenharmony_ci               .reference = 0u,
885bf215546Sopenharmony_ci            },
886bf215546Sopenharmony_ci            .minDepthBounds = 0.0f,
887bf215546Sopenharmony_ci            .maxDepthBounds = 1.0f,
888bf215546Sopenharmony_ci         },
889bf215546Sopenharmony_ci      .pDynamicState =
890bf215546Sopenharmony_ci         &(VkPipelineDynamicStateCreateInfo){
891bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
892bf215546Sopenharmony_ci            .dynamicStateCount = 2,
893bf215546Sopenharmony_ci            .pDynamicStates =
894bf215546Sopenharmony_ci               (VkDynamicState[]){
895bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_VIEWPORT,
896bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_SCISSOR,
897bf215546Sopenharmony_ci               },
898bf215546Sopenharmony_ci         },
899bf215546Sopenharmony_ci      .flags = 0,
900bf215546Sopenharmony_ci      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
901bf215546Sopenharmony_ci      .renderPass = VK_NULL_HANDLE,
902bf215546Sopenharmony_ci      .subpass = 0,
903bf215546Sopenharmony_ci   };
904bf215546Sopenharmony_ci
905bf215546Sopenharmony_ci   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
906bf215546Sopenharmony_ci
907bf215546Sopenharmony_ci   result = radv_graphics_pipeline_create(
908bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
909bf215546Sopenharmony_ci      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
910bf215546Sopenharmony_ci      &device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]);
911bf215546Sopenharmony_ci
912bf215546Sopenharmony_ci   ralloc_free(vs);
913bf215546Sopenharmony_ci   ralloc_free(fs);
914bf215546Sopenharmony_ci
915bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
916bf215546Sopenharmony_ci   return result;
917bf215546Sopenharmony_ci}
918bf215546Sopenharmony_ci
919bf215546Sopenharmony_cistatic VkResult
920bf215546Sopenharmony_ciblit2d_init_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
921bf215546Sopenharmony_ci                                  uint32_t log2_samples)
922bf215546Sopenharmony_ci{
923bf215546Sopenharmony_ci   VkResult result;
924bf215546Sopenharmony_ci   const char *name;
925bf215546Sopenharmony_ci
926bf215546Sopenharmony_ci   mtx_lock(&device->meta_state.mtx);
927bf215546Sopenharmony_ci   if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) {
928bf215546Sopenharmony_ci      mtx_unlock(&device->meta_state.mtx);
929bf215546Sopenharmony_ci      return VK_SUCCESS;
930bf215546Sopenharmony_ci   }
931bf215546Sopenharmony_ci
932bf215546Sopenharmony_ci   texel_fetch_build_func src_func;
933bf215546Sopenharmony_ci   switch (src_type) {
934bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE:
935bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
936bf215546Sopenharmony_ci      name = "meta_blit2d_stencil_image_fs";
937bf215546Sopenharmony_ci      break;
938bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_IMAGE_3D:
939bf215546Sopenharmony_ci      src_func = build_nir_texel_fetch;
940bf215546Sopenharmony_ci      name = "meta_blit3d_stencil_image_fs";
941bf215546Sopenharmony_ci      break;
942bf215546Sopenharmony_ci   case BLIT2D_SRC_TYPE_BUFFER:
943bf215546Sopenharmony_ci      src_func = build_nir_buffer_fetch;
944bf215546Sopenharmony_ci      name = "meta_blit2d_stencil_buffer_fs";
945bf215546Sopenharmony_ci      break;
946bf215546Sopenharmony_ci   default:
947bf215546Sopenharmony_ci      unreachable("unknown blit src type\n");
948bf215546Sopenharmony_ci      break;
949bf215546Sopenharmony_ci   }
950bf215546Sopenharmony_ci
951bf215546Sopenharmony_ci   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
952bf215546Sopenharmony_ci   nir_shader *fs = build_nir_copy_fragment_shader_stencil(
953bf215546Sopenharmony_ci      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
954bf215546Sopenharmony_ci   nir_shader *vs = build_nir_vertex_shader(device);
955bf215546Sopenharmony_ci
956bf215546Sopenharmony_ci   vi_create_info = &normal_vi_create_info;
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
959bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
960bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_VERTEX_BIT,
961bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(vs),
962bf215546Sopenharmony_ci       .pName = "main",
963bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
964bf215546Sopenharmony_ci      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
965bf215546Sopenharmony_ci       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
966bf215546Sopenharmony_ci       .module = vk_shader_module_handle_from_nir(fs),
967bf215546Sopenharmony_ci       .pName = "main",
968bf215546Sopenharmony_ci       .pSpecializationInfo = NULL},
969bf215546Sopenharmony_ci   };
970bf215546Sopenharmony_ci
971bf215546Sopenharmony_ci   const VkPipelineRenderingCreateInfo rendering_create_info = {
972bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
973bf215546Sopenharmony_ci      .stencilAttachmentFormat = VK_FORMAT_S8_UINT,
974bf215546Sopenharmony_ci   };
975bf215546Sopenharmony_ci
976bf215546Sopenharmony_ci   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
977bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
978bf215546Sopenharmony_ci      .pNext = &rendering_create_info,
979bf215546Sopenharmony_ci      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
980bf215546Sopenharmony_ci      .pStages = pipeline_shader_stages,
981bf215546Sopenharmony_ci      .pVertexInputState = vi_create_info,
982bf215546Sopenharmony_ci      .pInputAssemblyState =
983bf215546Sopenharmony_ci         &(VkPipelineInputAssemblyStateCreateInfo){
984bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
985bf215546Sopenharmony_ci            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
986bf215546Sopenharmony_ci            .primitiveRestartEnable = false,
987bf215546Sopenharmony_ci         },
988bf215546Sopenharmony_ci      .pViewportState =
989bf215546Sopenharmony_ci         &(VkPipelineViewportStateCreateInfo){
990bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
991bf215546Sopenharmony_ci            .viewportCount = 1,
992bf215546Sopenharmony_ci            .scissorCount = 1,
993bf215546Sopenharmony_ci         },
994bf215546Sopenharmony_ci      .pRasterizationState =
995bf215546Sopenharmony_ci         &(VkPipelineRasterizationStateCreateInfo){
996bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
997bf215546Sopenharmony_ci            .rasterizerDiscardEnable = false,
998bf215546Sopenharmony_ci            .polygonMode = VK_POLYGON_MODE_FILL,
999bf215546Sopenharmony_ci            .cullMode = VK_CULL_MODE_NONE,
1000bf215546Sopenharmony_ci            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
1001bf215546Sopenharmony_ci            .depthBiasConstantFactor = 0.0f,
1002bf215546Sopenharmony_ci            .depthBiasClamp = 0.0f,
1003bf215546Sopenharmony_ci            .depthBiasSlopeFactor = 0.0f,
1004bf215546Sopenharmony_ci            .lineWidth = 1.0f},
1005bf215546Sopenharmony_ci      .pMultisampleState =
1006bf215546Sopenharmony_ci         &(VkPipelineMultisampleStateCreateInfo){
1007bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1008bf215546Sopenharmony_ci            .rasterizationSamples = 1 << log2_samples,
1009bf215546Sopenharmony_ci            .sampleShadingEnable = false,
1010bf215546Sopenharmony_ci            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
1011bf215546Sopenharmony_ci         },
1012bf215546Sopenharmony_ci      .pColorBlendState =
1013bf215546Sopenharmony_ci         &(VkPipelineColorBlendStateCreateInfo){
1014bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1015bf215546Sopenharmony_ci            .attachmentCount = 0,
1016bf215546Sopenharmony_ci            .pAttachments = NULL,
1017bf215546Sopenharmony_ci            .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
1018bf215546Sopenharmony_ci         },
1019bf215546Sopenharmony_ci      .pDepthStencilState =
1020bf215546Sopenharmony_ci         &(VkPipelineDepthStencilStateCreateInfo){
1021bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1022bf215546Sopenharmony_ci            .depthTestEnable = false,
1023bf215546Sopenharmony_ci            .depthWriteEnable = false,
1024bf215546Sopenharmony_ci            .stencilTestEnable = true,
1025bf215546Sopenharmony_ci            .front = {.failOp = VK_STENCIL_OP_REPLACE,
1026bf215546Sopenharmony_ci                      .passOp = VK_STENCIL_OP_REPLACE,
1027bf215546Sopenharmony_ci                      .depthFailOp = VK_STENCIL_OP_REPLACE,
1028bf215546Sopenharmony_ci                      .compareOp = VK_COMPARE_OP_ALWAYS,
1029bf215546Sopenharmony_ci                      .compareMask = 0xff,
1030bf215546Sopenharmony_ci                      .writeMask = 0xff,
1031bf215546Sopenharmony_ci                      .reference = 0},
1032bf215546Sopenharmony_ci            .back = {.failOp = VK_STENCIL_OP_REPLACE,
1033bf215546Sopenharmony_ci                     .passOp = VK_STENCIL_OP_REPLACE,
1034bf215546Sopenharmony_ci                     .depthFailOp = VK_STENCIL_OP_REPLACE,
1035bf215546Sopenharmony_ci                     .compareOp = VK_COMPARE_OP_ALWAYS,
1036bf215546Sopenharmony_ci                     .compareMask = 0xff,
1037bf215546Sopenharmony_ci                     .writeMask = 0xff,
1038bf215546Sopenharmony_ci                     .reference = 0},
1039bf215546Sopenharmony_ci            .depthCompareOp = VK_COMPARE_OP_ALWAYS,
1040bf215546Sopenharmony_ci            .minDepthBounds = 0.0f,
1041bf215546Sopenharmony_ci            .maxDepthBounds = 1.0f,
1042bf215546Sopenharmony_ci         },
1043bf215546Sopenharmony_ci      .pDynamicState =
1044bf215546Sopenharmony_ci         &(VkPipelineDynamicStateCreateInfo){
1045bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1046bf215546Sopenharmony_ci            .dynamicStateCount = 2,
1047bf215546Sopenharmony_ci            .pDynamicStates =
1048bf215546Sopenharmony_ci               (VkDynamicState[]){
1049bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_VIEWPORT,
1050bf215546Sopenharmony_ci                  VK_DYNAMIC_STATE_SCISSOR,
1051bf215546Sopenharmony_ci               },
1052bf215546Sopenharmony_ci         },
1053bf215546Sopenharmony_ci      .flags = 0,
1054bf215546Sopenharmony_ci      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1055bf215546Sopenharmony_ci      .renderPass = VK_NULL_HANDLE,
1056bf215546Sopenharmony_ci      .subpass = 0,
1057bf215546Sopenharmony_ci   };
1058bf215546Sopenharmony_ci
1059bf215546Sopenharmony_ci   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
1060bf215546Sopenharmony_ci
1061bf215546Sopenharmony_ci   result = radv_graphics_pipeline_create(
1062bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
1063bf215546Sopenharmony_ci      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
1064bf215546Sopenharmony_ci      &device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]);
1065bf215546Sopenharmony_ci
1066bf215546Sopenharmony_ci   ralloc_free(vs);
1067bf215546Sopenharmony_ci   ralloc_free(fs);
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
1070bf215546Sopenharmony_ci   return result;
1071bf215546Sopenharmony_ci}
1072bf215546Sopenharmony_ci
1073bf215546Sopenharmony_cistatic VkResult
1074bf215546Sopenharmony_cimeta_blit2d_create_pipe_layout(struct radv_device *device, int idx, uint32_t log2_samples)
1075bf215546Sopenharmony_ci{
1076bf215546Sopenharmony_ci   VkResult result;
1077bf215546Sopenharmony_ci   VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER)
1078bf215546Sopenharmony_ci                                   ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
1079bf215546Sopenharmony_ci                                   : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1080bf215546Sopenharmony_ci   const VkPushConstantRange push_constant_ranges[] = {
1081bf215546Sopenharmony_ci      {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
1082bf215546Sopenharmony_ci      {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
1083bf215546Sopenharmony_ci   };
1084bf215546Sopenharmony_ci   int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
1085bf215546Sopenharmony_ci
1086bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(
1087bf215546Sopenharmony_ci      radv_device_to_handle(device),
1088bf215546Sopenharmony_ci      &(VkDescriptorSetLayoutCreateInfo){
1089bf215546Sopenharmony_ci         .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1090bf215546Sopenharmony_ci         .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1091bf215546Sopenharmony_ci         .bindingCount = 1,
1092bf215546Sopenharmony_ci         .pBindings =
1093bf215546Sopenharmony_ci            (VkDescriptorSetLayoutBinding[]){
1094bf215546Sopenharmony_ci               {.binding = 0,
1095bf215546Sopenharmony_ci                .descriptorType = desc_type,
1096bf215546Sopenharmony_ci                .descriptorCount = 1,
1097bf215546Sopenharmony_ci                .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1098bf215546Sopenharmony_ci                .pImmutableSamplers = NULL},
1099bf215546Sopenharmony_ci            }},
1100bf215546Sopenharmony_ci      &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].ds_layouts[idx]);
1101bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1102bf215546Sopenharmony_ci      goto fail;
1103bf215546Sopenharmony_ci
1104bf215546Sopenharmony_ci   result = radv_CreatePipelineLayout(
1105bf215546Sopenharmony_ci      radv_device_to_handle(device),
1106bf215546Sopenharmony_ci      &(VkPipelineLayoutCreateInfo){
1107bf215546Sopenharmony_ci         .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1108bf215546Sopenharmony_ci         .setLayoutCount = 1,
1109bf215546Sopenharmony_ci         .pSetLayouts = &device->meta_state.blit2d[log2_samples].ds_layouts[idx],
1110bf215546Sopenharmony_ci         .pushConstantRangeCount = num_push_constant_range,
1111bf215546Sopenharmony_ci         .pPushConstantRanges = push_constant_ranges,
1112bf215546Sopenharmony_ci      },
1113bf215546Sopenharmony_ci      &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].p_layouts[idx]);
1114bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1115bf215546Sopenharmony_ci      goto fail;
1116bf215546Sopenharmony_ci   return VK_SUCCESS;
1117bf215546Sopenharmony_cifail:
1118bf215546Sopenharmony_ci   return result;
1119bf215546Sopenharmony_ci}
1120bf215546Sopenharmony_ci
1121bf215546Sopenharmony_ciVkResult
1122bf215546Sopenharmony_ciradv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand)
1123bf215546Sopenharmony_ci{
1124bf215546Sopenharmony_ci   VkResult result;
1125bf215546Sopenharmony_ci
1126bf215546Sopenharmony_ci   for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; log2_samples++) {
1127bf215546Sopenharmony_ci      for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
1128bf215546Sopenharmony_ci         /* Don't need to handle copies between buffers and multisample images. */
1129bf215546Sopenharmony_ci         if (src == BLIT2D_SRC_TYPE_BUFFER && log2_samples > 0)
1130bf215546Sopenharmony_ci            continue;
1131bf215546Sopenharmony_ci
1132bf215546Sopenharmony_ci         /* There are no multisampled 3D images. */
1133bf215546Sopenharmony_ci         if (src == BLIT2D_SRC_TYPE_IMAGE_3D && log2_samples > 0)
1134bf215546Sopenharmony_ci            continue;
1135bf215546Sopenharmony_ci
1136bf215546Sopenharmony_ci         result = meta_blit2d_create_pipe_layout(device, src, log2_samples);
1137bf215546Sopenharmony_ci         if (result != VK_SUCCESS)
1138bf215546Sopenharmony_ci            return result;
1139bf215546Sopenharmony_ci
1140bf215546Sopenharmony_ci         if (on_demand)
1141bf215546Sopenharmony_ci            continue;
1142bf215546Sopenharmony_ci
1143bf215546Sopenharmony_ci         for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
1144bf215546Sopenharmony_ci            result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j],
1145bf215546Sopenharmony_ci                                                log2_samples);
1146bf215546Sopenharmony_ci            if (result != VK_SUCCESS)
1147bf215546Sopenharmony_ci               return result;
1148bf215546Sopenharmony_ci         }
1149bf215546Sopenharmony_ci
1150bf215546Sopenharmony_ci         result = blit2d_init_depth_only_pipeline(device, src, log2_samples);
1151bf215546Sopenharmony_ci         if (result != VK_SUCCESS)
1152bf215546Sopenharmony_ci            return result;
1153bf215546Sopenharmony_ci
1154bf215546Sopenharmony_ci         result = blit2d_init_stencil_only_pipeline(device, src, log2_samples);
1155bf215546Sopenharmony_ci         if (result != VK_SUCCESS)
1156bf215546Sopenharmony_ci            return result;
1157bf215546Sopenharmony_ci      }
1158bf215546Sopenharmony_ci   }
1159bf215546Sopenharmony_ci
1160bf215546Sopenharmony_ci   return VK_SUCCESS;
1161bf215546Sopenharmony_ci}
1162