radv_meta_blit.c revision 01e04c3f
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
27struct blit_region {
28	VkOffset3D src_offset;
29	VkExtent3D src_extent;
30	VkOffset3D dest_offset;
31	VkExtent3D dest_extent;
32};
33
34static VkResult
35build_pipeline(struct radv_device *device,
36               VkImageAspectFlagBits aspect,
37               enum glsl_sampler_dim tex_dim,
38               unsigned fs_key,
39               VkPipeline *pipeline);
40
41static nir_shader *
42build_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
109static nir_shader *
110build_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), false);
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
167static nir_shader *
168build_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), false);
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
225static nir_shader *
226build_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), false);
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
283static enum glsl_sampler_dim
284translate_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
297static void
298meta_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_CmdBeginRenderPass(radv_cmd_buffer_to_handle(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						       }, VK_SUBPASS_CONTENTS_INLINE);
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_CmdBeginRenderPass(radv_cmd_buffer_to_handle(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						       }, VK_SUBPASS_CONTENTS_INLINE);
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_CmdBeginRenderPass(radv_cmd_buffer_to_handle(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						       }, VK_SUBPASS_CONTENTS_INLINE);
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	if (!*pipeline) {
443		VkResult ret = build_pipeline(device, src_iview->aspect_mask, translate_sampler_dim(src_image->type), fs_key, pipeline);
444		if (ret != VK_SUCCESS) {
445			cmd_buffer->record_result = ret;
446			goto fail_pipeline;
447		}
448	}
449
450	radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
451			     VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
452
453	radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
454			              device->meta_state.blit.pipeline_layout,
455				      0, /* set */
456				      1, /* descriptorWriteCount */
457				      (VkWriteDescriptorSet[]) {
458				              {
459				                      .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
460				                      .dstBinding = 0,
461				                      .dstArrayElement = 0,
462				                      .descriptorCount = 1,
463				                      .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
464				                      .pImageInfo = (VkDescriptorImageInfo[]) {
465				                              {
466				                                      .sampler = sampler,
467				                                      .imageView = radv_image_view_to_handle(src_iview),
468				                                      .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
469				                              },
470				                      }
471				              }
472				      });
473
474	radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
475		.x = dest_offset_0.x,
476		.y = dest_offset_0.y,
477		.width = dest_offset_1.x - dest_offset_0.x,
478		.height = dest_offset_1.y - dest_offset_0.y,
479		.minDepth = 0.0f,
480		.maxDepth = 1.0f
481	});
482
483	radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkRect2D) {
484		.offset = (VkOffset2D) { MIN2(dest_offset_0.x, dest_offset_1.x), MIN2(dest_offset_0.y, dest_offset_1.y) },
485		.extent = (VkExtent2D) {
486			abs(dest_offset_1.x - dest_offset_0.x),
487			abs(dest_offset_1.y - dest_offset_0.y)
488		},
489	});
490
491	radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
492
493fail_pipeline:
494	radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
495
496	/* At the point where we emit the draw call, all data from the
497	 * descriptor sets, etc. has been used.  We are free to delete it.
498	 */
499	/* TODO: above comment is not valid for at least descriptor sets/pools,
500	 * as we may not free them till after execution finishes. Check others. */
501
502	radv_DestroyFramebuffer(radv_device_to_handle(device), fb,
503				&cmd_buffer->pool->alloc);
504}
505
506static bool
507flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
508{
509	bool flip = false;
510	if (*src0 > *src1) {
511		unsigned tmp = *src0;
512		*src0 = *src1;
513		*src1 = tmp;
514		flip = !flip;
515	}
516
517	if (*dst0 > *dst1) {
518		unsigned tmp = *dst0;
519		*dst0 = *dst1;
520		*dst1 = tmp;
521		flip = !flip;
522	}
523	return flip;
524}
525
526void radv_CmdBlitImage(
527	VkCommandBuffer                             commandBuffer,
528	VkImage                                     srcImage,
529	VkImageLayout                               srcImageLayout,
530	VkImage                                     destImage,
531	VkImageLayout                               destImageLayout,
532	uint32_t                                    regionCount,
533	const VkImageBlit*                          pRegions,
534	VkFilter                                    filter)
535
536{
537	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
538	RADV_FROM_HANDLE(radv_image, src_image, srcImage);
539	RADV_FROM_HANDLE(radv_image, dest_image, destImage);
540	struct radv_device *device = cmd_buffer->device;
541	struct radv_meta_saved_state saved_state;
542	bool old_predicating;
543	VkSampler sampler;
544
545	/* From the Vulkan 1.0 spec:
546	 *
547	 *    vkCmdBlitImage must not be used for multisampled source or
548	 *    destination images. Use vkCmdResolveImage for this purpose.
549	 */
550	assert(src_image->info.samples == 1);
551	assert(dest_image->info.samples == 1);
552
553	radv_CreateSampler(radv_device_to_handle(device),
554			   &(VkSamplerCreateInfo) {
555				.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
556				.magFilter = filter,
557				.minFilter = filter,
558				.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
559				.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
560				.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
561			   }, &cmd_buffer->pool->alloc, &sampler);
562
563	radv_meta_save(&saved_state, cmd_buffer,
564		       RADV_META_SAVE_GRAPHICS_PIPELINE |
565		       RADV_META_SAVE_CONSTANTS |
566		       RADV_META_SAVE_DESCRIPTORS);
567
568	/* VK_EXT_conditional_rendering says that blit commands should not be
569	 * affected by conditional rendering.
570	 */
571	old_predicating = cmd_buffer->state.predicating;
572	cmd_buffer->state.predicating = false;
573
574	for (unsigned r = 0; r < regionCount; r++) {
575		const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource;
576		const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource;
577
578		unsigned dst_start, dst_end;
579		if (dest_image->type == VK_IMAGE_TYPE_3D) {
580			assert(dst_res->baseArrayLayer == 0);
581			dst_start = pRegions[r].dstOffsets[0].z;
582			dst_end = pRegions[r].dstOffsets[1].z;
583		} else {
584			dst_start = dst_res->baseArrayLayer;
585			dst_end = dst_start + dst_res->layerCount;
586		}
587
588		unsigned src_start, src_end;
589		if (src_image->type == VK_IMAGE_TYPE_3D) {
590			assert(src_res->baseArrayLayer == 0);
591			src_start = pRegions[r].srcOffsets[0].z;
592			src_end = pRegions[r].srcOffsets[1].z;
593		} else {
594			src_start = src_res->baseArrayLayer;
595			src_end = src_start + src_res->layerCount;
596		}
597
598		bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
599		float src_z_step = (float)(src_end + 1 - src_start) /
600			(float)(dst_end + 1 - dst_start);
601
602		if (flip_z) {
603			src_start = src_end;
604			src_z_step *= -1;
605		}
606
607		unsigned src_x0 = pRegions[r].srcOffsets[0].x;
608		unsigned src_x1 = pRegions[r].srcOffsets[1].x;
609		unsigned dst_x0 = pRegions[r].dstOffsets[0].x;
610		unsigned dst_x1 = pRegions[r].dstOffsets[1].x;
611
612		unsigned src_y0 = pRegions[r].srcOffsets[0].y;
613		unsigned src_y1 = pRegions[r].srcOffsets[1].y;
614		unsigned dst_y0 = pRegions[r].dstOffsets[0].y;
615		unsigned dst_y1 = pRegions[r].dstOffsets[1].y;
616
617		VkRect2D dest_box;
618		dest_box.offset.x = MIN2(dst_x0, dst_x1);
619		dest_box.offset.y = MIN2(dst_y0, dst_y1);
620		dest_box.extent.width = abs(dst_x1 - dst_x0);
621		dest_box.extent.height = abs(dst_y1 - dst_y0);
622
623		const unsigned num_layers = dst_end - dst_start;
624		for (unsigned i = 0; i < num_layers; i++) {
625			struct radv_image_view dest_iview, src_iview;
626
627			const VkOffset2D dest_offset_0 = {
628				.x = dst_x0,
629				.y = dst_y0,
630			};
631			const VkOffset2D dest_offset_1 = {
632				.x = dst_x1,
633				.y = dst_y1,
634			};
635			VkOffset3D src_offset_0 = {
636				.x = src_x0,
637				.y = src_y0,
638				.z = src_start + i * src_z_step,
639			};
640			VkOffset3D src_offset_1 = {
641				.x = src_x1,
642				.y = src_y1,
643				.z = src_start + i * src_z_step,
644			};
645			const uint32_t dest_array_slice = dst_start + i;
646
647			/* 3D images have just 1 layer */
648			const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
649
650			radv_image_view_init(&dest_iview, cmd_buffer->device,
651					     &(VkImageViewCreateInfo) {
652						     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
653							     .image = destImage,
654							     .viewType = radv_meta_get_view_type(dest_image),
655							     .format = dest_image->vk_format,
656							     .subresourceRange = {
657							     .aspectMask = dst_res->aspectMask,
658							     .baseMipLevel = dst_res->mipLevel,
659							     .levelCount = 1,
660							     .baseArrayLayer = dest_array_slice,
661							     .layerCount = 1
662						     },
663					     });
664			radv_image_view_init(&src_iview, cmd_buffer->device,
665					     &(VkImageViewCreateInfo) {
666						.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
667							.image = srcImage,
668							.viewType = radv_meta_get_view_type(src_image),
669							.format = src_image->vk_format,
670							.subresourceRange = {
671							.aspectMask = src_res->aspectMask,
672							.baseMipLevel = src_res->mipLevel,
673							.levelCount = 1,
674							.baseArrayLayer = src_array_slice,
675							.layerCount = 1
676						},
677					});
678			meta_emit_blit(cmd_buffer,
679				       src_image, &src_iview, srcImageLayout,
680				       src_offset_0, src_offset_1,
681				       dest_image, &dest_iview, destImageLayout,
682				       dest_offset_0, dest_offset_1,
683				       dest_box,
684				       sampler);
685		}
686	}
687
688	/* Restore conditional rendering. */
689	cmd_buffer->state.predicating = old_predicating;
690
691	radv_meta_restore(&saved_state, cmd_buffer);
692
693	radv_DestroySampler(radv_device_to_handle(device), sampler,
694			    &cmd_buffer->pool->alloc);
695}
696
697void
698radv_device_finish_meta_blit_state(struct radv_device *device)
699{
700	struct radv_meta_state *state = &device->meta_state;
701
702	for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
703		for (unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
704			radv_DestroyRenderPass(radv_device_to_handle(device),
705			                       state->blit.render_pass[i][j],
706			                       &state->alloc);
707		}
708		radv_DestroyPipeline(radv_device_to_handle(device),
709				     state->blit.pipeline_1d_src[i],
710				     &state->alloc);
711		radv_DestroyPipeline(radv_device_to_handle(device),
712				     state->blit.pipeline_2d_src[i],
713				     &state->alloc);
714		radv_DestroyPipeline(radv_device_to_handle(device),
715				     state->blit.pipeline_3d_src[i],
716				     &state->alloc);
717	}
718
719	for (enum radv_blit_ds_layout i = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; i < RADV_BLIT_DS_LAYOUT_COUNT; i++) {
720		radv_DestroyRenderPass(radv_device_to_handle(device),
721				       state->blit.depth_only_rp[i], &state->alloc);
722		radv_DestroyRenderPass(radv_device_to_handle(device),
723				       state->blit.stencil_only_rp[i], &state->alloc);
724	}
725
726	radv_DestroyPipeline(radv_device_to_handle(device),
727			     state->blit.depth_only_1d_pipeline, &state->alloc);
728	radv_DestroyPipeline(radv_device_to_handle(device),
729			     state->blit.depth_only_2d_pipeline, &state->alloc);
730	radv_DestroyPipeline(radv_device_to_handle(device),
731			     state->blit.depth_only_3d_pipeline, &state->alloc);
732
733	radv_DestroyPipeline(radv_device_to_handle(device),
734			     state->blit.stencil_only_1d_pipeline,
735			     &state->alloc);
736	radv_DestroyPipeline(radv_device_to_handle(device),
737			     state->blit.stencil_only_2d_pipeline,
738			     &state->alloc);
739	radv_DestroyPipeline(radv_device_to_handle(device),
740			     state->blit.stencil_only_3d_pipeline,
741			     &state->alloc);
742
743
744	radv_DestroyPipelineLayout(radv_device_to_handle(device),
745				   state->blit.pipeline_layout, &state->alloc);
746	radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
747					state->blit.ds_layout, &state->alloc);
748}
749
750static VkResult
751build_pipeline(struct radv_device *device,
752               VkImageAspectFlagBits aspect,
753               enum glsl_sampler_dim tex_dim,
754               unsigned fs_key,
755               VkPipeline *pipeline)
756{
757	VkResult result = VK_SUCCESS;
758
759	mtx_lock(&device->meta_state.mtx);
760
761	if (*pipeline) {
762		mtx_unlock(&device->meta_state.mtx);
763		return VK_SUCCESS;
764	}
765
766	struct radv_shader_module fs = {0};
767	struct radv_shader_module vs = {.nir = build_nir_vertex_shader()};
768	VkRenderPass rp;
769
770	switch(aspect) {
771	case VK_IMAGE_ASPECT_COLOR_BIT:
772		fs.nir = build_nir_copy_fragment_shader(tex_dim);
773		rp = device->meta_state.blit.render_pass[fs_key][0];
774		break;
775	case VK_IMAGE_ASPECT_DEPTH_BIT:
776		fs.nir = build_nir_copy_fragment_shader_depth(tex_dim);
777		rp = device->meta_state.blit.depth_only_rp[0];
778		break;
779	case VK_IMAGE_ASPECT_STENCIL_BIT:
780		fs.nir = build_nir_copy_fragment_shader_stencil(tex_dim);
781		rp = device->meta_state.blit.stencil_only_rp[0];
782		break;
783	default:
784		unreachable("Unhandled aspect");
785	}
786	VkPipelineVertexInputStateCreateInfo vi_create_info = {
787		.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
788		.vertexBindingDescriptionCount = 0,
789		.vertexAttributeDescriptionCount = 0,
790	};
791
792	VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
793		{
794			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
795			.stage = VK_SHADER_STAGE_VERTEX_BIT,
796			.module = radv_shader_module_to_handle(&vs),
797			.pName = "main",
798			.pSpecializationInfo = NULL
799		}, {
800			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
801			.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
802			.module = radv_shader_module_to_handle(&fs),
803			.pName = "main",
804			.pSpecializationInfo = NULL
805		},
806	};
807
808	VkGraphicsPipelineCreateInfo vk_pipeline_info = {
809		.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
810		.stageCount = ARRAY_SIZE(pipeline_shader_stages),
811		.pStages = pipeline_shader_stages,
812		.pVertexInputState = &vi_create_info,
813		.pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
814			.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
815			.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
816			.primitiveRestartEnable = false,
817		},
818		.pViewportState = &(VkPipelineViewportStateCreateInfo) {
819			.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
820			.viewportCount = 1,
821			.scissorCount = 1,
822		},
823		.pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
824			.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
825			.rasterizerDiscardEnable = false,
826			.polygonMode = VK_POLYGON_MODE_FILL,
827			.cullMode = VK_CULL_MODE_NONE,
828			.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
829		},
830		.pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
831			.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
832			.rasterizationSamples = 1,
833			.sampleShadingEnable = false,
834			.pSampleMask = (VkSampleMask[]) { UINT32_MAX },
835		},
836		.pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
837			.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
838			.dynamicStateCount = 4,
839			.pDynamicStates = (VkDynamicState[]) {
840				VK_DYNAMIC_STATE_VIEWPORT,
841				VK_DYNAMIC_STATE_SCISSOR,
842				VK_DYNAMIC_STATE_LINE_WIDTH,
843				VK_DYNAMIC_STATE_BLEND_CONSTANTS,
844			},
845		},
846		.flags = 0,
847		.layout = device->meta_state.blit.pipeline_layout,
848		.renderPass = rp,
849		.subpass = 0,
850	};
851
852	VkPipelineColorBlendStateCreateInfo color_blend_info = {
853		.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
854		.attachmentCount = 1,
855		.pAttachments = (VkPipelineColorBlendAttachmentState []) {
856			{
857				.colorWriteMask = VK_COLOR_COMPONENT_A_BIT |
858						  VK_COLOR_COMPONENT_R_BIT |
859						  VK_COLOR_COMPONENT_G_BIT |
860						  VK_COLOR_COMPONENT_B_BIT },
861			}
862		};
863
864	VkPipelineDepthStencilStateCreateInfo depth_info = {
865		.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
866		.depthTestEnable = true,
867		.depthWriteEnable = true,
868		.depthCompareOp = VK_COMPARE_OP_ALWAYS,
869	};
870
871	VkPipelineDepthStencilStateCreateInfo stencil_info = {
872		.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
873		.depthTestEnable = false,
874		.depthWriteEnable = false,
875		.stencilTestEnable = true,
876		.front = {
877			.failOp = VK_STENCIL_OP_REPLACE,
878			.passOp = VK_STENCIL_OP_REPLACE,
879			.depthFailOp = VK_STENCIL_OP_REPLACE,
880			.compareOp = VK_COMPARE_OP_ALWAYS,
881			.compareMask = 0xff,
882			.writeMask = 0xff,
883			.reference = 0
884		},
885		.back = {
886			.failOp = VK_STENCIL_OP_REPLACE,
887			.passOp = VK_STENCIL_OP_REPLACE,
888			.depthFailOp = VK_STENCIL_OP_REPLACE,
889			.compareOp = VK_COMPARE_OP_ALWAYS,
890			.compareMask = 0xff,
891			.writeMask = 0xff,
892			.reference = 0
893		},
894		.depthCompareOp = VK_COMPARE_OP_ALWAYS,
895	};
896
897	switch(aspect) {
898	case VK_IMAGE_ASPECT_COLOR_BIT:
899		vk_pipeline_info.pColorBlendState = &color_blend_info;
900		break;
901	case VK_IMAGE_ASPECT_DEPTH_BIT:
902		vk_pipeline_info.pDepthStencilState = &depth_info;
903		break;
904	case VK_IMAGE_ASPECT_STENCIL_BIT:
905		vk_pipeline_info.pDepthStencilState = &stencil_info;
906		break;
907	default:
908		unreachable("Unhandled aspect");
909	}
910
911	const struct radv_graphics_pipeline_create_info radv_pipeline_info = {
912		.use_rectlist = true
913	};
914
915	result = radv_graphics_pipeline_create(radv_device_to_handle(device),
916	                                       radv_pipeline_cache_to_handle(&device->meta_state.cache),
917	                                       &vk_pipeline_info, &radv_pipeline_info,
918	                                       &device->meta_state.alloc, pipeline);
919	ralloc_free(vs.nir);
920	ralloc_free(fs.nir);
921	mtx_unlock(&device->meta_state.mtx);
922	return result;
923}
924
925static VkResult
926radv_device_init_meta_blit_color(struct radv_device *device, bool on_demand)
927{
928	VkResult result;
929
930	for (unsigned i = 0; i < NUM_META_FS_KEYS; ++i) {
931		unsigned key = radv_format_meta_fs_key(radv_fs_key_format_exemplars[i]);
932		for(unsigned j = 0; j < RADV_META_DST_LAYOUT_COUNT; ++j) {
933			VkImageLayout layout = radv_meta_dst_layout_to_layout(j);
934			result = radv_CreateRenderPass(radv_device_to_handle(device),
935						&(VkRenderPassCreateInfo) {
936							.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
937								.attachmentCount = 1,
938								.pAttachments = &(VkAttachmentDescription) {
939								.format = radv_fs_key_format_exemplars[i],
940								.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
941								.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
942								.initialLayout = layout,
943								.finalLayout = layout,
944							},
945								.subpassCount = 1,
946										.pSubpasses = &(VkSubpassDescription) {
947								.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
948								.inputAttachmentCount = 0,
949								.colorAttachmentCount = 1,
950								.pColorAttachments = &(VkAttachmentReference) {
951									.attachment = 0,
952									.layout = layout,
953								},
954								.pResolveAttachments = NULL,
955								.pDepthStencilAttachment = &(VkAttachmentReference) {
956									.attachment = VK_ATTACHMENT_UNUSED,
957									.layout = VK_IMAGE_LAYOUT_GENERAL,
958								},
959								.preserveAttachmentCount = 1,
960								.pPreserveAttachments = (uint32_t[]) { 0 },
961							},
962							.dependencyCount = 0,
963						}, &device->meta_state.alloc, &device->meta_state.blit.render_pass[key][j]);
964			if (result != VK_SUCCESS)
965				goto fail;
966		}
967
968		if (on_demand)
969			continue;
970
971		result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_1D, key, &device->meta_state.blit.pipeline_1d_src[key]);
972		if (result != VK_SUCCESS)
973			goto fail;
974
975		result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_2D, key, &device->meta_state.blit.pipeline_2d_src[key]);
976		if (result != VK_SUCCESS)
977			goto fail;
978
979		result = build_pipeline(device, VK_IMAGE_ASPECT_COLOR_BIT, GLSL_SAMPLER_DIM_3D, key, &device->meta_state.blit.pipeline_3d_src[key]);
980		if (result != VK_SUCCESS)
981			goto fail;
982
983	}
984
985	result = VK_SUCCESS;
986fail:
987	return result;
988}
989
990static VkResult
991radv_device_init_meta_blit_depth(struct radv_device *device, bool on_demand)
992{
993	VkResult result;
994
995	for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
996		VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
997		result = radv_CreateRenderPass(radv_device_to_handle(device),
998					       &(VkRenderPassCreateInfo) {
999						       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1000						       .attachmentCount = 1,
1001						       .pAttachments = &(VkAttachmentDescription) {
1002							       .format = VK_FORMAT_D32_SFLOAT,
1003							       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1004							       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1005							       .initialLayout = layout,
1006							       .finalLayout = layout,
1007						       },
1008						       .subpassCount = 1,
1009						       .pSubpasses = &(VkSubpassDescription) {
1010							       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1011							       .inputAttachmentCount = 0,
1012							       .colorAttachmentCount = 0,
1013							       .pColorAttachments = NULL,
1014							       .pResolveAttachments = NULL,
1015							       .pDepthStencilAttachment = &(VkAttachmentReference) {
1016								       .attachment = 0,
1017								       .layout = layout,
1018								},
1019							       .preserveAttachmentCount = 1,
1020							       .pPreserveAttachments = (uint32_t[]) { 0 },
1021							},
1022						        .dependencyCount = 0,
1023						}, &device->meta_state.alloc, &device->meta_state.blit.depth_only_rp[ds_layout]);
1024		if (result != VK_SUCCESS)
1025			goto fail;
1026	}
1027
1028	if (on_demand)
1029		return VK_SUCCESS;
1030
1031	result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_1D, 0, &device->meta_state.blit.depth_only_1d_pipeline);
1032	if (result != VK_SUCCESS)
1033		goto fail;
1034
1035	result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_2D, 0, &device->meta_state.blit.depth_only_2d_pipeline);
1036	if (result != VK_SUCCESS)
1037		goto fail;
1038
1039	result = build_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, GLSL_SAMPLER_DIM_3D, 0, &device->meta_state.blit.depth_only_3d_pipeline);
1040	if (result != VK_SUCCESS)
1041		goto fail;
1042
1043fail:
1044	return result;
1045}
1046
1047static VkResult
1048radv_device_init_meta_blit_stencil(struct radv_device *device, bool on_demand)
1049{
1050	VkResult result;
1051
1052	for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
1053		VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
1054		result = radv_CreateRenderPass(radv_device_to_handle(device),
1055					       &(VkRenderPassCreateInfo) {
1056						       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1057						       .attachmentCount = 1,
1058						       .pAttachments = &(VkAttachmentDescription) {
1059							       .format = VK_FORMAT_S8_UINT,
1060							       .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1061							       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1062							       .initialLayout = layout,
1063							       .finalLayout = layout,
1064						       },
1065						       .subpassCount = 1,
1066						       .pSubpasses = &(VkSubpassDescription) {
1067							       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1068							       .inputAttachmentCount = 0,
1069							       .colorAttachmentCount = 0,
1070							       .pColorAttachments = NULL,
1071							       .pResolveAttachments = NULL,
1072							       .pDepthStencilAttachment = &(VkAttachmentReference) {
1073								       .attachment = 0,
1074								       .layout = layout,
1075							       },
1076							       .preserveAttachmentCount = 1,
1077							       .pPreserveAttachments = (uint32_t[]) { 0 },
1078						       },
1079						       .dependencyCount = 0,
1080					 }, &device->meta_state.alloc, &device->meta_state.blit.stencil_only_rp[ds_layout]);
1081	}
1082	if (result != VK_SUCCESS)
1083		goto fail;
1084
1085	if (on_demand)
1086		return VK_SUCCESS;
1087
1088	result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_1D, 0, &device->meta_state.blit.stencil_only_1d_pipeline);
1089	if (result != VK_SUCCESS)
1090		goto fail;
1091
1092	result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_2D, 0, &device->meta_state.blit.stencil_only_2d_pipeline);
1093	if (result != VK_SUCCESS)
1094		goto fail;
1095
1096	result = build_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, GLSL_SAMPLER_DIM_3D, 0, &device->meta_state.blit.stencil_only_3d_pipeline);
1097	if (result != VK_SUCCESS)
1098		goto fail;
1099
1100
1101fail:
1102	return result;
1103}
1104
1105VkResult
1106radv_device_init_meta_blit_state(struct radv_device *device, bool on_demand)
1107{
1108	VkResult result;
1109
1110	VkDescriptorSetLayoutCreateInfo ds_layout_info = {
1111		.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1112		.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1113		.bindingCount = 1,
1114		.pBindings = (VkDescriptorSetLayoutBinding[]) {
1115			{
1116				.binding = 0,
1117				.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1118				.descriptorCount = 1,
1119				.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1120				.pImmutableSamplers = NULL
1121			},
1122		}
1123	};
1124	result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
1125						&ds_layout_info,
1126						&device->meta_state.alloc,
1127						&device->meta_state.blit.ds_layout);
1128	if (result != VK_SUCCESS)
1129		goto fail;
1130
1131	const VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 20};
1132
1133	result = radv_CreatePipelineLayout(radv_device_to_handle(device),
1134					   &(VkPipelineLayoutCreateInfo) {
1135						   .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1136							   .setLayoutCount = 1,
1137							   .pSetLayouts = &device->meta_state.blit.ds_layout,
1138							   .pushConstantRangeCount = 1,
1139							   .pPushConstantRanges = &push_constant_range,
1140							   },
1141					   &device->meta_state.alloc, &device->meta_state.blit.pipeline_layout);
1142	if (result != VK_SUCCESS)
1143		goto fail;
1144
1145	result = radv_device_init_meta_blit_color(device, on_demand);
1146	if (result != VK_SUCCESS)
1147		goto fail;
1148
1149	result = radv_device_init_meta_blit_depth(device, on_demand);
1150	if (result != VK_SUCCESS)
1151		goto fail;
1152
1153	result = radv_device_init_meta_blit_stencil(device, on_demand);
1154
1155fail:
1156	if (result != VK_SUCCESS)
1157		radv_device_finish_meta_blit_state(device);
1158	return result;
1159}
1160