1 /*
2 * Copyright © 2016 Red Hat
3 *
4 * based on anv driver:
5 * Copyright © 2016 Intel Corporation
6 *
7 * SPDX-License-Identifier: MIT
8 */
9
10 #include "nir/nir_builder.h"
11 #include "radv_entrypoints.h"
12 #include "radv_meta.h"
13 #include "vk_common_entrypoints.h"
14 #include "vk_format.h"
15 #include "vk_shader_module.h"
16
17 enum blit2d_src_type {
18 BLIT2D_SRC_TYPE_IMAGE,
19 BLIT2D_SRC_TYPE_IMAGE_3D,
20 BLIT2D_SRC_TYPE_BUFFER,
21 BLIT2D_NUM_SRC_TYPES,
22 };
23
24 static VkResult get_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type, VkFormat format,
25 uint32_t log2_samples, VkPipeline *pipeline_out, VkPipelineLayout *layout_out);
26
27 static VkResult get_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
28 uint32_t log2_samples, VkPipeline *pipeline_out, VkPipelineLayout *layout_out);
29
30 static VkResult get_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
31 uint32_t log2_samples, VkPipeline *pipeline_out,
32 VkPipelineLayout *layout_out);
33
34 static void
create_iview(struct radv_cmd_buffer * cmd_buffer,struct radv_meta_blit2d_surf * surf,struct radv_image_view * iview,VkFormat depth_format,VkImageAspectFlagBits aspects)35 create_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf, struct radv_image_view *iview,
36 VkFormat depth_format, VkImageAspectFlagBits aspects)
37 {
38 struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
39 VkFormat format;
40
41 if (depth_format)
42 format = depth_format;
43 else
44 format = surf->format;
45
46 radv_image_view_init(iview, device,
47 &(VkImageViewCreateInfo){
48 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
49 .image = radv_image_to_handle(surf->image),
50 .viewType = radv_meta_get_view_type(surf->image),
51 .format = format,
52 .subresourceRange = {.aspectMask = aspects,
53 .baseMipLevel = surf->level,
54 .levelCount = 1,
55 .baseArrayLayer = surf->layer,
56 .layerCount = 1},
57 },
58 &(struct radv_image_view_extra_create_info){.disable_dcc_mrt = surf->disable_compression});
59 }
60
61 static void
create_bview(struct radv_cmd_buffer * cmd_buffer,struct radv_meta_blit2d_buffer * src,struct radv_buffer_view * bview,VkFormat depth_format)62 create_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src, struct radv_buffer_view *bview,
63 VkFormat depth_format)
64 {
65 struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
66 VkFormat format;
67
68 if (depth_format)
69 format = depth_format;
70 else
71 format = src->format;
72 radv_buffer_view_init(bview, device,
73 &(VkBufferViewCreateInfo){
74 .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
75 .flags = 0,
76 .buffer = radv_buffer_to_handle(src->buffer),
77 .format = format,
78 .offset = src->offset,
79 .range = VK_WHOLE_SIZE,
80 });
81 }
82
83 struct blit2d_src_temps {
84 struct radv_image_view iview;
85 struct radv_buffer_view bview;
86 };
87
88 static void
blit2d_bind_src(struct radv_cmd_buffer * cmd_buffer,VkPipelineLayout layout,struct radv_meta_blit2d_surf * src_img,struct radv_meta_blit2d_buffer * src_buf,struct blit2d_src_temps * tmp,enum blit2d_src_type src_type,VkFormat depth_format,VkImageAspectFlagBits aspects,uint32_t log2_samples)89 blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, VkPipelineLayout layout, struct radv_meta_blit2d_surf *src_img,
90 struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp, enum blit2d_src_type src_type,
91 VkFormat depth_format, VkImageAspectFlagBits aspects, uint32_t log2_samples)
92 {
93 if (src_type == BLIT2D_SRC_TYPE_BUFFER) {
94 create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format);
95
96 radv_meta_push_descriptor_set(
97 cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1,
98 (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
99 .dstBinding = 0,
100 .dstArrayElement = 0,
101 .descriptorCount = 1,
102 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
103 .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(&tmp->bview)}}});
104
105 vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4,
106 &src_buf->pitch);
107 } else {
108 create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects);
109
110 if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
111 vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4,
112 &src_img->layer);
113
114 radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1,
115 (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
116 .dstBinding = 0,
117 .dstArrayElement = 0,
118 .descriptorCount = 1,
119 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
120 .pImageInfo = (VkDescriptorImageInfo[]){
121 {
122 .sampler = VK_NULL_HANDLE,
123 .imageView = radv_image_view_to_handle(&tmp->iview),
124 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
125 },
126 }}});
127 }
128 }
129
130 static void
radv_meta_blit2d_normal_dst(struct radv_cmd_buffer * cmd_buffer,struct radv_meta_blit2d_surf * src_img,struct radv_meta_blit2d_buffer * src_buf,struct radv_meta_blit2d_surf * dst,struct radv_meta_blit2d_rect * rect,enum blit2d_src_type src_type,uint32_t log2_samples)131 radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
132 struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
133 struct radv_meta_blit2d_rect *rect, enum blit2d_src_type src_type, uint32_t log2_samples)
134 {
135 struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
136 VkPipelineLayout layout;
137 VkPipeline pipeline;
138 VkResult result;
139
140 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
141 &(VkViewport){.x = rect->dst_x,
142 .y = rect->dst_y,
143 .width = rect->width,
144 .height = rect->height,
145 .minDepth = 0.0f,
146 .maxDepth = 1.0f});
147
148 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
149 &(VkRect2D){
150 .offset = (VkOffset2D){rect->dst_x, rect->dst_y},
151 .extent = (VkExtent2D){rect->width, rect->height},
152 });
153
154 u_foreach_bit (i, dst->aspect_mask) {
155 unsigned aspect_mask = 1u << i;
156 unsigned src_aspect_mask = aspect_mask;
157 VkFormat depth_format = 0;
158 if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
159 depth_format = vk_format_stencil_only(dst->image->vk.format);
160 else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
161 depth_format = vk_format_depth_only(dst->image->vk.format);
162 else if (src_img)
163 src_aspect_mask = src_img->aspect_mask;
164
165 struct radv_image_view dst_iview;
166 create_iview(cmd_buffer, dst, &dst_iview, depth_format, aspect_mask);
167
168 const VkRenderingAttachmentInfo att_info = {
169 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
170 .imageView = radv_image_view_to_handle(&dst_iview),
171 .imageLayout = dst->current_layout,
172 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
173 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
174 };
175
176 VkRenderingInfo rendering_info = {
177 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
178 .flags = VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA,
179 .renderArea =
180 {
181 .offset = {rect->dst_x, rect->dst_y},
182 .extent = {rect->width, rect->height},
183 },
184 .layerCount = 1,
185 };
186
187 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT || aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
188 aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT || aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
189 result = get_color_pipeline(device, src_type, dst_iview.vk.format, log2_samples, &pipeline, &layout);
190 if (result != VK_SUCCESS) {
191 vk_command_buffer_set_error(&cmd_buffer->vk, result);
192 goto fail_pipeline;
193 }
194
195 rendering_info.colorAttachmentCount = 1;
196 rendering_info.pColorAttachments = &att_info;
197
198 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
199 } else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
200 result = get_depth_only_pipeline(device, src_type, log2_samples, &pipeline, &layout);
201 if (result != VK_SUCCESS) {
202 vk_command_buffer_set_error(&cmd_buffer->vk, result);
203 goto fail_pipeline;
204 }
205
206 rendering_info.pDepthAttachment = &att_info,
207 rendering_info.pStencilAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? &att_info : NULL,
208
209 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
210
211 } else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
212 result = get_stencil_only_pipeline(device, src_type, log2_samples, &pipeline, &layout);
213 if (result != VK_SUCCESS) {
214 vk_command_buffer_set_error(&cmd_buffer->vk, result);
215 goto fail_pipeline;
216 }
217
218 rendering_info.pDepthAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ? &att_info : NULL,
219 rendering_info.pStencilAttachment = &att_info,
220
221 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
222 } else
223 unreachable("Processing blit2d with multiple aspects.");
224
225 float vertex_push_constants[4] = {
226 rect->src_x,
227 rect->src_y,
228 rect->src_x + rect->width,
229 rect->src_y + rect->height,
230 };
231
232 vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 16,
233 vertex_push_constants);
234
235 struct blit2d_src_temps src_temps;
236 blit2d_bind_src(cmd_buffer, layout, src_img, src_buf, &src_temps, src_type, depth_format, src_aspect_mask,
237 log2_samples);
238
239 radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
240
241 radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
242
243 radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
244
245 fail_pipeline:
246
247 if (src_type == BLIT2D_SRC_TYPE_BUFFER)
248 radv_buffer_view_finish(&src_temps.bview);
249 else
250 radv_image_view_finish(&src_temps.iview);
251
252 radv_image_view_finish(&dst_iview);
253 }
254 }
255
256 void
radv_meta_blit2d(struct radv_cmd_buffer * cmd_buffer,struct radv_meta_blit2d_surf * src_img,struct radv_meta_blit2d_buffer * src_buf,struct radv_meta_blit2d_surf * dst,struct radv_meta_blit2d_rect * rect)257 radv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
258 struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
259 struct radv_meta_blit2d_rect *rect)
260 {
261 bool use_3d = (src_img && src_img->image->vk.image_type == VK_IMAGE_TYPE_3D);
262 enum blit2d_src_type src_type = src_buf ? BLIT2D_SRC_TYPE_BUFFER
263 : use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D
264 : BLIT2D_SRC_TYPE_IMAGE;
265 radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, rect, src_type,
266 src_img ? util_logbase2(src_img->image->vk.samples) : 0);
267 }
268
269 static nir_shader *
build_nir_vertex_shader(struct radv_device * device)270 build_nir_vertex_shader(struct radv_device *device)
271 {
272 const struct glsl_type *vec4 = glsl_vec4_type();
273 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
274 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_VERTEX, "meta_blit2d_vs");
275
276 nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
277 pos_out->data.location = VARYING_SLOT_POS;
278
279 nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos");
280 tex_pos_out->data.location = VARYING_SLOT_VAR0;
281 tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
282
283 nir_def *outvec = nir_gen_rect_vertices(&b, NULL, NULL);
284 nir_store_var(&b, pos_out, outvec, 0xf);
285
286 nir_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
287 nir_def *vertex_id = nir_load_vertex_id_zero_base(&b);
288
289 /* vertex 0 - src_x, src_y */
290 /* vertex 1 - src_x, src_y+h */
291 /* vertex 2 - src_x+w, src_y */
292 /* so channel 0 is vertex_id != 2 ? src_x : src_x + w
293 channel 1 is vertex id != 1 ? src_y : src_y + w */
294
295 nir_def *c0cmp = nir_ine_imm(&b, vertex_id, 2);
296 nir_def *c1cmp = nir_ine_imm(&b, vertex_id, 1);
297
298 nir_def *comp[2];
299 comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
300
301 comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
302 nir_def *out_tex_vec = nir_vec(&b, comp, 2);
303 nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3);
304 return b.shader;
305 }
306
307 typedef nir_def *(*texel_fetch_build_func)(struct nir_builder *, struct radv_device *, nir_def *, bool, bool);
308
309 static nir_def *
build_nir_texel_fetch(struct nir_builder * b,struct radv_device * device,nir_def * tex_pos,bool is_3d,bool is_multisampled)310 build_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, nir_def *tex_pos, bool is_3d,
311 bool is_multisampled)
312 {
313 enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D
314 : is_multisampled ? GLSL_SAMPLER_DIM_MS
315 : GLSL_SAMPLER_DIM_2D;
316 const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT);
317 nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
318 sampler->data.descriptor_set = 0;
319 sampler->data.binding = 0;
320
321 nir_def *tex_pos_3d = NULL;
322 nir_def *sample_idx = NULL;
323 if (is_3d) {
324 nir_def *layer = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
325
326 nir_def *chans[3];
327 chans[0] = nir_channel(b, tex_pos, 0);
328 chans[1] = nir_channel(b, tex_pos, 1);
329 chans[2] = layer;
330 tex_pos_3d = nir_vec(b, chans, 3);
331 }
332 if (is_multisampled) {
333 sample_idx = nir_load_sample_id(b);
334 }
335
336 nir_deref_instr *tex_deref = nir_build_deref_var(b, sampler);
337
338 if (is_multisampled) {
339 return nir_txf_ms_deref(b, tex_deref, tex_pos, sample_idx);
340 } else {
341 return nir_txf_deref(b, tex_deref, is_3d ? tex_pos_3d : tex_pos, NULL);
342 }
343 }
344
345 static nir_def *
build_nir_buffer_fetch(struct nir_builder * b,struct radv_device * device,nir_def * tex_pos,bool is_3d,bool is_multisampled)346 build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_def *tex_pos, bool is_3d,
347 bool is_multisampled)
348 {
349 const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT);
350 nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
351 sampler->data.descriptor_set = 0;
352 sampler->data.binding = 0;
353
354 nir_def *width = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
355
356 nir_def *pos_x = nir_channel(b, tex_pos, 0);
357 nir_def *pos_y = nir_channel(b, tex_pos, 1);
358 pos_y = nir_imul(b, pos_y, width);
359 pos_x = nir_iadd(b, pos_x, pos_y);
360
361 nir_deref_instr *tex_deref = nir_build_deref_var(b, sampler);
362 return nir_txf_deref(b, tex_deref, pos_x, NULL);
363 }
364
365 static nir_shader *
build_nir_copy_fragment_shader(struct radv_device * device,texel_fetch_build_func txf_func,const char * name,bool is_3d,bool is_multisampled)366 build_nir_copy_fragment_shader(struct radv_device *device, texel_fetch_build_func txf_func, const char *name,
367 bool is_3d, bool is_multisampled)
368 {
369 const struct glsl_type *vec4 = glsl_vec4_type();
370 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
371 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
372
373 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
374 tex_pos_in->data.location = VARYING_SLOT_VAR0;
375
376 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
377 color_out->data.location = FRAG_RESULT_DATA0;
378
379 nir_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
380 nir_def *tex_pos = nir_trim_vector(&b, pos_int, 2);
381
382 nir_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
383 nir_store_var(&b, color_out, color, 0xf);
384
385 b.shader->info.fs.uses_sample_shading = is_multisampled;
386
387 return b.shader;
388 }
389
390 static nir_shader *
build_nir_copy_fragment_shader_depth(struct radv_device * device,texel_fetch_build_func txf_func,const char * name,bool is_3d,bool is_multisampled)391 build_nir_copy_fragment_shader_depth(struct radv_device *device, texel_fetch_build_func txf_func, const char *name,
392 bool is_3d, bool is_multisampled)
393 {
394 const struct glsl_type *vec4 = glsl_vec4_type();
395 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
396 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
397
398 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
399 tex_pos_in->data.location = VARYING_SLOT_VAR0;
400
401 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
402 color_out->data.location = FRAG_RESULT_DEPTH;
403
404 nir_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
405 nir_def *tex_pos = nir_trim_vector(&b, pos_int, 2);
406
407 nir_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
408 nir_store_var(&b, color_out, color, 0x1);
409
410 b.shader->info.fs.uses_sample_shading = is_multisampled;
411
412 return b.shader;
413 }
414
415 static nir_shader *
build_nir_copy_fragment_shader_stencil(struct radv_device * device,texel_fetch_build_func txf_func,const char * name,bool is_3d,bool is_multisampled)416 build_nir_copy_fragment_shader_stencil(struct radv_device *device, texel_fetch_build_func txf_func, const char *name,
417 bool is_3d, bool is_multisampled)
418 {
419 const struct glsl_type *vec4 = glsl_vec4_type();
420 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
421 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
422
423 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
424 tex_pos_in->data.location = VARYING_SLOT_VAR0;
425
426 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
427 color_out->data.location = FRAG_RESULT_STENCIL;
428
429 nir_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
430 nir_def *tex_pos = nir_trim_vector(&b, pos_int, 2);
431
432 nir_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
433 nir_store_var(&b, color_out, color, 0x1);
434
435 b.shader->info.fs.uses_sample_shading = is_multisampled;
436
437 return b.shader;
438 }
439
440 static VkResult
create_layout(struct radv_device * device,int idx,VkPipelineLayout * layout_out)441 create_layout(struct radv_device *device, int idx, VkPipelineLayout *layout_out)
442 {
443 const VkDescriptorType desc_type =
444 (idx == BLIT2D_SRC_TYPE_BUFFER) ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
445 char key_data[64];
446
447 snprintf(key_data, sizeof(key_data), "radv-blit2d-%d", idx);
448
449 const VkDescriptorSetLayoutBinding binding = {
450 .binding = 0,
451 .descriptorType = desc_type,
452 .descriptorCount = 1,
453 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
454 };
455
456 const VkDescriptorSetLayoutCreateInfo desc_info = {
457 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
458 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT,
459 .bindingCount = 1,
460 .pBindings = &binding,
461 };
462
463 const VkPushConstantRange pc_range = {
464 .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
465 .size = 20,
466 };
467
468 return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data,
469 strlen(key_data), layout_out);
470 }
471
472 static VkResult
get_color_pipeline(struct radv_device * device,enum blit2d_src_type src_type,VkFormat format,uint32_t log2_samples,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)473 get_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type, VkFormat format, uint32_t log2_samples,
474 VkPipeline *pipeline_out, VkPipelineLayout *layout_out)
475 {
476 const unsigned fs_key = radv_format_meta_fs_key(device, format);
477 char key_data[64];
478 const char *name;
479 VkResult result;
480
481 result = create_layout(device, src_type, layout_out);
482 if (result != VK_SUCCESS)
483 return result;
484
485 snprintf(key_data, sizeof(key_data), "radv-blit2d-color-%d-%d-%d", src_type, log2_samples, fs_key);
486
487 texel_fetch_build_func src_func;
488 switch (src_type) {
489 case BLIT2D_SRC_TYPE_IMAGE:
490 src_func = build_nir_texel_fetch;
491 name = "meta_blit2d_image_fs";
492 break;
493 case BLIT2D_SRC_TYPE_IMAGE_3D:
494 src_func = build_nir_texel_fetch;
495 name = "meta_blit3d_image_fs";
496 break;
497 case BLIT2D_SRC_TYPE_BUFFER:
498 src_func = build_nir_buffer_fetch;
499 name = "meta_blit2d_buffer_fs";
500 break;
501 default:
502 unreachable("unknown blit src type\n");
503 break;
504 }
505
506 nir_shader *vs_module = build_nir_vertex_shader(device);
507 nir_shader *fs_module =
508 build_nir_copy_fragment_shader(device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
509
510 const VkGraphicsPipelineCreateInfo pipeline_create_info = {
511 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
512 .stageCount = 2,
513 .pStages =
514 (VkPipelineShaderStageCreateInfo[]){
515 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
516 .stage = VK_SHADER_STAGE_VERTEX_BIT,
517 .module = vk_shader_module_handle_from_nir(vs_module),
518 .pName = "main",
519 .pSpecializationInfo = NULL},
520 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
521 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
522 .module = vk_shader_module_handle_from_nir(fs_module),
523 .pName = "main",
524 .pSpecializationInfo = NULL},
525 },
526 .pVertexInputState =
527 &(VkPipelineVertexInputStateCreateInfo){
528 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
529 .vertexBindingDescriptionCount = 0,
530 .vertexAttributeDescriptionCount = 0,
531 },
532 .pInputAssemblyState =
533 &(VkPipelineInputAssemblyStateCreateInfo){
534 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
535 .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
536 .primitiveRestartEnable = false,
537 },
538 .pViewportState =
539 &(VkPipelineViewportStateCreateInfo){
540 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
541 .viewportCount = 1,
542 .scissorCount = 1,
543 },
544 .pRasterizationState =
545 &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
546 .rasterizerDiscardEnable = false,
547 .polygonMode = VK_POLYGON_MODE_FILL,
548 .cullMode = VK_CULL_MODE_NONE,
549 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
550 .depthBiasConstantFactor = 0.0f,
551 .depthBiasClamp = 0.0f,
552 .depthBiasSlopeFactor = 0.0f,
553 .lineWidth = 1.0f},
554 .pMultisampleState =
555 &(VkPipelineMultisampleStateCreateInfo){
556 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
557 .rasterizationSamples = 1 << log2_samples,
558 .sampleShadingEnable = log2_samples > 1,
559 .minSampleShading = 1.0,
560 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
561 },
562 .pColorBlendState =
563 &(VkPipelineColorBlendStateCreateInfo){
564 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
565 .attachmentCount = 1,
566 .pAttachments =
567 (VkPipelineColorBlendAttachmentState[]){
568 {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
569 VK_COLOR_COMPONENT_B_BIT},
570 },
571 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}},
572 .pDynamicState =
573 &(VkPipelineDynamicStateCreateInfo){
574 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
575 .dynamicStateCount = 2,
576 .pDynamicStates =
577 (VkDynamicState[]){
578 VK_DYNAMIC_STATE_VIEWPORT,
579 VK_DYNAMIC_STATE_SCISSOR,
580 },
581 },
582 .layout = *layout_out,
583 };
584
585 struct vk_meta_rendering_info render = {
586 .color_attachment_count = 1,
587 .color_attachment_formats = {format},
588 };
589
590 result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render,
591 key_data, strlen(key_data), pipeline_out);
592
593 ralloc_free(vs_module);
594 ralloc_free(fs_module);
595 return result;
596 }
597
598 static VkResult
get_depth_only_pipeline(struct radv_device * device,enum blit2d_src_type src_type,uint32_t log2_samples,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)599 get_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type, uint32_t log2_samples,
600 VkPipeline *pipeline_out, VkPipelineLayout *layout_out)
601 {
602 char key_data[64];
603 const char *name;
604 VkResult result;
605
606 result = create_layout(device, src_type, layout_out);
607 if (result != VK_SUCCESS)
608 return result;
609
610 snprintf(key_data, sizeof(key_data), "radv-blit2d-depth-%d-%d", src_type, log2_samples);
611
612 texel_fetch_build_func src_func;
613 switch (src_type) {
614 case BLIT2D_SRC_TYPE_IMAGE:
615 src_func = build_nir_texel_fetch;
616 name = "meta_blit2d_depth_image_fs";
617 break;
618 case BLIT2D_SRC_TYPE_IMAGE_3D:
619 src_func = build_nir_texel_fetch;
620 name = "meta_blit3d_depth_image_fs";
621 break;
622 case BLIT2D_SRC_TYPE_BUFFER:
623 src_func = build_nir_buffer_fetch;
624 name = "meta_blit2d_depth_buffer_fs";
625 break;
626 default:
627 unreachable("unknown blit src type\n");
628 break;
629 }
630
631 nir_shader *vs_module = build_nir_vertex_shader(device);
632 nir_shader *fs_module = build_nir_copy_fragment_shader_depth(device, src_func, name,
633 src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
634
635 const VkGraphicsPipelineCreateInfo pipeline_create_info = {
636 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
637 .stageCount = 2,
638 .pStages =
639 (VkPipelineShaderStageCreateInfo[]){
640 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
641 .stage = VK_SHADER_STAGE_VERTEX_BIT,
642 .module = vk_shader_module_handle_from_nir(vs_module),
643 .pName = "main",
644 .pSpecializationInfo = NULL},
645 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
646 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
647 .module = vk_shader_module_handle_from_nir(fs_module),
648 .pName = "main",
649 .pSpecializationInfo = NULL},
650 },
651 .pVertexInputState =
652 &(VkPipelineVertexInputStateCreateInfo){
653 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
654 .vertexBindingDescriptionCount = 0,
655 .vertexAttributeDescriptionCount = 0,
656 },
657 .pInputAssemblyState =
658 &(VkPipelineInputAssemblyStateCreateInfo){
659 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
660 .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
661 .primitiveRestartEnable = false,
662 },
663 .pViewportState =
664 &(VkPipelineViewportStateCreateInfo){
665 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
666 .viewportCount = 1,
667 .scissorCount = 1,
668 },
669 .pRasterizationState =
670 &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
671 .rasterizerDiscardEnable = false,
672 .polygonMode = VK_POLYGON_MODE_FILL,
673 .cullMode = VK_CULL_MODE_NONE,
674 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
675 .depthBiasConstantFactor = 0.0f,
676 .depthBiasClamp = 0.0f,
677 .depthBiasSlopeFactor = 0.0f,
678 .lineWidth = 1.0f},
679 .pMultisampleState =
680 &(VkPipelineMultisampleStateCreateInfo){
681 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
682 .rasterizationSamples = 1 << log2_samples,
683 .sampleShadingEnable = false,
684 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
685 },
686 .pColorBlendState =
687 &(VkPipelineColorBlendStateCreateInfo){
688 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
689 .attachmentCount = 0,
690 .pAttachments = NULL,
691 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
692 },
693 .pDepthStencilState =
694 &(VkPipelineDepthStencilStateCreateInfo){
695 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
696 .depthTestEnable = true,
697 .depthWriteEnable = true,
698 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
699 .front =
700 {
701 .failOp = VK_STENCIL_OP_KEEP,
702 .passOp = VK_STENCIL_OP_KEEP,
703 .depthFailOp = VK_STENCIL_OP_KEEP,
704 .compareOp = VK_COMPARE_OP_NEVER,
705 .compareMask = UINT32_MAX,
706 .writeMask = UINT32_MAX,
707 .reference = 0u,
708 },
709 .back =
710 {
711 .failOp = VK_STENCIL_OP_KEEP,
712 .passOp = VK_STENCIL_OP_KEEP,
713 .depthFailOp = VK_STENCIL_OP_KEEP,
714 .compareOp = VK_COMPARE_OP_NEVER,
715 .compareMask = UINT32_MAX,
716 .writeMask = UINT32_MAX,
717 .reference = 0u,
718 },
719 .minDepthBounds = 0.0f,
720 .maxDepthBounds = 1.0f,
721 },
722 .pDynamicState =
723 &(VkPipelineDynamicStateCreateInfo){
724 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
725 .dynamicStateCount = 2,
726 .pDynamicStates =
727 (VkDynamicState[]){
728 VK_DYNAMIC_STATE_VIEWPORT,
729 VK_DYNAMIC_STATE_SCISSOR,
730 },
731 },
732 .layout = *layout_out,
733 };
734
735 struct vk_meta_rendering_info render = {
736 .depth_attachment_format = VK_FORMAT_D32_SFLOAT,
737 };
738
739 result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render,
740 key_data, strlen(key_data), pipeline_out);
741
742 ralloc_free(vs_module);
743 ralloc_free(fs_module);
744 return result;
745 }
746
747 static VkResult
get_stencil_only_pipeline(struct radv_device * device,enum blit2d_src_type src_type,uint32_t log2_samples,VkPipeline * pipeline_out,VkPipelineLayout * layout_out)748 get_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type, uint32_t log2_samples,
749 VkPipeline *pipeline_out, VkPipelineLayout *layout_out)
750 {
751 char key_data[64];
752 const char *name;
753 VkResult result;
754
755 result = create_layout(device, src_type, layout_out);
756 if (result != VK_SUCCESS)
757 return result;
758
759 snprintf(key_data, sizeof(key_data), "radv-blit2d-stencil-%d-%d", src_type, log2_samples);
760
761 texel_fetch_build_func src_func;
762 switch (src_type) {
763 case BLIT2D_SRC_TYPE_IMAGE:
764 src_func = build_nir_texel_fetch;
765 name = "meta_blit2d_stencil_image_fs";
766 break;
767 case BLIT2D_SRC_TYPE_IMAGE_3D:
768 src_func = build_nir_texel_fetch;
769 name = "meta_blit3d_stencil_image_fs";
770 break;
771 case BLIT2D_SRC_TYPE_BUFFER:
772 src_func = build_nir_buffer_fetch;
773 name = "meta_blit2d_stencil_buffer_fs";
774 break;
775 default:
776 unreachable("unknown blit src type\n");
777 break;
778 }
779
780 nir_shader *vs_module = build_nir_vertex_shader(device);
781 nir_shader *fs_module = build_nir_copy_fragment_shader_stencil(
782 device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
783
784 const VkGraphicsPipelineCreateInfo pipeline_create_info = {
785 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
786 .stageCount = 2,
787 .pStages =
788 (VkPipelineShaderStageCreateInfo[]){
789 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
790 .stage = VK_SHADER_STAGE_VERTEX_BIT,
791 .module = vk_shader_module_handle_from_nir(vs_module),
792 .pName = "main",
793 .pSpecializationInfo = NULL},
794 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
795 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
796 .module = vk_shader_module_handle_from_nir(fs_module),
797 .pName = "main",
798 .pSpecializationInfo = NULL},
799 },
800 .pVertexInputState =
801 &(VkPipelineVertexInputStateCreateInfo){
802 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
803 .vertexBindingDescriptionCount = 0,
804 .vertexAttributeDescriptionCount = 0,
805 },
806 .pInputAssemblyState =
807 &(VkPipelineInputAssemblyStateCreateInfo){
808 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
809 .topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
810 .primitiveRestartEnable = false,
811 },
812 .pViewportState =
813 &(VkPipelineViewportStateCreateInfo){
814 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
815 .viewportCount = 1,
816 .scissorCount = 1,
817 },
818 .pRasterizationState =
819 &(VkPipelineRasterizationStateCreateInfo){.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
820 .rasterizerDiscardEnable = false,
821 .polygonMode = VK_POLYGON_MODE_FILL,
822 .cullMode = VK_CULL_MODE_NONE,
823 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
824 .depthBiasConstantFactor = 0.0f,
825 .depthBiasClamp = 0.0f,
826 .depthBiasSlopeFactor = 0.0f,
827 .lineWidth = 1.0f},
828 .pMultisampleState =
829 &(VkPipelineMultisampleStateCreateInfo){
830 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
831 .rasterizationSamples = 1 << log2_samples,
832 .sampleShadingEnable = false,
833 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
834 },
835 .pColorBlendState =
836 &(VkPipelineColorBlendStateCreateInfo){
837 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
838 .attachmentCount = 0,
839 .pAttachments = NULL,
840 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
841 },
842 .pDepthStencilState =
843 &(VkPipelineDepthStencilStateCreateInfo){
844 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
845 .depthTestEnable = false,
846 .depthWriteEnable = false,
847 .stencilTestEnable = true,
848 .front = {.failOp = VK_STENCIL_OP_REPLACE,
849 .passOp = VK_STENCIL_OP_REPLACE,
850 .depthFailOp = VK_STENCIL_OP_REPLACE,
851 .compareOp = VK_COMPARE_OP_ALWAYS,
852 .compareMask = 0xff,
853 .writeMask = 0xff,
854 .reference = 0},
855 .back = {.failOp = VK_STENCIL_OP_REPLACE,
856 .passOp = VK_STENCIL_OP_REPLACE,
857 .depthFailOp = VK_STENCIL_OP_REPLACE,
858 .compareOp = VK_COMPARE_OP_ALWAYS,
859 .compareMask = 0xff,
860 .writeMask = 0xff,
861 .reference = 0},
862 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
863 .minDepthBounds = 0.0f,
864 .maxDepthBounds = 1.0f,
865 },
866 .pDynamicState =
867 &(VkPipelineDynamicStateCreateInfo){
868 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
869 .dynamicStateCount = 2,
870 .pDynamicStates =
871 (VkDynamicState[]){
872 VK_DYNAMIC_STATE_VIEWPORT,
873 VK_DYNAMIC_STATE_SCISSOR,
874 },
875 },
876 .layout = *layout_out,
877 };
878
879 struct vk_meta_rendering_info render = {
880 .stencil_attachment_format = VK_FORMAT_S8_UINT,
881 };
882
883 result = vk_meta_create_graphics_pipeline(&device->vk, &device->meta_state.device, &pipeline_create_info, &render,
884 key_data, strlen(key_data), pipeline_out);
885
886 ralloc_free(vs_module);
887 ralloc_free(fs_module);
888 return result;
889 }
890