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