radv_meta_blit.c revision 7ec681f3
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include "nir/nir_builder.h"
25#include "radv_meta.h"
26
27struct blit_region {
28   VkOffset3D src_offset;
29   VkExtent3D src_extent;
30   VkOffset3D dest_offset;
31   VkExtent3D dest_extent;
32};
33
34static VkResult build_pipeline(struct radv_device *device, VkImageAspectFlagBits aspect,
35                               enum glsl_sampler_dim tex_dim, unsigned fs_key,
36                               VkPipeline *pipeline);
37
38static nir_shader *
39build_nir_vertex_shader(void)
40{
41   const struct glsl_type *vec4 = glsl_vec4_type();
42   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL, "meta_blit_vs");
43
44   nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
45   pos_out->data.location = VARYING_SLOT_POS;
46
47   nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "v_tex_pos");
48   tex_pos_out->data.location = VARYING_SLOT_VAR0;
49   tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
50
51   nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b);
52
53   nir_store_var(&b, pos_out, outvec, 0xf);
54
55   nir_ssa_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
56   nir_ssa_def *src0_z =
57      nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 0), .base = 16, .range = 4);
58
59   nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(&b);
60
61   /* vertex 0 - src0_x, src0_y, src0_z */
62   /* vertex 1 - src0_x, src1_y, src0_z*/
63   /* vertex 2 - src1_x, src0_y, src0_z */
64   /* so channel 0 is vertex_id != 2 ? src_x : src_x + w
65      channel 1 is vertex id != 1 ? src_y : src_y + w */
66
67   nir_ssa_def *c0cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 2));
68   nir_ssa_def *c1cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 1));
69
70   nir_ssa_def *comp[4];
71   comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
72
73   comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
74   comp[2] = src0_z;
75   comp[3] = nir_imm_float(&b, 1.0);
76   nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 4);
77   nir_store_var(&b, tex_pos_out, out_tex_vec, 0xf);
78   return b.shader;
79}
80
81static nir_shader *
82build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
83{
84   const struct glsl_type *vec4 = glsl_vec4_type();
85   nir_builder b =
86      nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "meta_blit_fs.%d", tex_dim);
87
88   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos");
89   tex_pos_in->data.location = VARYING_SLOT_VAR0;
90
91   /* Swizzle the array index which comes in as Z coordinate into the right
92    * position.
93    */
94   unsigned swz[] = {0, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 1), 2};
95   nir_ssa_def *const tex_pos =
96      nir_swizzle(&b, nir_load_var(&b, tex_pos_in), swz, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 3));
97
98   const struct glsl_type *sampler_type =
99      glsl_sampler_type(tex_dim, false, tex_dim != GLSL_SAMPLER_DIM_3D, glsl_get_base_type(vec4));
100   nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
101   sampler->data.descriptor_set = 0;
102   sampler->data.binding = 0;
103
104   nir_ssa_def *tex_deref = &nir_build_deref_var(&b, sampler)->dest.ssa;
105
106   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
107   tex->sampler_dim = tex_dim;
108   tex->op = nir_texop_tex;
109   tex->src[0].src_type = nir_tex_src_coord;
110   tex->src[0].src = nir_src_for_ssa(tex_pos);
111   tex->src[1].src_type = nir_tex_src_texture_deref;
112   tex->src[1].src = nir_src_for_ssa(tex_deref);
113   tex->src[2].src_type = nir_tex_src_sampler_deref;
114   tex->src[2].src = nir_src_for_ssa(tex_deref);
115   tex->dest_type = nir_type_float32; /* TODO */
116   tex->is_array = glsl_sampler_type_is_array(sampler_type);
117   tex->coord_components = tex_pos->num_components;
118
119   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
120   nir_builder_instr_insert(&b, &tex->instr);
121
122   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
123   color_out->data.location = FRAG_RESULT_DATA0;
124   nir_store_var(&b, color_out, &tex->dest.ssa, 0xf);
125
126   return b.shader;
127}
128
129static nir_shader *
130build_nir_copy_fragment_shader_depth(enum glsl_sampler_dim tex_dim)
131{
132   const struct glsl_type *vec4 = glsl_vec4_type();
133   nir_builder b =
134      nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "meta_blit_depth_fs.%d", tex_dim);
135
136   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos");
137   tex_pos_in->data.location = VARYING_SLOT_VAR0;
138
139   /* Swizzle the array index which comes in as Z coordinate into the right
140    * position.
141    */
142   unsigned swz[] = {0, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 1), 2};
143   nir_ssa_def *const tex_pos =
144      nir_swizzle(&b, nir_load_var(&b, tex_pos_in), swz, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 3));
145
146   const struct glsl_type *sampler_type =
147      glsl_sampler_type(tex_dim, false, tex_dim != GLSL_SAMPLER_DIM_3D, glsl_get_base_type(vec4));
148   nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
149   sampler->data.descriptor_set = 0;
150   sampler->data.binding = 0;
151
152   nir_ssa_def *tex_deref = &nir_build_deref_var(&b, sampler)->dest.ssa;
153
154   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
155   tex->sampler_dim = tex_dim;
156   tex->op = nir_texop_tex;
157   tex->src[0].src_type = nir_tex_src_coord;
158   tex->src[0].src = nir_src_for_ssa(tex_pos);
159   tex->src[1].src_type = nir_tex_src_texture_deref;
160   tex->src[1].src = nir_src_for_ssa(tex_deref);
161   tex->src[2].src_type = nir_tex_src_sampler_deref;
162   tex->src[2].src = nir_src_for_ssa(tex_deref);
163   tex->dest_type = nir_type_float32; /* TODO */
164   tex->is_array = glsl_sampler_type_is_array(sampler_type);
165   tex->coord_components = tex_pos->num_components;
166
167   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
168   nir_builder_instr_insert(&b, &tex->instr);
169
170   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
171   color_out->data.location = FRAG_RESULT_DEPTH;
172   nir_store_var(&b, color_out, &tex->dest.ssa, 0x1);
173
174   return b.shader;
175}
176
177static nir_shader *
178build_nir_copy_fragment_shader_stencil(enum glsl_sampler_dim tex_dim)
179{
180   const struct glsl_type *vec4 = glsl_vec4_type();
181   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL,
182                                                  "meta_blit_stencil_fs.%d", tex_dim);
183
184   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec4, "v_tex_pos");
185   tex_pos_in->data.location = VARYING_SLOT_VAR0;
186
187   /* Swizzle the array index which comes in as Z coordinate into the right
188    * position.
189    */
190   unsigned swz[] = {0, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 1), 2};
191   nir_ssa_def *const tex_pos =
192      nir_swizzle(&b, nir_load_var(&b, tex_pos_in), swz, (tex_dim == GLSL_SAMPLER_DIM_1D ? 2 : 3));
193
194   const struct glsl_type *sampler_type =
195      glsl_sampler_type(tex_dim, false, tex_dim != GLSL_SAMPLER_DIM_3D, glsl_get_base_type(vec4));
196   nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
197   sampler->data.descriptor_set = 0;
198   sampler->data.binding = 0;
199
200   nir_ssa_def *tex_deref = &nir_build_deref_var(&b, sampler)->dest.ssa;
201
202   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
203   tex->sampler_dim = tex_dim;
204   tex->op = nir_texop_tex;
205   tex->src[0].src_type = nir_tex_src_coord;
206   tex->src[0].src = nir_src_for_ssa(tex_pos);
207   tex->src[1].src_type = nir_tex_src_texture_deref;
208   tex->src[1].src = nir_src_for_ssa(tex_deref);
209   tex->src[2].src_type = nir_tex_src_sampler_deref;
210   tex->src[2].src = nir_src_for_ssa(tex_deref);
211   tex->dest_type = nir_type_float32; /* TODO */
212   tex->is_array = glsl_sampler_type_is_array(sampler_type);
213   tex->coord_components = tex_pos->num_components;
214
215   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
216   nir_builder_instr_insert(&b, &tex->instr);
217
218   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
219   color_out->data.location = FRAG_RESULT_STENCIL;
220   nir_store_var(&b, color_out, &tex->dest.ssa, 0x1);
221
222   return b.shader;
223}
224
225static enum glsl_sampler_dim
226translate_sampler_dim(VkImageType type)
227{
228   switch (type) {
229   case VK_IMAGE_TYPE_1D:
230      return GLSL_SAMPLER_DIM_1D;
231   case VK_IMAGE_TYPE_2D:
232      return GLSL_SAMPLER_DIM_2D;
233   case VK_IMAGE_TYPE_3D:
234      return GLSL_SAMPLER_DIM_3D;
235   default:
236      unreachable("Unhandled image type");
237   }
238}
239
240static void
241meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,
242               struct radv_image_view *src_iview, VkImageLayout src_image_layout,
243               float src_offset_0[3], float src_offset_1[3], struct radv_image *dest_image,
244               struct radv_image_view *dest_iview, VkImageLayout dest_image_layout,
245               VkOffset2D dest_offset_0, VkOffset2D dest_offset_1, VkRect2D dest_box,
246               VkSampler sampler)
247{
248   struct radv_device *device = cmd_buffer->device;
249   uint32_t src_width = radv_minify(src_iview->image->info.width, src_iview->base_mip);
250   uint32_t src_height = radv_minify(src_iview->image->info.height, src_iview->base_mip);
251   uint32_t src_depth = radv_minify(src_iview->image->info.depth, src_iview->base_mip);
252   uint32_t dst_width = radv_minify(dest_iview->image->info.width, dest_iview->base_mip);
253   uint32_t dst_height = radv_minify(dest_iview->image->info.height, dest_iview->base_mip);
254
255   assert(src_image->info.samples == dest_image->info.samples);
256
257   float vertex_push_constants[5] = {
258      src_offset_0[0] / (float)src_width, src_offset_0[1] / (float)src_height,
259      src_offset_1[0] / (float)src_width, src_offset_1[1] / (float)src_height,
260      src_offset_0[2] / (float)src_depth,
261   };
262
263   radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
264                         device->meta_state.blit.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 20,
265                         vertex_push_constants);
266
267   VkFramebuffer fb;
268   radv_CreateFramebuffer(radv_device_to_handle(device),
269                          &(VkFramebufferCreateInfo){
270                             .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
271                             .attachmentCount = 1,
272                             .pAttachments =
273                                (VkImageView[]){
274                                   radv_image_view_to_handle(dest_iview),
275                                },
276                             .width = dst_width,
277                             .height = dst_height,
278                             .layers = 1,
279                          },
280                          &cmd_buffer->pool->alloc, &fb);
281   VkPipeline *pipeline = NULL;
282   unsigned fs_key = 0;
283   switch (src_iview->aspect_mask) {
284   case VK_IMAGE_ASPECT_COLOR_BIT: {
285      unsigned dst_layout = radv_meta_dst_layout_from_layout(dest_image_layout);
286      fs_key = radv_format_meta_fs_key(device, dest_image->vk_format);
287
288      radv_cmd_buffer_begin_render_pass(
289         cmd_buffer,
290         &(VkRenderPassBeginInfo){
291            .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
292            .renderPass = device->meta_state.blit.render_pass[fs_key][dst_layout],
293            .framebuffer = fb,
294            .renderArea =
295               {
296                  .offset = {dest_box.offset.x, dest_box.offset.y},
297                  .extent = {dest_box.extent.width, dest_box.extent.height},
298               },
299            .clearValueCount = 0,
300            .pClearValues = NULL,
301         },
302         NULL);
303      switch (src_image->type) {
304      case VK_IMAGE_TYPE_1D:
305         pipeline = &device->meta_state.blit.pipeline_1d_src[fs_key];
306         break;
307      case VK_IMAGE_TYPE_2D:
308         pipeline = &device->meta_state.blit.pipeline_2d_src[fs_key];
309         break;
310      case VK_IMAGE_TYPE_3D:
311         pipeline = &device->meta_state.blit.pipeline_3d_src[fs_key];
312         break;
313      default:
314         unreachable("bad VkImageType");
315      }
316      break;
317   }
318   case VK_IMAGE_ASPECT_DEPTH_BIT: {
319      enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dest_image_layout);
320      radv_cmd_buffer_begin_render_pass(
321         cmd_buffer,
322         &(VkRenderPassBeginInfo){
323            .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
324            .renderPass = device->meta_state.blit.depth_only_rp[ds_layout],
325            .framebuffer = fb,
326            .renderArea =
327               {
328                  .offset = {dest_box.offset.x, dest_box.offset.y},
329                  .extent = {dest_box.extent.width, dest_box.extent.height},
330               },
331            .clearValueCount = 0,
332            .pClearValues = NULL,
333         },
334         NULL);
335      switch (src_image->type) {
336      case VK_IMAGE_TYPE_1D:
337         pipeline = &device->meta_state.blit.depth_only_1d_pipeline;
338         break;
339      case VK_IMAGE_TYPE_2D:
340         pipeline = &device->meta_state.blit.depth_only_2d_pipeline;
341         break;
342      case VK_IMAGE_TYPE_3D:
343         pipeline = &device->meta_state.blit.depth_only_3d_pipeline;
344         break;
345      default:
346         unreachable("bad VkImageType");
347      }
348      break;
349   }
350   case VK_IMAGE_ASPECT_STENCIL_BIT: {
351      enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dest_image_layout);
352      radv_cmd_buffer_begin_render_pass(
353         cmd_buffer,
354         &(VkRenderPassBeginInfo){
355            .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
356            .renderPass = device->meta_state.blit.stencil_only_rp[ds_layout],
357            .framebuffer = fb,
358            .renderArea =
359               {
360                  .offset = {dest_box.offset.x, dest_box.offset.y},
361                  .extent = {dest_box.extent.width, dest_box.extent.height},
362               },
363            .clearValueCount = 0,
364            .pClearValues = NULL,
365         },
366         NULL);
367      switch (src_image->type) {
368      case VK_IMAGE_TYPE_1D:
369         pipeline = &device->meta_state.blit.stencil_only_1d_pipeline;
370         break;
371      case VK_IMAGE_TYPE_2D:
372         pipeline = &device->meta_state.blit.stencil_only_2d_pipeline;
373         break;
374      case VK_IMAGE_TYPE_3D:
375         pipeline = &device->meta_state.blit.stencil_only_3d_pipeline;
376         break;
377      default:
378         unreachable("bad VkImageType");
379      }
380      break;
381   }
382   default:
383      unreachable("bad VkImageType");
384   }
385
386   radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
387
388   if (!*pipeline) {
389      VkResult ret = build_pipeline(device, src_iview->aspect_mask,
390                                    translate_sampler_dim(src_image->type), fs_key, pipeline);
391      if (ret != VK_SUCCESS) {
392         cmd_buffer->record_result = ret;
393         goto fail_pipeline;
394      }
395   }
396
397   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
398                        *pipeline);
399
400   radv_meta_push_descriptor_set(
401      cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, device->meta_state.blit.pipeline_layout,
402      0, /* set */
403      1, /* descriptorWriteCount */
404      (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
405                                .dstBinding = 0,
406                                .dstArrayElement = 0,
407                                .descriptorCount = 1,
408                                .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
409                                .pImageInfo = (VkDescriptorImageInfo[]){
410                                   {
411                                      .sampler = sampler,
412                                      .imageView = radv_image_view_to_handle(src_iview),
413                                      .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
414                                   },
415                                }}});
416
417   radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
418                       &(VkViewport){.x = dest_offset_0.x,
419                                     .y = dest_offset_0.y,
420                                     .width = dest_offset_1.x - dest_offset_0.x,
421                                     .height = dest_offset_1.y - dest_offset_0.y,
422                                     .minDepth = 0.0f,
423                                     .maxDepth = 1.0f});
424
425   radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
426                      &(VkRect2D){
427                         .offset = (VkOffset2D){MIN2(dest_offset_0.x, dest_offset_1.x),
428                                                MIN2(dest_offset_0.y, dest_offset_1.y)},
429                         .extent = (VkExtent2D){abs(dest_offset_1.x - dest_offset_0.x),
430                                                abs(dest_offset_1.y - dest_offset_0.y)},
431                      });
432
433   radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
434
435fail_pipeline:
436   radv_cmd_buffer_end_render_pass(cmd_buffer);
437
438   /* At the point where we emit the draw call, all data from the
439    * descriptor sets, etc. has been used.  We are free to delete it.
440    */
441   /* TODO: above comment is not valid for at least descriptor sets/pools,
442    * as we may not free them till after execution finishes. Check others. */
443
444   radv_DestroyFramebuffer(radv_device_to_handle(device), fb, &cmd_buffer->pool->alloc);
445}
446
447static bool
448flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
449{
450   bool flip = false;
451   if (*src0 > *src1) {
452      unsigned tmp = *src0;
453      *src0 = *src1;
454      *src1 = tmp;
455      flip = !flip;
456   }
457
458   if (*dst0 > *dst1) {
459      unsigned tmp = *dst0;
460      *dst0 = *dst1;
461      *dst1 = tmp;
462      flip = !flip;
463   }
464   return flip;
465}
466
467static void
468blit_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,
469           VkImageLayout src_image_layout, struct radv_image *dst_image,
470           VkImageLayout dst_image_layout, const VkImageBlit2KHR *region, VkFilter filter)
471{
472   const VkImageSubresourceLayers *src_res = &region->srcSubresource;
473   const VkImageSubresourceLayers *dst_res = &region->dstSubresource;
474   struct radv_device *device = cmd_buffer->device;
475   struct radv_meta_saved_state saved_state;
476   bool old_predicating;
477   VkSampler sampler;
478
479   /* From the Vulkan 1.0 spec:
480    *
481    *    vkCmdBlitImage must not be used for multisampled source or
482    *    destination images. Use vkCmdResolveImage for this purpose.
483    */
484   assert(src_image->info.samples == 1);
485   assert(dst_image->info.samples == 1);
486
487   radv_CreateSampler(radv_device_to_handle(device),
488                      &(VkSamplerCreateInfo){
489                         .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
490                         .magFilter = filter,
491                         .minFilter = filter,
492                         .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
493                         .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
494                         .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
495                      },
496                      &cmd_buffer->pool->alloc, &sampler);
497
498   radv_meta_save(
499      &saved_state, cmd_buffer,
500      RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
501
502   /* VK_EXT_conditional_rendering says that blit commands should not be
503    * affected by conditional rendering.
504    */
505   old_predicating = cmd_buffer->state.predicating;
506   cmd_buffer->state.predicating = false;
507
508   unsigned dst_start, dst_end;
509   if (dst_image->type == VK_IMAGE_TYPE_3D) {
510      assert(dst_res->baseArrayLayer == 0);
511      dst_start = region->dstOffsets[0].z;
512      dst_end = region->dstOffsets[1].z;
513   } else {
514      dst_start = dst_res->baseArrayLayer;
515      dst_end = dst_start + dst_res->layerCount;
516   }
517
518   unsigned src_start, src_end;
519   if (src_image->type == VK_IMAGE_TYPE_3D) {
520      assert(src_res->baseArrayLayer == 0);
521      src_start = region->srcOffsets[0].z;
522      src_end = region->srcOffsets[1].z;
523   } else {
524      src_start = src_res->baseArrayLayer;
525      src_end = src_start + src_res->layerCount;
526   }
527
528   bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
529   float src_z_step = (float)(src_end - src_start) / (float)(dst_end - dst_start);
530
531   /* There is no interpolation to the pixel center during
532    * rendering, so add the 0.5 offset ourselves here. */
533   float depth_center_offset = 0;
534   if (src_image->type == VK_IMAGE_TYPE_3D)
535      depth_center_offset = 0.5 / (dst_end - dst_start) * (src_end - src_start);
536
537   if (flip_z) {
538      src_start = src_end;
539      src_z_step *= -1;
540      depth_center_offset *= -1;
541   }
542
543   unsigned src_x0 = region->srcOffsets[0].x;
544   unsigned src_x1 = region->srcOffsets[1].x;
545   unsigned dst_x0 = region->dstOffsets[0].x;
546   unsigned dst_x1 = region->dstOffsets[1].x;
547
548   unsigned src_y0 = region->srcOffsets[0].y;
549   unsigned src_y1 = region->srcOffsets[1].y;
550   unsigned dst_y0 = region->dstOffsets[0].y;
551   unsigned dst_y1 = region->dstOffsets[1].y;
552
553   VkRect2D dst_box;
554   dst_box.offset.x = MIN2(dst_x0, dst_x1);
555   dst_box.offset.y = MIN2(dst_y0, dst_y1);
556   dst_box.extent.width = dst_x1 - dst_x0;
557   dst_box.extent.height = dst_y1 - dst_y0;
558
559   const unsigned num_layers = dst_end - dst_start;
560   for (unsigned i = 0; i < num_layers; i++) {
561      struct radv_image_view dst_iview, src_iview;
562
563      const VkOffset2D dst_offset_0 = {
564         .x = dst_x0,
565         .y = dst_y0,
566      };
567      const VkOffset2D dst_offset_1 = {
568         .x = dst_x1,
569         .y = dst_y1,
570      };
571
572      float src_offset_0[3] = {
573         src_x0,
574         src_y0,
575         src_start + i * src_z_step + depth_center_offset,
576      };
577      float src_offset_1[3] = {
578         src_x1,
579         src_y1,
580         src_start + i * src_z_step + depth_center_offset,
581      };
582      const uint32_t dst_array_slice = dst_start + i;
583
584      /* 3D images have just 1 layer */
585      const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
586
587      radv_image_view_init(&dst_iview, cmd_buffer->device,
588                           &(VkImageViewCreateInfo){
589                              .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
590                              .image = radv_image_to_handle(dst_image),
591                              .viewType = radv_meta_get_view_type(dst_image),
592                              .format = dst_image->vk_format,
593                              .subresourceRange = {.aspectMask = dst_res->aspectMask,
594                                                   .baseMipLevel = dst_res->mipLevel,
595                                                   .levelCount = 1,
596                                                   .baseArrayLayer = dst_array_slice,
597                                                   .layerCount = 1},
598                           },
599                           NULL);
600      radv_image_view_init(&src_iview, cmd_buffer->device,
601                           &(VkImageViewCreateInfo){
602                              .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
603                              .image = radv_image_to_handle(src_image),
604                              .viewType = radv_meta_get_view_type(src_image),
605                              .format = src_image->vk_format,
606                              .subresourceRange = {.aspectMask = src_res->aspectMask,
607                                                   .baseMipLevel = src_res->mipLevel,
608                                                   .levelCount = 1,
609                                                   .baseArrayLayer = src_array_slice,
610                                                   .layerCount = 1},
611                           },
612                           NULL);
613      meta_emit_blit(cmd_buffer, src_image, &src_iview, src_image_layout, src_offset_0,
614                     src_offset_1, dst_image, &dst_iview, dst_image_layout, dst_offset_0,
615                     dst_offset_1, dst_box, sampler);
616
617      radv_image_view_finish(&dst_iview);
618      radv_image_view_finish(&src_iview);
619   }
620
621   /* Restore conditional rendering. */
622   cmd_buffer->state.predicating = old_predicating;
623
624   radv_meta_restore(&saved_state, cmd_buffer);
625
626   radv_DestroySampler(radv_device_to_handle(device), sampler, &cmd_buffer->pool->alloc);
627}
628
629void
630radv_CmdBlitImage2KHR(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR *pBlitImageInfo)
631{
632   RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
633   RADV_FROM_HANDLE(radv_image, src_image, pBlitImageInfo->srcImage);
634   RADV_FROM_HANDLE(radv_image, dst_image, pBlitImageInfo->dstImage);
635
636   for (unsigned r = 0; r < pBlitImageInfo->regionCount; r++) {
637      blit_image(cmd_buffer, src_image, pBlitImageInfo->srcImageLayout, dst_image,
638                 pBlitImageInfo->dstImageLayout, &pBlitImageInfo->pRegions[r],
639                 pBlitImageInfo->filter);
640   }
641}
642
643void
644radv_device_finish_meta_blit_state(struct radv_device *device)
645{
646   struct radv_meta_state *state = &device->meta_state;
647
648   for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
649      for (unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
650         radv_DestroyRenderPass(radv_device_to_handle(device), state->blit.render_pass[i][j],
651                                &state->alloc);
652      }
653      radv_DestroyPipeline(radv_device_to_handle(device), state->blit.pipeline_1d_src[i],
654                           &state->alloc);
655      radv_DestroyPipeline(radv_device_to_handle(device), state->blit.pipeline_2d_src[i],
656                           &state->alloc);
657      radv_DestroyPipeline(radv_device_to_handle(device), state->blit.pipeline_3d_src[i],
658                           &state->alloc);
659   }
660
661   for (enum radv_blit_ds_layout i = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; i < RADV_BLIT_DS_LAYOUT_COUNT;
662        i++) {
663      radv_DestroyRenderPass(radv_device_to_handle(device), state->blit.depth_only_rp[i],
664                             &state->alloc);
665      radv_DestroyRenderPass(radv_device_to_handle(device), state->blit.stencil_only_rp[i],
666                             &state->alloc);
667   }
668
669   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.depth_only_1d_pipeline,
670                        &state->alloc);
671   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.depth_only_2d_pipeline,
672                        &state->alloc);
673   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.depth_only_3d_pipeline,
674                        &state->alloc);
675
676   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.stencil_only_1d_pipeline,
677                        &state->alloc);
678   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.stencil_only_2d_pipeline,
679                        &state->alloc);
680   radv_DestroyPipeline(radv_device_to_handle(device), state->blit.stencil_only_3d_pipeline,
681                        &state->alloc);
682
683   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->blit.pipeline_layout,
684                              &state->alloc);
685   radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), state->blit.ds_layout,
686                                   &state->alloc);
687}
688
689static VkResult
690build_pipeline(struct radv_device *device, VkImageAspectFlagBits aspect,
691               enum glsl_sampler_dim tex_dim, unsigned fs_key, VkPipeline *pipeline)
692{
693   VkResult result = VK_SUCCESS;
694
695   mtx_lock(&device->meta_state.mtx);
696
697   if (*pipeline) {
698      mtx_unlock(&device->meta_state.mtx);
699      return VK_SUCCESS;
700   }
701
702   nir_shader *fs;
703   nir_shader *vs = build_nir_vertex_shader();
704   VkRenderPass rp;
705
706   switch (aspect) {
707   case VK_IMAGE_ASPECT_COLOR_BIT:
708      fs = build_nir_copy_fragment_shader(tex_dim);
709      rp = device->meta_state.blit.render_pass[fs_key][0];
710      break;
711   case VK_IMAGE_ASPECT_DEPTH_BIT:
712      fs = build_nir_copy_fragment_shader_depth(tex_dim);
713      rp = device->meta_state.blit.depth_only_rp[0];
714      break;
715   case VK_IMAGE_ASPECT_STENCIL_BIT:
716      fs = build_nir_copy_fragment_shader_stencil(tex_dim);
717      rp = device->meta_state.blit.stencil_only_rp[0];
718      break;
719   default:
720      unreachable("Unhandled aspect");
721   }
722   VkPipelineVertexInputStateCreateInfo vi_create_info = {
723      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
724      .vertexBindingDescriptionCount = 0,
725      .vertexAttributeDescriptionCount = 0,
726   };
727
728   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
729      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
730       .stage = VK_SHADER_STAGE_VERTEX_BIT,
731       .module = vk_shader_module_handle_from_nir(vs),
732       .pName = "main",
733       .pSpecializationInfo = NULL},
734      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
735       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
736       .module = vk_shader_module_handle_from_nir(fs),
737       .pName = "main",
738       .pSpecializationInfo = NULL},
739   };
740
741   VkGraphicsPipelineCreateInfo vk_pipeline_info = {
742      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
743      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
744      .pStages = pipeline_shader_stages,
745      .pVertexInputState = &vi_create_info,
746      .pInputAssemblyState =
747         &(VkPipelineInputAssemblyStateCreateInfo){
748            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
749            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
750            .primitiveRestartEnable = false,
751         },
752      .pViewportState =
753         &(VkPipelineViewportStateCreateInfo){
754            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
755            .viewportCount = 1,
756            .scissorCount = 1,
757         },
758      .pRasterizationState =
759         &(VkPipelineRasterizationStateCreateInfo){
760            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
761            .rasterizerDiscardEnable = false,
762            .polygonMode = VK_POLYGON_MODE_FILL,
763            .cullMode = VK_CULL_MODE_NONE,
764            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
765      .pMultisampleState =
766         &(VkPipelineMultisampleStateCreateInfo){
767            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
768            .rasterizationSamples = 1,
769            .sampleShadingEnable = false,
770            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
771         },
772      .pDynamicState =
773         &(VkPipelineDynamicStateCreateInfo){
774            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
775            .dynamicStateCount = 4,
776            .pDynamicStates =
777               (VkDynamicState[]){
778                  VK_DYNAMIC_STATE_VIEWPORT,
779                  VK_DYNAMIC_STATE_SCISSOR,
780                  VK_DYNAMIC_STATE_LINE_WIDTH,
781                  VK_DYNAMIC_STATE_BLEND_CONSTANTS,
782               },
783         },
784      .flags = 0,
785      .layout = device->meta_state.blit.pipeline_layout,
786      .renderPass = rp,
787      .subpass = 0,
788   };
789
790   VkPipelineColorBlendStateCreateInfo color_blend_info = {
791      .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
792      .attachmentCount = 1,
793      .pAttachments = (VkPipelineColorBlendAttachmentState[]){
794         {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |
795                            VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},
796      }};
797
798   VkPipelineDepthStencilStateCreateInfo depth_info = {
799      .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
800      .depthTestEnable = true,
801      .depthWriteEnable = true,
802      .depthCompareOp = VK_COMPARE_OP_ALWAYS,
803   };
804
805   VkPipelineDepthStencilStateCreateInfo stencil_info = {
806      .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
807      .depthTestEnable = false,
808      .depthWriteEnable = false,
809      .stencilTestEnable = true,
810      .front = {.failOp = VK_STENCIL_OP_REPLACE,
811                .passOp = VK_STENCIL_OP_REPLACE,
812                .depthFailOp = VK_STENCIL_OP_REPLACE,
813                .compareOp = VK_COMPARE_OP_ALWAYS,
814                .compareMask = 0xff,
815                .writeMask = 0xff,
816                .reference = 0},
817      .back = {.failOp = VK_STENCIL_OP_REPLACE,
818               .passOp = VK_STENCIL_OP_REPLACE,
819               .depthFailOp = VK_STENCIL_OP_REPLACE,
820               .compareOp = VK_COMPARE_OP_ALWAYS,
821               .compareMask = 0xff,
822               .writeMask = 0xff,
823               .reference = 0},
824      .depthCompareOp = VK_COMPARE_OP_ALWAYS,
825   };
826
827   switch (aspect) {
828   case VK_IMAGE_ASPECT_COLOR_BIT:
829      vk_pipeline_info.pColorBlendState = &color_blend_info;
830      break;
831   case VK_IMAGE_ASPECT_DEPTH_BIT:
832      vk_pipeline_info.pDepthStencilState = &depth_info;
833      break;
834   case VK_IMAGE_ASPECT_STENCIL_BIT:
835      vk_pipeline_info.pDepthStencilState = &stencil_info;
836      break;
837   default:
838      unreachable("Unhandled aspect");
839   }
840
841   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
842
843   result = radv_graphics_pipeline_create(
844      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
845      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, pipeline);
846   ralloc_free(vs);
847   ralloc_free(fs);
848   mtx_unlock(&device->meta_state.mtx);
849   return result;
850}
851
852static VkResult
853radv_device_init_meta_blit_color(struct radv_device *device, bool on_demand)
854{
855   VkResult result;
856
857   for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
858      unsigned key = radv_format_meta_fs_key(device, radv_fs_key_format_exemplars[i]);
859      for (unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
860         VkImageLayout layout = radv_meta_dst_layout_to_layout(j);
861         result = radv_CreateRenderPass2(
862            radv_device_to_handle(device),
863            &(VkRenderPassCreateInfo2){
864               .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
865               .attachmentCount = 1,
866               .pAttachments =
867                  &(VkAttachmentDescription2){
868                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
869                     .format = radv_fs_key_format_exemplars[i],
870                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
871                     .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
872                     .initialLayout = layout,
873                     .finalLayout = layout,
874                  },
875               .subpassCount = 1,
876               .pSubpasses =
877                  &(VkSubpassDescription2){
878                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
879                     .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
880                     .inputAttachmentCount = 0,
881                     .colorAttachmentCount = 1,
882                     .pColorAttachments =
883                        &(VkAttachmentReference2){
884                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
885                           .attachment = 0,
886                           .layout = layout,
887                        },
888                     .pResolveAttachments = NULL,
889                     .pDepthStencilAttachment =
890                        &(VkAttachmentReference2){
891                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
892                           .attachment = VK_ATTACHMENT_UNUSED,
893                           .layout = VK_IMAGE_LAYOUT_GENERAL,
894                        },
895                     .preserveAttachmentCount = 0,
896                     .pPreserveAttachments = NULL,
897                  },
898               .dependencyCount = 2,
899               .pDependencies =
900                  (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
901                                            .srcSubpass = VK_SUBPASS_EXTERNAL,
902                                            .dstSubpass = 0,
903                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
904                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
905                                            .srcAccessMask = 0,
906                                            .dstAccessMask = 0,
907                                            .dependencyFlags = 0},
908                                           {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
909                                            .srcSubpass = 0,
910                                            .dstSubpass = VK_SUBPASS_EXTERNAL,
911                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
912                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
913                                            .srcAccessMask = 0,
914                                            .dstAccessMask = 0,
915                                            .dependencyFlags = 0}},
916            },
917            &device->meta_state.alloc, &device->meta_state.blit.render_pass[key][j]);
918         if (result != VK_SUCCESS)
919            goto fail;
920      }
921
922      if (on_demand)
923         continue;
924
925      result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_1D, key,
926                              &device->meta_state.blit.pipeline_1d_src[key]);
927      if (result != VK_SUCCESS)
928         goto fail;
929
930      result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_2D, key,
931                              &device->meta_state.blit.pipeline_2d_src[key]);
932      if (result != VK_SUCCESS)
933         goto fail;
934
935      result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_3D, key,
936                              &device->meta_state.blit.pipeline_3d_src[key]);
937      if (result != VK_SUCCESS)
938         goto fail;
939   }
940
941   result = VK_SUCCESS;
942fail:
943   return result;
944}
945
946static VkResult
947radv_device_init_meta_blit_depth(struct radv_device *device, bool on_demand)
948{
949   VkResult result;
950
951   for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
952        ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
953      VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
954      result = radv_CreateRenderPass2(
955         radv_device_to_handle(device),
956         &(VkRenderPassCreateInfo2){
957            .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
958            .attachmentCount = 1,
959            .pAttachments =
960               &(VkAttachmentDescription2){
961                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
962                  .format = VK_FORMAT_D32_SFLOAT,
963                  .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
964                  .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
965                  .initialLayout = layout,
966                  .finalLayout = layout,
967               },
968            .subpassCount = 1,
969            .pSubpasses =
970               &(VkSubpassDescription2){
971                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
972                  .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
973                  .inputAttachmentCount = 0,
974                  .colorAttachmentCount = 0,
975                  .pColorAttachments = NULL,
976                  .pResolveAttachments = NULL,
977                  .pDepthStencilAttachment =
978                     &(VkAttachmentReference2){
979                        .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
980                        .attachment = 0,
981                        .layout = layout,
982                     },
983                  .preserveAttachmentCount = 0,
984                  .pPreserveAttachments = NULL,
985               },
986            .dependencyCount = 2,
987            .pDependencies =
988               (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
989                                         .srcSubpass = VK_SUBPASS_EXTERNAL,
990                                         .dstSubpass = 0,
991                                         .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
992                                         .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
993                                         .srcAccessMask = 0,
994                                         .dstAccessMask = 0,
995                                         .dependencyFlags = 0},
996                                        {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
997                                         .srcSubpass = 0,
998                                         .dstSubpass = VK_SUBPASS_EXTERNAL,
999                                         .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1000                                         .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1001                                         .srcAccessMask = 0,
1002                                         .dstAccessMask = 0,
1003                                         .dependencyFlags = 0}},
1004         },
1005         &device->meta_state.alloc, &device->meta_state.blit.depth_only_rp[ds_layout]);
1006      if (result != VK_SUCCESS)
1007         goto fail;
1008   }
1009
1010   if (on_demand)
1011      return VK_SUCCESS;
1012
1013   result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_1D, 0,
1014                           &device->meta_state.blit.depth_only_1d_pipeline);
1015   if (result != VK_SUCCESS)
1016      goto fail;
1017
1018   result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_2D, 0,
1019                           &device->meta_state.blit.depth_only_2d_pipeline);
1020   if (result != VK_SUCCESS)
1021      goto fail;
1022
1023   result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_3D, 0,
1024                           &device->meta_state.blit.depth_only_3d_pipeline);
1025   if (result != VK_SUCCESS)
1026      goto fail;
1027
1028fail:
1029   return result;
1030}
1031
1032static VkResult
1033radv_device_init_meta_blit_stencil(struct radv_device *device, bool on_demand)
1034{
1035   VkResult result;
1036
1037   for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
1038        ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
1039      VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
1040      result = radv_CreateRenderPass2(
1041         radv_device_to_handle(device),
1042         &(VkRenderPassCreateInfo2){
1043            .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
1044            .attachmentCount = 1,
1045            .pAttachments =
1046               &(VkAttachmentDescription2){
1047                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
1048                  .format = VK_FORMAT_S8_UINT,
1049                  .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1050                  .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1051                  .initialLayout = layout,
1052                  .finalLayout = layout,
1053               },
1054            .subpassCount = 1,
1055            .pSubpasses =
1056               &(VkSubpassDescription2){
1057                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
1058                  .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1059                  .inputAttachmentCount = 0,
1060                  .colorAttachmentCount = 0,
1061                  .pColorAttachments = NULL,
1062                  .pResolveAttachments = NULL,
1063                  .pDepthStencilAttachment =
1064                     &(VkAttachmentReference2){
1065                        .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
1066                        .attachment = 0,
1067                        .layout = layout,
1068                     },
1069                  .preserveAttachmentCount = 0,
1070                  .pPreserveAttachments = NULL,
1071               },
1072            .dependencyCount = 2,
1073            .pDependencies =
1074               (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
1075                                         .srcSubpass = VK_SUBPASS_EXTERNAL,
1076                                         .dstSubpass = 0,
1077                                         .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1078                                         .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1079                                         .srcAccessMask = 0,
1080                                         .dstAccessMask = 0,
1081                                         .dependencyFlags = 0},
1082                                        {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
1083                                         .srcSubpass = 0,
1084                                         .dstSubpass = VK_SUBPASS_EXTERNAL,
1085                                         .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1086                                         .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1087                                         .srcAccessMask = 0,
1088                                         .dstAccessMask = 0,
1089                                         .dependencyFlags = 0}},
1090
1091         },
1092         &device->meta_state.alloc, &device->meta_state.blit.stencil_only_rp[ds_layout]);
1093   }
1094   if (result != VK_SUCCESS)
1095      goto fail;
1096
1097   if (on_demand)
1098      return VK_SUCCESS;
1099
1100   result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_1D, 0,
1101                           &device->meta_state.blit.stencil_only_1d_pipeline);
1102   if (result != VK_SUCCESS)
1103      goto fail;
1104
1105   result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_2D, 0,
1106                           &device->meta_state.blit.stencil_only_2d_pipeline);
1107   if (result != VK_SUCCESS)
1108      goto fail;
1109
1110   result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_3D, 0,
1111                           &device->meta_state.blit.stencil_only_3d_pipeline);
1112   if (result != VK_SUCCESS)
1113      goto fail;
1114
1115fail:
1116   return result;
1117}
1118
1119VkResult
1120radv_device_init_meta_blit_state(struct radv_device *device, bool on_demand)
1121{
1122   VkResult result;
1123
1124   VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1125      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1126      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1127      .bindingCount = 1,
1128      .pBindings = (VkDescriptorSetLayoutBinding[]){
1129         {.binding = 0,
1130          .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1131          .descriptorCount = 1,
1132          .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1133          .pImmutableSamplers = NULL},
1134      }};
1135   result =
1136      radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_layout_info,
1137                                     &device->meta_state.alloc, &device->meta_state.blit.ds_layout);
1138   if (result != VK_SUCCESS)
1139      goto fail;
1140
1141   const VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 20};
1142
1143   result = radv_CreatePipelineLayout(radv_device_to_handle(device),
1144                                      &(VkPipelineLayoutCreateInfo){
1145                                         .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1146                                         .setLayoutCount = 1,
1147                                         .pSetLayouts = &device->meta_state.blit.ds_layout,
1148                                         .pushConstantRangeCount = 1,
1149                                         .pPushConstantRanges = &push_constant_range,
1150                                      },
1151                                      &device->meta_state.alloc,
1152                                      &device->meta_state.blit.pipeline_layout);
1153   if (result != VK_SUCCESS)
1154      goto fail;
1155
1156   result = radv_device_init_meta_blit_color(device, on_demand);
1157   if (result != VK_SUCCESS)
1158      goto fail;
1159
1160   result = radv_device_init_meta_blit_depth(device, on_demand);
1161   if (result != VK_SUCCESS)
1162      goto fail;
1163
1164   result = radv_device_init_meta_blit_stencil(device, on_demand);
1165
1166fail:
1167   if (result != VK_SUCCESS)
1168      radv_device_finish_meta_blit_state(device);
1169   return result;
1170}
1171