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