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