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