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