radv: Don't take absolute value of unsigned type.
[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 VkOffset3D src_offset_0,
303 VkOffset3D src_offset_1,
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 (float)src_offset_0.x / (float)src_width,
323 (float)src_offset_0.y / (float)src_height,
324 (float)src_offset_1.x / (float)src_width,
325 (float)src_offset_1.y / (float)src_height,
326 (float)src_offset_0.z / (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 + 1 - src_start) /
603 (float)(dst_end + 1 - dst_start);
604
605 if (flip_z) {
606 src_start = src_end;
607 src_z_step *= -1;
608 }
609
610 unsigned src_x0 = pRegions[r].srcOffsets[0].x;
611 unsigned src_x1 = pRegions[r].srcOffsets[1].x;
612 unsigned dst_x0 = pRegions[r].dstOffsets[0].x;
613 unsigned dst_x1 = pRegions[r].dstOffsets[1].x;
614
615 unsigned src_y0 = pRegions[r].srcOffsets[0].y;
616 unsigned src_y1 = pRegions[r].srcOffsets[1].y;
617 unsigned dst_y0 = pRegions[r].dstOffsets[0].y;
618 unsigned dst_y1 = pRegions[r].dstOffsets[1].y;
619
620 VkRect2D dest_box;
621 dest_box.offset.x = MIN2(dst_x0, dst_x1);
622 dest_box.offset.y = MIN2(dst_y0, dst_y1);
623 dest_box.extent.width = dst_x1 - dst_x0;
624 dest_box.extent.height = dst_y1 - dst_y0;
625
626 const unsigned num_layers = dst_end - dst_start;
627 for (unsigned i = 0; i < num_layers; i++) {
628 struct radv_image_view dest_iview, src_iview;
629
630 const VkOffset2D dest_offset_0 = {
631 .x = dst_x0,
632 .y = dst_y0,
633 };
634 const VkOffset2D dest_offset_1 = {
635 .x = dst_x1,
636 .y = dst_y1,
637 };
638 VkOffset3D src_offset_0 = {
639 .x = src_x0,
640 .y = src_y0,
641 .z = src_start + i * src_z_step,
642 };
643 VkOffset3D src_offset_1 = {
644 .x = src_x1,
645 .y = src_y1,
646 .z = src_start + i * src_z_step,
647 };
648 const uint32_t dest_array_slice = dst_start + i;
649
650 /* 3D images have just 1 layer */
651 const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
652
653 radv_image_view_init(&dest_iview, cmd_buffer->device,
654 &(VkImageViewCreateInfo) {
655 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
656 .image = destImage,
657 .viewType = radv_meta_get_view_type(dest_image),
658 .format = dest_image->vk_format,
659 .subresourceRange = {
660 .aspectMask = dst_res->aspectMask,
661 .baseMipLevel = dst_res->mipLevel,
662 .levelCount = 1,
663 .baseArrayLayer = dest_array_slice,
664 .layerCount = 1
665 },
666 }, NULL);
667 radv_image_view_init(&src_iview, cmd_buffer->device,
668 &(VkImageViewCreateInfo) {
669 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
670 .image = srcImage,
671 .viewType = radv_meta_get_view_type(src_image),
672 .format = src_image->vk_format,
673 .subresourceRange = {
674 .aspectMask = src_res->aspectMask,
675 .baseMipLevel = src_res->mipLevel,
676 .levelCount = 1,
677 .baseArrayLayer = src_array_slice,
678 .layerCount = 1
679 },
680 }, NULL);
681 meta_emit_blit(cmd_buffer,
682 src_image, &src_iview, srcImageLayout,
683 src_offset_0, src_offset_1,
684 dest_image, &dest_iview, destImageLayout,
685 dest_offset_0, dest_offset_1,
686 dest_box,
687 sampler);
688 }
689 }
690
691 /* Restore conditional rendering. */
692 cmd_buffer->state.predicating = old_predicating;
693
694 radv_meta_restore(&saved_state, cmd_buffer);
695
696 radv_DestroySampler(radv_device_to_handle(device), sampler,
697 &cmd_buffer->pool->alloc);
698 }
699
700 void
701 radv_device_finish_meta_blit_state(struct radv_device *device)
702 {
703 struct radv_meta_state *state = &device->meta_state;
704
705 for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
706 for (unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
707 radv_DestroyRenderPass(radv_device_to_handle(device),
708 state->blit.render_pass[i][j],
709 &state->alloc);
710 }
711 radv_DestroyPipeline(radv_device_to_handle(device),
712 state->blit.pipeline_1d_src[i],
713 &state->alloc);
714 radv_DestroyPipeline(radv_device_to_handle(device),
715 state->blit.pipeline_2d_src[i],
716 &state->alloc);
717 radv_DestroyPipeline(radv_device_to_handle(device),
718 state->blit.pipeline_3d_src[i],
719 &state->alloc);
720 }
721
722 for (enum radv_blit_ds_layout i = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; i < RADV_BLIT_DS_LAYOUT_COUNT; i++) {
723 radv_DestroyRenderPass(radv_device_to_handle(device),
724 state->blit.depth_only_rp[i], &state->alloc);
725 radv_DestroyRenderPass(radv_device_to_handle(device),
726 state->blit.stencil_only_rp[i], &state->alloc);
727 }
728
729 radv_DestroyPipeline(radv_device_to_handle(device),
730 state->blit.depth_only_1d_pipeline, &state->alloc);
731 radv_DestroyPipeline(radv_device_to_handle(device),
732 state->blit.depth_only_2d_pipeline, &state->alloc);
733 radv_DestroyPipeline(radv_device_to_handle(device),
734 state->blit.depth_only_3d_pipeline, &state->alloc);
735
736 radv_DestroyPipeline(radv_device_to_handle(device),
737 state->blit.stencil_only_1d_pipeline,
738 &state->alloc);
739 radv_DestroyPipeline(radv_device_to_handle(device),
740 state->blit.stencil_only_2d_pipeline,
741 &state->alloc);
742 radv_DestroyPipeline(radv_device_to_handle(device),
743 state->blit.stencil_only_3d_pipeline,
744 &state->alloc);
745
746
747 radv_DestroyPipelineLayout(radv_device_to_handle(device),
748 state->blit.pipeline_layout, &state->alloc);
749 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
750 state->blit.ds_layout, &state->alloc);
751 }
752
753 static VkResult
754 build_pipeline(struct radv_device *device,
755 VkImageAspectFlagBits aspect,
756 enum glsl_sampler_dim tex_dim,
757 unsigned fs_key,
758 VkPipeline *pipeline)
759 {
760 VkResult result = VK_SUCCESS;
761
762 mtx_lock(&device->meta_state.mtx);
763
764 if (*pipeline) {
765 mtx_unlock(&device->meta_state.mtx);
766 return VK_SUCCESS;
767 }
768
769 struct radv_shader_module fs = {0};
770 struct radv_shader_module vs = {.nir = build_nir_vertex_shader()};
771 VkRenderPass rp;
772
773 switch(aspect) {
774 case VK_IMAGE_ASPECT_COLOR_BIT:
775 fs.nir = build_nir_copy_fragment_shader(tex_dim);
776 rp = device->meta_state.blit.render_pass[fs_key][0];
777 break;
778 case VK_IMAGE_ASPECT_DEPTH_BIT:
779 fs.nir = build_nir_copy_fragment_shader_depth(tex_dim);
780 rp = device->meta_state.blit.depth_only_rp[0];
781 break;
782 case VK_IMAGE_ASPECT_STENCIL_BIT:
783 fs.nir = build_nir_copy_fragment_shader_stencil(tex_dim);
784 rp = device->meta_state.blit.stencil_only_rp[0];
785 break;
786 default:
787 unreachable("Unhandled aspect");
788 }
789 VkPipelineVertexInputStateCreateInfo vi_create_info = {
790 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
791 .vertexBindingDescriptionCount = 0,
792 .vertexAttributeDescriptionCount = 0,
793 };
794
795 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
796 {
797 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
798 .stage = VK_SHADER_STAGE_VERTEX_BIT,
799 .module = radv_shader_module_to_handle(&vs),
800 .pName = "main",
801 .pSpecializationInfo = NULL
802 }, {
803 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
804 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
805 .module = radv_shader_module_to_handle(&fs),
806 .pName = "main",
807 .pSpecializationInfo = NULL
808 },
809 };
810
811 VkGraphicsPipelineCreateInfo vk_pipeline_info = {
812 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
813 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
814 .pStages = pipeline_shader_stages,
815 .pVertexInputState = &vi_create_info,
816 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
817 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
818 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
819 .primitiveRestartEnable = false,
820 },
821 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
822 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
823 .viewportCount = 1,
824 .scissorCount = 1,
825 },
826 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
827 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
828 .rasterizerDiscardEnable = false,
829 .polygonMode = VK_POLYGON_MODE_FILL,
830 .cullMode = VK_CULL_MODE_NONE,
831 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
832 },
833 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
834 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
835 .rasterizationSamples = 1,
836 .sampleShadingEnable = false,
837 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
838 },
839 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
840 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
841 .dynamicStateCount = 4,
842 .pDynamicStates = (VkDynamicState[]) {
843 VK_DYNAMIC_STATE_VIEWPORT,
844 VK_DYNAMIC_STATE_SCISSOR,
845 VK_DYNAMIC_STATE_LINE_WIDTH,
846 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
847 },
848 },
849 .flags = 0,
850 .layout = device->meta_state.blit.pipeline_layout,
851 .renderPass = rp,
852 .subpass = 0,
853 };
854
855 VkPipelineColorBlendStateCreateInfo color_blend_info = {
856 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
857 .attachmentCount = 1,
858 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
859 {
860 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
861 VK_COLOR_COMPONENT_R_BIT |
862 VK_COLOR_COMPONENT_G_BIT |
863 VK_COLOR_COMPONENT_B_BIT },
864 }
865 };
866
867 VkPipelineDepthStencilStateCreateInfo depth_info = {
868 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
869 .depthTestEnable = true,
870 .depthWriteEnable = true,
871 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
872 };
873
874 VkPipelineDepthStencilStateCreateInfo stencil_info = {
875 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
876 .depthTestEnable = false,
877 .depthWriteEnable = false,
878 .stencilTestEnable = true,
879 .front = {
880 .failOp = VK_STENCIL_OP_REPLACE,
881 .passOp = VK_STENCIL_OP_REPLACE,
882 .depthFailOp = VK_STENCIL_OP_REPLACE,
883 .compareOp = VK_COMPARE_OP_ALWAYS,
884 .compareMask = 0xff,
885 .writeMask = 0xff,
886 .reference = 0
887 },
888 .back = {
889 .failOp = VK_STENCIL_OP_REPLACE,
890 .passOp = VK_STENCIL_OP_REPLACE,
891 .depthFailOp = VK_STENCIL_OP_REPLACE,
892 .compareOp = VK_COMPARE_OP_ALWAYS,
893 .compareMask = 0xff,
894 .writeMask = 0xff,
895 .reference = 0
896 },
897 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
898 };
899
900 switch(aspect) {
901 case VK_IMAGE_ASPECT_COLOR_BIT:
902 vk_pipeline_info.pColorBlendState = &color_blend_info;
903 break;
904 case VK_IMAGE_ASPECT_DEPTH_BIT:
905 vk_pipeline_info.pDepthStencilState = &depth_info;
906 break;
907 case VK_IMAGE_ASPECT_STENCIL_BIT:
908 vk_pipeline_info.pDepthStencilState = &stencil_info;
909 break;
910 default:
911 unreachable("Unhandled aspect");
912 }
913
914 const struct radv_graphics_pipeline_create_info radv_pipeline_info = {
915 .use_rectlist = true
916 };
917
918 result = radv_graphics_pipeline_create(radv_device_to_handle(device),
919 radv_pipeline_cache_to_handle(&device->meta_state.cache),
920 &vk_pipeline_info, &radv_pipeline_info,
921 &device->meta_state.alloc, pipeline);
922 ralloc_free(vs.nir);
923 ralloc_free(fs.nir);
924 mtx_unlock(&device->meta_state.mtx);
925 return result;
926 }
927
928 static VkResult
929 radv_device_init_meta_blit_color(struct radv_device *device, bool on_demand)
930 {
931 VkResult result;
932
933 for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
934 unsigned key = radv_format_meta_fs_key(radv_fs_key_format_exemplars[i]);
935 for(unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
936 VkImageLayout layout = radv_meta_dst_layout_to_layout(j);
937 result = radv_CreateRenderPass(radv_device_to_handle(device),
938 &(VkRenderPassCreateInfo) {
939 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
940 .attachmentCount = 1,
941 .pAttachments = &(VkAttachmentDescription) {
942 .format = radv_fs_key_format_exemplars[i],
943 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
944 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
945 .initialLayout = layout,
946 .finalLayout = layout,
947 },
948 .subpassCount = 1,
949 .pSubpasses = &(VkSubpassDescription) {
950 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
951 .inputAttachmentCount = 0,
952 .colorAttachmentCount = 1,
953 .pColorAttachments = &(VkAttachmentReference) {
954 .attachment = 0,
955 .layout = layout,
956 },
957 .pResolveAttachments = NULL,
958 .pDepthStencilAttachment = &(VkAttachmentReference) {
959 .attachment = VK_ATTACHMENT_UNUSED,
960 .layout = VK_IMAGE_LAYOUT_GENERAL,
961 },
962 .preserveAttachmentCount = 0,
963 .pPreserveAttachments = NULL,
964 },
965 .dependencyCount = 2,
966 .pDependencies = (VkSubpassDependency[]) {
967 {
968 .srcSubpass = VK_SUBPASS_EXTERNAL,
969 .dstSubpass = 0,
970 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
971 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
972 .srcAccessMask = 0,
973 .dstAccessMask = 0,
974 .dependencyFlags = 0
975 },
976 {
977 .srcSubpass = 0,
978 .dstSubpass = VK_SUBPASS_EXTERNAL,
979 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
980 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
981 .srcAccessMask = 0,
982 .dstAccessMask = 0,
983 .dependencyFlags = 0
984 }
985 },
986 }, &device->meta_state.alloc, &device->meta_state.blit.render_pass[key][j]);
987 if (result != VK_SUCCESS)
988 goto fail;
989 }
990
991 if (on_demand)
992 continue;
993
994 result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_1D, key, &device->meta_state.blit.pipeline_1d_src[key]);
995 if (result != VK_SUCCESS)
996 goto fail;
997
998 result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_2D, key, &device->meta_state.blit.pipeline_2d_src[key]);
999 if (result != VK_SUCCESS)
1000 goto fail;
1001
1002 result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_3D, key, &device->meta_state.blit.pipeline_3d_src[key]);
1003 if (result != VK_SUCCESS)
1004 goto fail;
1005
1006 }
1007
1008 result = VK_SUCCESS;
1009 fail:
1010 return result;
1011 }
1012
1013 static VkResult
1014 radv_device_init_meta_blit_depth(struct radv_device *device, bool on_demand)
1015 {
1016 VkResult result;
1017
1018 for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
1019 VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
1020 result = radv_CreateRenderPass(radv_device_to_handle(device),
1021 &(VkRenderPassCreateInfo) {
1022 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1023 .attachmentCount = 1,
1024 .pAttachments = &(VkAttachmentDescription) {
1025 .format = VK_FORMAT_D32_SFLOAT,
1026 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1027 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1028 .initialLayout = layout,
1029 .finalLayout = layout,
1030 },
1031 .subpassCount = 1,
1032 .pSubpasses = &(VkSubpassDescription) {
1033 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1034 .inputAttachmentCount = 0,
1035 .colorAttachmentCount = 0,
1036 .pColorAttachments = NULL,
1037 .pResolveAttachments = NULL,
1038 .pDepthStencilAttachment = &(VkAttachmentReference) {
1039 .attachment = 0,
1040 .layout = layout,
1041 },
1042 .preserveAttachmentCount = 0,
1043 .pPreserveAttachments = NULL,
1044 },
1045 .dependencyCount = 2,
1046 .pDependencies = (VkSubpassDependency[]) {
1047 {
1048 .srcSubpass = VK_SUBPASS_EXTERNAL,
1049 .dstSubpass = 0,
1050 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1051 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1052 .srcAccessMask = 0,
1053 .dstAccessMask = 0,
1054 .dependencyFlags = 0
1055 },
1056 {
1057 .srcSubpass = 0,
1058 .dstSubpass = VK_SUBPASS_EXTERNAL,
1059 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1060 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1061 .srcAccessMask = 0,
1062 .dstAccessMask = 0,
1063 .dependencyFlags = 0
1064 }
1065 },
1066 }, &device->meta_state.alloc, &device->meta_state.blit.depth_only_rp[ds_layout]);
1067 if (result != VK_SUCCESS)
1068 goto fail;
1069 }
1070
1071 if (on_demand)
1072 return VK_SUCCESS;
1073
1074 result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_1D, 0, &device->meta_state.blit.depth_only_1d_pipeline);
1075 if (result != VK_SUCCESS)
1076 goto fail;
1077
1078 result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_2D, 0, &device->meta_state.blit.depth_only_2d_pipeline);
1079 if (result != VK_SUCCESS)
1080 goto fail;
1081
1082 result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_3D, 0, &device->meta_state.blit.depth_only_3d_pipeline);
1083 if (result != VK_SUCCESS)
1084 goto fail;
1085
1086 fail:
1087 return result;
1088 }
1089
1090 static VkResult
1091 radv_device_init_meta_blit_stencil(struct radv_device *device, bool on_demand)
1092 {
1093 VkResult result;
1094
1095 for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
1096 VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
1097 result = radv_CreateRenderPass(radv_device_to_handle(device),
1098 &(VkRenderPassCreateInfo) {
1099 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1100 .attachmentCount = 1,
1101 .pAttachments = &(VkAttachmentDescription) {
1102 .format = VK_FORMAT_S8_UINT,
1103 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1104 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1105 .initialLayout = layout,
1106 .finalLayout = layout,
1107 },
1108 .subpassCount = 1,
1109 .pSubpasses = &(VkSubpassDescription) {
1110 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1111 .inputAttachmentCount = 0,
1112 .colorAttachmentCount = 0,
1113 .pColorAttachments = NULL,
1114 .pResolveAttachments = NULL,
1115 .pDepthStencilAttachment = &(VkAttachmentReference) {
1116 .attachment = 0,
1117 .layout = layout,
1118 },
1119 .preserveAttachmentCount = 0,
1120 .pPreserveAttachments = NULL,
1121 },
1122 .dependencyCount = 2,
1123 .pDependencies = (VkSubpassDependency[]) {
1124 {
1125 .srcSubpass = VK_SUBPASS_EXTERNAL,
1126 .dstSubpass = 0,
1127 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1128 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1129 .srcAccessMask = 0,
1130 .dstAccessMask = 0,
1131 .dependencyFlags = 0
1132 },
1133 {
1134 .srcSubpass = 0,
1135 .dstSubpass = VK_SUBPASS_EXTERNAL,
1136 .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1137 .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1138 .srcAccessMask = 0,
1139 .dstAccessMask = 0,
1140 .dependencyFlags = 0
1141 }
1142 },
1143
1144 }, &device->meta_state.alloc, &device->meta_state.blit.stencil_only_rp[ds_layout]);
1145 }
1146 if (result != VK_SUCCESS)
1147 goto fail;
1148
1149 if (on_demand)
1150 return VK_SUCCESS;
1151
1152 result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_1D, 0, &device->meta_state.blit.stencil_only_1d_pipeline);
1153 if (result != VK_SUCCESS)
1154 goto fail;
1155
1156 result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_2D, 0, &device->meta_state.blit.stencil_only_2d_pipeline);
1157 if (result != VK_SUCCESS)
1158 goto fail;
1159
1160 result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_3D, 0, &device->meta_state.blit.stencil_only_3d_pipeline);
1161 if (result != VK_SUCCESS)
1162 goto fail;
1163
1164
1165 fail:
1166 return result;
1167 }
1168
1169 VkResult
1170 radv_device_init_meta_blit_state(struct radv_device *device, bool on_demand)
1171 {
1172 VkResult result;
1173
1174 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1175 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1176 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1177 .bindingCount = 1,
1178 .pBindings = (VkDescriptorSetLayoutBinding[]) {
1179 {
1180 .binding = 0,
1181 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1182 .descriptorCount = 1,
1183 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1184 .pImmutableSamplers = NULL
1185 },
1186 }
1187 };
1188 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
1189 &ds_layout_info,
1190 &device->meta_state.alloc,
1191 &device->meta_state.blit.ds_layout);
1192 if (result != VK_SUCCESS)
1193 goto fail;
1194
1195 const VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 20};
1196
1197 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
1198 &(VkPipelineLayoutCreateInfo) {
1199 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1200 .setLayoutCount = 1,
1201 .pSetLayouts = &device->meta_state.blit.ds_layout,
1202 .pushConstantRangeCount = 1,
1203 .pPushConstantRanges = &push_constant_range,
1204 },
1205 &device->meta_state.alloc, &device->meta_state.blit.pipeline_layout);
1206 if (result != VK_SUCCESS)
1207 goto fail;
1208
1209 result = radv_device_init_meta_blit_color(device, on_demand);
1210 if (result != VK_SUCCESS)
1211 goto fail;
1212
1213 result = radv_device_init_meta_blit_depth(device, on_demand);
1214 if (result != VK_SUCCESS)
1215 goto fail;
1216
1217 result = radv_device_init_meta_blit_stencil(device, on_demand);
1218
1219 fail:
1220 if (result != VK_SUCCESS)
1221 radv_device_finish_meta_blit_state(device);
1222 return result;
1223 }