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