1 /*
2 * Copyright © 2016 Red Hat
3 *
4 * based on anv driver:
5 * Copyright © 2016 Intel Corporation
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27 #include "nir/nir_builder.h"
28 #include "radv_meta.h"
29 #include "vk_format.h"
30
31 enum blit2d_src_type {
32 BLIT2D_SRC_TYPE_IMAGE,
33 BLIT2D_SRC_TYPE_IMAGE_3D,
34 BLIT2D_SRC_TYPE_BUFFER,
35 BLIT2D_NUM_SRC_TYPES,
36 };
37
38 static VkResult blit2d_init_color_pipeline(struct radv_device *device,
39 enum blit2d_src_type src_type, VkFormat format,
40 uint32_t log2_samples);
41
42 static VkResult blit2d_init_depth_only_pipeline(struct radv_device *device,
43 enum blit2d_src_type src_type,
44 uint32_t log2_samples);
45
46 static VkResult blit2d_init_stencil_only_pipeline(struct radv_device *device,
47 enum blit2d_src_type src_type,
48 uint32_t log2_samples);
49
50 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)51 create_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf,
52 struct radv_image_view *iview, VkFormat depth_format, VkImageAspectFlagBits aspects)
53 {
54 VkFormat format;
55
56 if (depth_format)
57 format = depth_format;
58 else
59 format = surf->format;
60
61 radv_image_view_init(iview, cmd_buffer->device,
62 &(VkImageViewCreateInfo){
63 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
64 .image = radv_image_to_handle(surf->image),
65 .viewType = radv_meta_get_view_type(surf->image),
66 .format = format,
67 .subresourceRange = {.aspectMask = aspects,
68 .baseMipLevel = surf->level,
69 .levelCount = 1,
70 .baseArrayLayer = surf->layer,
71 .layerCount = 1},
72 },
73 0, &(struct radv_image_view_extra_create_info){
74 .disable_dcc_mrt = surf->disable_compression
75 });
76 }
77
78 static void
create_bview(struct radv_cmd_buffer * cmd_buffer,struct radv_meta_blit2d_buffer * src,struct radv_buffer_view * bview,VkFormat depth_format)79 create_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src,
80 struct radv_buffer_view *bview, VkFormat depth_format)
81 {
82 VkFormat format;
83
84 if (depth_format)
85 format = depth_format;
86 else
87 format = src->format;
88 radv_buffer_view_init(bview, cmd_buffer->device,
89 &(VkBufferViewCreateInfo){
90 .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
91 .flags = 0,
92 .buffer = radv_buffer_to_handle(src->buffer),
93 .format = format,
94 .offset = src->offset,
95 .range = VK_WHOLE_SIZE,
96 });
97 }
98
99 struct blit2d_src_temps {
100 struct radv_image_view iview;
101 struct radv_buffer_view bview;
102 };
103
104 static void
blit2d_bind_src(struct radv_cmd_buffer * cmd_buffer,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)105 blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
106 struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp,
107 enum blit2d_src_type src_type, VkFormat depth_format, VkImageAspectFlagBits aspects,
108 uint32_t log2_samples)
109 {
110 struct radv_device *device = cmd_buffer->device;
111
112 if (src_type == BLIT2D_SRC_TYPE_BUFFER) {
113 create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format);
114
115 radv_meta_push_descriptor_set(
116 cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
117 device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
118 1, /* descriptorWriteCount */
119 (VkWriteDescriptorSet[]){
120 {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
121 .dstBinding = 0,
122 .dstArrayElement = 0,
123 .descriptorCount = 1,
124 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
125 .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(&tmp->bview)}}});
126
127 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
128 device->meta_state.blit2d[log2_samples].p_layouts[src_type],
129 VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch);
130 } else {
131 create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects);
132
133 if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
134 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
135 device->meta_state.blit2d[log2_samples].p_layouts[src_type],
136 VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_img->layer);
137
138 radv_meta_push_descriptor_set(
139 cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
140 device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
141 1, /* descriptorWriteCount */
142 (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
143 .dstBinding = 0,
144 .dstArrayElement = 0,
145 .descriptorCount = 1,
146 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
147 .pImageInfo = (VkDescriptorImageInfo[]){
148 {
149 .sampler = VK_NULL_HANDLE,
150 .imageView = radv_image_view_to_handle(&tmp->iview),
151 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
152 },
153 }}});
154 }
155 }
156
157 struct blit2d_dst_temps {
158 VkImage image;
159 struct radv_image_view iview;
160 VkFramebuffer fb;
161 };
162
163 static void
bind_pipeline(struct radv_cmd_buffer * cmd_buffer,enum blit2d_src_type src_type,unsigned fs_key,uint32_t log2_samples)164 bind_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type, unsigned fs_key,
165 uint32_t log2_samples)
166 {
167 VkPipeline pipeline =
168 cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key];
169
170 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
171 pipeline);
172 }
173
174 static void
bind_depth_pipeline(struct radv_cmd_buffer * cmd_buffer,enum blit2d_src_type src_type,uint32_t log2_samples)175 bind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
176 uint32_t log2_samples)
177 {
178 VkPipeline pipeline =
179 cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type];
180
181 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
182 pipeline);
183 }
184
185 static void
bind_stencil_pipeline(struct radv_cmd_buffer * cmd_buffer,enum blit2d_src_type src_type,uint32_t log2_samples)186 bind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
187 uint32_t log2_samples)
188 {
189 VkPipeline pipeline =
190 cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type];
191
192 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
193 pipeline);
194 }
195
196 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,unsigned num_rects,struct radv_meta_blit2d_rect * rects,enum blit2d_src_type src_type,uint32_t log2_samples)197 radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer,
198 struct radv_meta_blit2d_surf *src_img,
199 struct radv_meta_blit2d_buffer *src_buf,
200 struct radv_meta_blit2d_surf *dst, unsigned num_rects,
201 struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type,
202 uint32_t log2_samples)
203 {
204 struct radv_device *device = cmd_buffer->device;
205
206 for (unsigned r = 0; r < num_rects; ++r) {
207 u_foreach_bit(i, dst->aspect_mask)
208 {
209 unsigned aspect_mask = 1u << i;
210 unsigned src_aspect_mask = aspect_mask;
211 VkFormat depth_format = 0;
212 if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
213 depth_format = vk_format_stencil_only(dst->image->vk.format);
214 else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
215 depth_format = vk_format_depth_only(dst->image->vk.format);
216 else if (src_img)
217 src_aspect_mask = src_img->aspect_mask;
218
219 struct blit2d_src_temps src_temps;
220 blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format,
221 src_aspect_mask, log2_samples);
222
223 struct blit2d_dst_temps dst_temps;
224 create_iview(cmd_buffer, dst, &dst_temps.iview, depth_format, aspect_mask);
225
226 float vertex_push_constants[4] = {
227 rects[r].src_x,
228 rects[r].src_y,
229 rects[r].src_x + rects[r].width,
230 rects[r].src_y + rects[r].height,
231 };
232
233 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
234 device->meta_state.blit2d[log2_samples].p_layouts[src_type],
235 VK_SHADER_STAGE_VERTEX_BIT, 0, 16, vertex_push_constants);
236
237 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT ||
238 aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
239 aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT ||
240 aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
241 unsigned fs_key = radv_format_meta_fs_key(device, dst_temps.iview.vk.format);
242
243 if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] ==
244 VK_NULL_HANDLE) {
245 VkResult ret = blit2d_init_color_pipeline(
246 device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples);
247 if (ret != VK_SUCCESS) {
248 cmd_buffer->record_result = ret;
249 goto fail_pipeline;
250 }
251 }
252
253 const VkRenderingAttachmentInfo color_att_info = {
254 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
255 .imageView = radv_image_view_to_handle(&dst_temps.iview),
256 .imageLayout = dst->current_layout,
257 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
258 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
259 };
260
261 const VkRenderingInfo rendering_info = {
262 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
263 .renderArea = {
264 .offset = { rects[r].dst_x, rects[r].dst_y },
265 .extent = { rects[r].width, rects[r].height },
266 },
267 .layerCount = 1,
268 .colorAttachmentCount = 1,
269 .pColorAttachments = &color_att_info,
270 };
271
272 radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
273
274 bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples);
275 } else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
276 if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] ==
277 VK_NULL_HANDLE) {
278 VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples);
279 if (ret != VK_SUCCESS) {
280 cmd_buffer->record_result = ret;
281 goto fail_pipeline;
282 }
283 }
284
285 const VkRenderingAttachmentInfo depth_att_info = {
286 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
287 .imageView = radv_image_view_to_handle(&dst_temps.iview),
288 .imageLayout = dst->current_layout,
289 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
290 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
291 };
292
293 const VkRenderingInfo rendering_info = {
294 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
295 .renderArea = {
296 .offset = { rects[r].dst_x, rects[r].dst_y },
297 .extent = { rects[r].width, rects[r].height },
298 },
299 .layerCount = 1,
300 .pDepthAttachment = &depth_att_info,
301 .pStencilAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ?
302 &depth_att_info : NULL,
303 };
304
305 radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
306
307 bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
308
309 } else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
310 if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] ==
311 VK_NULL_HANDLE) {
312 VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples);
313 if (ret != VK_SUCCESS) {
314 cmd_buffer->record_result = ret;
315 goto fail_pipeline;
316 }
317 }
318
319 const VkRenderingAttachmentInfo stencil_att_info = {
320 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
321 .imageView = radv_image_view_to_handle(&dst_temps.iview),
322 .imageLayout = dst->current_layout,
323 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
324 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
325 };
326
327 const VkRenderingInfo rendering_info = {
328 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
329 .renderArea = {
330 .offset = { rects[r].dst_x, rects[r].dst_y },
331 .extent = { rects[r].width, rects[r].height },
332 },
333 .layerCount = 1,
334 .pDepthAttachment = (dst->image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ?
335 &stencil_att_info : NULL,
336 .pStencilAttachment = &stencil_att_info,
337 };
338
339 radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info);
340
341 bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
342 } else
343 unreachable("Processing blit2d with multiple aspects.");
344
345 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
346 &(VkViewport){.x = rects[r].dst_x,
347 .y = rects[r].dst_y,
348 .width = rects[r].width,
349 .height = rects[r].height,
350 .minDepth = 0.0f,
351 .maxDepth = 1.0f});
352
353 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
354 &(VkRect2D){
355 .offset = (VkOffset2D){rects[r].dst_x, rects[r].dst_y},
356 .extent = (VkExtent2D){rects[r].width, rects[r].height},
357 });
358
359 radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
360
361 radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer));
362
363 fail_pipeline:
364
365 if (src_type == BLIT2D_SRC_TYPE_BUFFER)
366 radv_buffer_view_finish(&src_temps.bview);
367 else
368 radv_image_view_finish(&src_temps.iview);
369
370 radv_image_view_finish(&dst_temps.iview);
371 }
372 }
373 }
374
375 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,unsigned num_rects,struct radv_meta_blit2d_rect * rects)376 radv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
377 struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
378 unsigned num_rects, struct radv_meta_blit2d_rect *rects)
379 {
380 bool use_3d = (src_img && src_img->image->vk.image_type == VK_IMAGE_TYPE_3D);
381 enum blit2d_src_type src_type = src_buf ? BLIT2D_SRC_TYPE_BUFFER
382 : use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D
383 : BLIT2D_SRC_TYPE_IMAGE;
384 radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, num_rects, rects, src_type,
385 src_img ? util_logbase2(src_img->image->info.samples) : 0);
386 }
387
388 static nir_shader *
build_nir_vertex_shader(struct radv_device * device)389 build_nir_vertex_shader(struct radv_device *device)
390 {
391 const struct glsl_type *vec4 = glsl_vec4_type();
392 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
393 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_VERTEX, "meta_blit2d_vs");
394
395 nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
396 pos_out->data.location = VARYING_SLOT_POS;
397
398 nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos");
399 tex_pos_out->data.location = VARYING_SLOT_VAR0;
400 tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
401
402 nir_ssa_def *outvec = nir_gen_rect_vertices(&b, NULL, NULL);
403 nir_store_var(&b, pos_out, outvec, 0xf);
404
405 nir_ssa_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
406 nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(&b);
407
408 /* vertex 0 - src_x, src_y */
409 /* vertex 1 - src_x, src_y+h */
410 /* vertex 2 - src_x+w, src_y */
411 /* so channel 0 is vertex_id != 2 ? src_x : src_x + w
412 channel 1 is vertex id != 1 ? src_y : src_y + w */
413
414 nir_ssa_def *c0cmp = nir_ine_imm(&b, vertex_id, 2);
415 nir_ssa_def *c1cmp = nir_ine_imm(&b, vertex_id, 1);
416
417 nir_ssa_def *comp[2];
418 comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
419
420 comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
421 nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 2);
422 nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3);
423 return b.shader;
424 }
425
426 typedef nir_ssa_def *(*texel_fetch_build_func)(struct nir_builder *, struct radv_device *,
427 nir_ssa_def *, bool, bool);
428
429 static nir_ssa_def *
build_nir_texel_fetch(struct nir_builder * b,struct radv_device * device,nir_ssa_def * tex_pos,bool is_3d,bool is_multisampled)430 build_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
431 bool is_3d, bool is_multisampled)
432 {
433 enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D
434 : is_multisampled ? GLSL_SAMPLER_DIM_MS
435 : GLSL_SAMPLER_DIM_2D;
436 const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT);
437 nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
438 sampler->data.descriptor_set = 0;
439 sampler->data.binding = 0;
440
441 nir_ssa_def *tex_pos_3d = NULL;
442 nir_ssa_def *sample_idx = NULL;
443 if (is_3d) {
444 nir_ssa_def *layer =
445 nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
446
447 nir_ssa_def *chans[3];
448 chans[0] = nir_channel(b, tex_pos, 0);
449 chans[1] = nir_channel(b, tex_pos, 1);
450 chans[2] = layer;
451 tex_pos_3d = nir_vec(b, chans, 3);
452 }
453 if (is_multisampled) {
454 sample_idx = nir_load_sample_id(b);
455 }
456
457 nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
458
459 nir_tex_instr *tex = nir_tex_instr_create(b->shader, is_multisampled ? 4 : 3);
460 tex->sampler_dim = dim;
461 tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
462 tex->src[0].src_type = nir_tex_src_coord;
463 tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : tex_pos);
464 tex->src[1].src_type = is_multisampled ? nir_tex_src_ms_index : nir_tex_src_lod;
465 tex->src[1].src = nir_src_for_ssa(is_multisampled ? sample_idx : nir_imm_int(b, 0));
466 tex->src[2].src_type = nir_tex_src_texture_deref;
467 tex->src[2].src = nir_src_for_ssa(tex_deref);
468 if (is_multisampled) {
469 tex->src[3].src_type = nir_tex_src_lod;
470 tex->src[3].src = nir_src_for_ssa(nir_imm_int(b, 0));
471 }
472 tex->dest_type = nir_type_uint32;
473 tex->is_array = false;
474 tex->coord_components = is_3d ? 3 : 2;
475
476 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
477 nir_builder_instr_insert(b, &tex->instr);
478
479 return &tex->dest.ssa;
480 }
481
482 static nir_ssa_def *
build_nir_buffer_fetch(struct nir_builder * b,struct radv_device * device,nir_ssa_def * tex_pos,bool is_3d,bool is_multisampled)483 build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
484 bool is_3d, bool is_multisampled)
485 {
486 const struct glsl_type *sampler_type =
487 glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT);
488 nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
489 sampler->data.descriptor_set = 0;
490 sampler->data.binding = 0;
491
492 nir_ssa_def *width = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
493
494 nir_ssa_def *pos_x = nir_channel(b, tex_pos, 0);
495 nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1);
496 pos_y = nir_imul(b, pos_y, width);
497 pos_x = nir_iadd(b, pos_x, pos_y);
498
499 nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
500
501 nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2);
502 tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
503 tex->op = nir_texop_txf;
504 tex->src[0].src_type = nir_tex_src_coord;
505 tex->src[0].src = nir_src_for_ssa(pos_x);
506 tex->src[1].src_type = nir_tex_src_texture_deref;
507 tex->src[1].src = nir_src_for_ssa(tex_deref);
508 tex->dest_type = nir_type_uint32;
509 tex->is_array = false;
510 tex->coord_components = 1;
511
512 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
513 nir_builder_instr_insert(b, &tex->instr);
514
515 return &tex->dest.ssa;
516 }
517
518 static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
519 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
520 .vertexBindingDescriptionCount = 0,
521 .vertexAttributeDescriptionCount = 0,
522 };
523
524 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)525 build_nir_copy_fragment_shader(struct radv_device *device, texel_fetch_build_func txf_func,
526 const char *name, bool is_3d, bool is_multisampled)
527 {
528 const struct glsl_type *vec4 = glsl_vec4_type();
529 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
530 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
531
532 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
533 tex_pos_in->data.location = VARYING_SLOT_VAR0;
534
535 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
536 color_out->data.location = FRAG_RESULT_DATA0;
537
538 nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
539 nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
540
541 nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
542 nir_store_var(&b, color_out, color, 0xf);
543
544 b.shader->info.fs.uses_sample_shading = is_multisampled;
545
546 return b.shader;
547 }
548
549 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)550 build_nir_copy_fragment_shader_depth(struct radv_device *device, texel_fetch_build_func txf_func,
551 const char *name, bool is_3d, bool is_multisampled)
552 {
553 const struct glsl_type *vec4 = glsl_vec4_type();
554 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
555 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
556
557 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
558 tex_pos_in->data.location = VARYING_SLOT_VAR0;
559
560 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
561 color_out->data.location = FRAG_RESULT_DEPTH;
562
563 nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
564 nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
565
566 nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
567 nir_store_var(&b, color_out, color, 0x1);
568
569 b.shader->info.fs.uses_sample_shading = is_multisampled;
570
571 return b.shader;
572 }
573
574 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)575 build_nir_copy_fragment_shader_stencil(struct radv_device *device, texel_fetch_build_func txf_func,
576 const char *name, bool is_3d, bool is_multisampled)
577 {
578 const struct glsl_type *vec4 = glsl_vec4_type();
579 const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
580 nir_builder b = radv_meta_init_shader(device, MESA_SHADER_FRAGMENT, "%s", name);
581
582 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
583 tex_pos_in->data.location = VARYING_SLOT_VAR0;
584
585 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
586 color_out->data.location = FRAG_RESULT_STENCIL;
587
588 nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
589 nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
590
591 nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
592 nir_store_var(&b, color_out, color, 0x1);
593
594 b.shader->info.fs.uses_sample_shading = is_multisampled;
595
596 return b.shader;
597 }
598
599 void
radv_device_finish_meta_blit2d_state(struct radv_device * device)600 radv_device_finish_meta_blit2d_state(struct radv_device *device)
601 {
602 struct radv_meta_state *state = &device->meta_state;
603
604 for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; ++log2_samples) {
605 for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
606 radv_DestroyPipelineLayout(radv_device_to_handle(device),
607 state->blit2d[log2_samples].p_layouts[src], &state->alloc);
608 device->vk.dispatch_table.DestroyDescriptorSetLayout(
609 radv_device_to_handle(device), state->blit2d[log2_samples].ds_layouts[src],
610 &state->alloc);
611
612 for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
613 radv_DestroyPipeline(radv_device_to_handle(device),
614 state->blit2d[log2_samples].pipelines[src][j], &state->alloc);
615 }
616
617 radv_DestroyPipeline(radv_device_to_handle(device),
618 state->blit2d[log2_samples].depth_only_pipeline[src], &state->alloc);
619 radv_DestroyPipeline(radv_device_to_handle(device),
620 state->blit2d[log2_samples].stencil_only_pipeline[src],
621 &state->alloc);
622 }
623 }
624 }
625
626 static VkResult
blit2d_init_color_pipeline(struct radv_device * device,enum blit2d_src_type src_type,VkFormat format,uint32_t log2_samples)627 blit2d_init_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
628 VkFormat format, uint32_t log2_samples)
629 {
630 VkResult result;
631 unsigned fs_key = radv_format_meta_fs_key(device, format);
632 const char *name;
633
634 mtx_lock(&device->meta_state.mtx);
635 if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) {
636 mtx_unlock(&device->meta_state.mtx);
637 return VK_SUCCESS;
638 }
639
640 texel_fetch_build_func src_func;
641 switch (src_type) {
642 case BLIT2D_SRC_TYPE_IMAGE:
643 src_func = build_nir_texel_fetch;
644 name = "meta_blit2d_image_fs";
645 break;
646 case BLIT2D_SRC_TYPE_IMAGE_3D:
647 src_func = build_nir_texel_fetch;
648 name = "meta_blit3d_image_fs";
649 break;
650 case BLIT2D_SRC_TYPE_BUFFER:
651 src_func = build_nir_buffer_fetch;
652 name = "meta_blit2d_buffer_fs";
653 break;
654 default:
655 unreachable("unknown blit src type\n");
656 break;
657 }
658
659 const VkPipelineVertexInputStateCreateInfo *vi_create_info;
660 nir_shader *fs = build_nir_copy_fragment_shader(
661 device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
662 nir_shader *vs = build_nir_vertex_shader(device);
663
664 vi_create_info = &normal_vi_create_info;
665
666 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
667 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
668 .stage = VK_SHADER_STAGE_VERTEX_BIT,
669 .module = vk_shader_module_handle_from_nir(vs),
670 .pName = "main",
671 .pSpecializationInfo = NULL},
672 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
673 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
674 .module = vk_shader_module_handle_from_nir(fs),
675 .pName = "main",
676 .pSpecializationInfo = NULL},
677 };
678
679 const VkPipelineRenderingCreateInfo rendering_create_info = {
680 .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
681 .colorAttachmentCount = 1,
682 .pColorAttachmentFormats = &format,
683 };
684
685 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
686 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
687 .pNext = &rendering_create_info,
688 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
689 .pStages = pipeline_shader_stages,
690 .pVertexInputState = vi_create_info,
691 .pInputAssemblyState =
692 &(VkPipelineInputAssemblyStateCreateInfo){
693 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
694 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
695 .primitiveRestartEnable = false,
696 },
697 .pViewportState =
698 &(VkPipelineViewportStateCreateInfo){
699 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
700 .viewportCount = 1,
701 .scissorCount = 1,
702 },
703 .pRasterizationState =
704 &(VkPipelineRasterizationStateCreateInfo){
705 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
706 .rasterizerDiscardEnable = false,
707 .polygonMode = VK_POLYGON_MODE_FILL,
708 .cullMode = VK_CULL_MODE_NONE,
709 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
710 .depthBiasConstantFactor = 0.0f,
711 .depthBiasClamp = 0.0f,
712 .depthBiasSlopeFactor = 0.0f,
713 .lineWidth = 1.0f},
714 .pMultisampleState =
715 &(VkPipelineMultisampleStateCreateInfo){
716 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
717 .rasterizationSamples = 1 << log2_samples,
718 .sampleShadingEnable = log2_samples > 1,
719 .minSampleShading = 1.0,
720 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
721 },
722 .pColorBlendState =
723 &(VkPipelineColorBlendStateCreateInfo){
724 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
725 .attachmentCount = 1,
726 .pAttachments =
727 (VkPipelineColorBlendAttachmentState[]){
728 {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |
729 VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},
730 },
731 .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }},
732 .pDynamicState =
733 &(VkPipelineDynamicStateCreateInfo){
734 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
735 .dynamicStateCount = 2,
736 .pDynamicStates =
737 (VkDynamicState[]){
738 VK_DYNAMIC_STATE_VIEWPORT,
739 VK_DYNAMIC_STATE_SCISSOR,
740 },
741 },
742 .flags = 0,
743 .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
744 .renderPass = VK_NULL_HANDLE,
745 .subpass = 0,
746 };
747
748 const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
749
750 result = radv_graphics_pipeline_create(
751 radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
752 &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
753 &device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]);
754
755 ralloc_free(vs);
756 ralloc_free(fs);
757
758 mtx_unlock(&device->meta_state.mtx);
759 return result;
760 }
761
762 static VkResult
blit2d_init_depth_only_pipeline(struct radv_device * device,enum blit2d_src_type src_type,uint32_t log2_samples)763 blit2d_init_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
764 uint32_t log2_samples)
765 {
766 VkResult result;
767 const char *name;
768
769 mtx_lock(&device->meta_state.mtx);
770 if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) {
771 mtx_unlock(&device->meta_state.mtx);
772 return VK_SUCCESS;
773 }
774
775 texel_fetch_build_func src_func;
776 switch (src_type) {
777 case BLIT2D_SRC_TYPE_IMAGE:
778 src_func = build_nir_texel_fetch;
779 name = "meta_blit2d_depth_image_fs";
780 break;
781 case BLIT2D_SRC_TYPE_IMAGE_3D:
782 src_func = build_nir_texel_fetch;
783 name = "meta_blit3d_depth_image_fs";
784 break;
785 case BLIT2D_SRC_TYPE_BUFFER:
786 src_func = build_nir_buffer_fetch;
787 name = "meta_blit2d_depth_buffer_fs";
788 break;
789 default:
790 unreachable("unknown blit src type\n");
791 break;
792 }
793
794 const VkPipelineVertexInputStateCreateInfo *vi_create_info;
795 nir_shader *fs = build_nir_copy_fragment_shader_depth(
796 device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
797 nir_shader *vs = build_nir_vertex_shader(device);
798
799 vi_create_info = &normal_vi_create_info;
800
801 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
802 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
803 .stage = VK_SHADER_STAGE_VERTEX_BIT,
804 .module = vk_shader_module_handle_from_nir(vs),
805 .pName = "main",
806 .pSpecializationInfo = NULL},
807 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
808 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
809 .module = vk_shader_module_handle_from_nir(fs),
810 .pName = "main",
811 .pSpecializationInfo = NULL},
812 };
813
814 const VkPipelineRenderingCreateInfo rendering_create_info = {
815 .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
816 .depthAttachmentFormat = VK_FORMAT_D32_SFLOAT,
817 };
818
819 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
820 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
821 .pNext = &rendering_create_info,
822 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
823 .pStages = pipeline_shader_stages,
824 .pVertexInputState = vi_create_info,
825 .pInputAssemblyState =
826 &(VkPipelineInputAssemblyStateCreateInfo){
827 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
828 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
829 .primitiveRestartEnable = false,
830 },
831 .pViewportState =
832 &(VkPipelineViewportStateCreateInfo){
833 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
834 .viewportCount = 1,
835 .scissorCount = 1,
836 },
837 .pRasterizationState =
838 &(VkPipelineRasterizationStateCreateInfo){
839 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
840 .rasterizerDiscardEnable = false,
841 .polygonMode = VK_POLYGON_MODE_FILL,
842 .cullMode = VK_CULL_MODE_NONE,
843 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
844 .depthBiasConstantFactor = 0.0f,
845 .depthBiasClamp = 0.0f,
846 .depthBiasSlopeFactor = 0.0f,
847 .lineWidth = 1.0f},
848 .pMultisampleState =
849 &(VkPipelineMultisampleStateCreateInfo){
850 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
851 .rasterizationSamples = 1 << log2_samples,
852 .sampleShadingEnable = false,
853 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
854 },
855 .pColorBlendState =
856 &(VkPipelineColorBlendStateCreateInfo){
857 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
858 .attachmentCount = 0,
859 .pAttachments = NULL,
860 .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
861 },
862 .pDepthStencilState =
863 &(VkPipelineDepthStencilStateCreateInfo){
864 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
865 .depthTestEnable = true,
866 .depthWriteEnable = true,
867 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
868 .front = {
869 .failOp = VK_STENCIL_OP_KEEP,
870 .passOp = VK_STENCIL_OP_KEEP,
871 .depthFailOp = VK_STENCIL_OP_KEEP,
872 .compareOp = VK_COMPARE_OP_NEVER,
873 .compareMask = UINT32_MAX,
874 .writeMask = UINT32_MAX,
875 .reference = 0u,
876 },
877 .back = {
878 .failOp = VK_STENCIL_OP_KEEP,
879 .passOp = VK_STENCIL_OP_KEEP,
880 .depthFailOp = VK_STENCIL_OP_KEEP,
881 .compareOp = VK_COMPARE_OP_NEVER,
882 .compareMask = UINT32_MAX,
883 .writeMask = UINT32_MAX,
884 .reference = 0u,
885 },
886 .minDepthBounds = 0.0f,
887 .maxDepthBounds = 1.0f,
888 },
889 .pDynamicState =
890 &(VkPipelineDynamicStateCreateInfo){
891 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
892 .dynamicStateCount = 2,
893 .pDynamicStates =
894 (VkDynamicState[]){
895 VK_DYNAMIC_STATE_VIEWPORT,
896 VK_DYNAMIC_STATE_SCISSOR,
897 },
898 },
899 .flags = 0,
900 .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
901 .renderPass = VK_NULL_HANDLE,
902 .subpass = 0,
903 };
904
905 const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
906
907 result = radv_graphics_pipeline_create(
908 radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
909 &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
910 &device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]);
911
912 ralloc_free(vs);
913 ralloc_free(fs);
914
915 mtx_unlock(&device->meta_state.mtx);
916 return result;
917 }
918
919 static VkResult
blit2d_init_stencil_only_pipeline(struct radv_device * device,enum blit2d_src_type src_type,uint32_t log2_samples)920 blit2d_init_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
921 uint32_t log2_samples)
922 {
923 VkResult result;
924 const char *name;
925
926 mtx_lock(&device->meta_state.mtx);
927 if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) {
928 mtx_unlock(&device->meta_state.mtx);
929 return VK_SUCCESS;
930 }
931
932 texel_fetch_build_func src_func;
933 switch (src_type) {
934 case BLIT2D_SRC_TYPE_IMAGE:
935 src_func = build_nir_texel_fetch;
936 name = "meta_blit2d_stencil_image_fs";
937 break;
938 case BLIT2D_SRC_TYPE_IMAGE_3D:
939 src_func = build_nir_texel_fetch;
940 name = "meta_blit3d_stencil_image_fs";
941 break;
942 case BLIT2D_SRC_TYPE_BUFFER:
943 src_func = build_nir_buffer_fetch;
944 name = "meta_blit2d_stencil_buffer_fs";
945 break;
946 default:
947 unreachable("unknown blit src type\n");
948 break;
949 }
950
951 const VkPipelineVertexInputStateCreateInfo *vi_create_info;
952 nir_shader *fs = build_nir_copy_fragment_shader_stencil(
953 device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
954 nir_shader *vs = build_nir_vertex_shader(device);
955
956 vi_create_info = &normal_vi_create_info;
957
958 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
959 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
960 .stage = VK_SHADER_STAGE_VERTEX_BIT,
961 .module = vk_shader_module_handle_from_nir(vs),
962 .pName = "main",
963 .pSpecializationInfo = NULL},
964 {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
965 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
966 .module = vk_shader_module_handle_from_nir(fs),
967 .pName = "main",
968 .pSpecializationInfo = NULL},
969 };
970
971 const VkPipelineRenderingCreateInfo rendering_create_info = {
972 .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
973 .stencilAttachmentFormat = VK_FORMAT_S8_UINT,
974 };
975
976 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
977 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
978 .pNext = &rendering_create_info,
979 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
980 .pStages = pipeline_shader_stages,
981 .pVertexInputState = vi_create_info,
982 .pInputAssemblyState =
983 &(VkPipelineInputAssemblyStateCreateInfo){
984 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
985 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
986 .primitiveRestartEnable = false,
987 },
988 .pViewportState =
989 &(VkPipelineViewportStateCreateInfo){
990 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
991 .viewportCount = 1,
992 .scissorCount = 1,
993 },
994 .pRasterizationState =
995 &(VkPipelineRasterizationStateCreateInfo){
996 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
997 .rasterizerDiscardEnable = false,
998 .polygonMode = VK_POLYGON_MODE_FILL,
999 .cullMode = VK_CULL_MODE_NONE,
1000 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
1001 .depthBiasConstantFactor = 0.0f,
1002 .depthBiasClamp = 0.0f,
1003 .depthBiasSlopeFactor = 0.0f,
1004 .lineWidth = 1.0f},
1005 .pMultisampleState =
1006 &(VkPipelineMultisampleStateCreateInfo){
1007 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1008 .rasterizationSamples = 1 << log2_samples,
1009 .sampleShadingEnable = false,
1010 .pSampleMask = (VkSampleMask[]){UINT32_MAX},
1011 },
1012 .pColorBlendState =
1013 &(VkPipelineColorBlendStateCreateInfo){
1014 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1015 .attachmentCount = 0,
1016 .pAttachments = NULL,
1017 .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
1018 },
1019 .pDepthStencilState =
1020 &(VkPipelineDepthStencilStateCreateInfo){
1021 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1022 .depthTestEnable = false,
1023 .depthWriteEnable = false,
1024 .stencilTestEnable = true,
1025 .front = {.failOp = VK_STENCIL_OP_REPLACE,
1026 .passOp = VK_STENCIL_OP_REPLACE,
1027 .depthFailOp = VK_STENCIL_OP_REPLACE,
1028 .compareOp = VK_COMPARE_OP_ALWAYS,
1029 .compareMask = 0xff,
1030 .writeMask = 0xff,
1031 .reference = 0},
1032 .back = {.failOp = VK_STENCIL_OP_REPLACE,
1033 .passOp = VK_STENCIL_OP_REPLACE,
1034 .depthFailOp = VK_STENCIL_OP_REPLACE,
1035 .compareOp = VK_COMPARE_OP_ALWAYS,
1036 .compareMask = 0xff,
1037 .writeMask = 0xff,
1038 .reference = 0},
1039 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
1040 .minDepthBounds = 0.0f,
1041 .maxDepthBounds = 1.0f,
1042 },
1043 .pDynamicState =
1044 &(VkPipelineDynamicStateCreateInfo){
1045 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1046 .dynamicStateCount = 2,
1047 .pDynamicStates =
1048 (VkDynamicState[]){
1049 VK_DYNAMIC_STATE_VIEWPORT,
1050 VK_DYNAMIC_STATE_SCISSOR,
1051 },
1052 },
1053 .flags = 0,
1054 .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1055 .renderPass = VK_NULL_HANDLE,
1056 .subpass = 0,
1057 };
1058
1059 const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
1060
1061 result = radv_graphics_pipeline_create(
1062 radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
1063 &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
1064 &device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]);
1065
1066 ralloc_free(vs);
1067 ralloc_free(fs);
1068
1069 mtx_unlock(&device->meta_state.mtx);
1070 return result;
1071 }
1072
1073 static VkResult
meta_blit2d_create_pipe_layout(struct radv_device * device,int idx,uint32_t log2_samples)1074 meta_blit2d_create_pipe_layout(struct radv_device *device, int idx, uint32_t log2_samples)
1075 {
1076 VkResult result;
1077 VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER)
1078 ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
1079 : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1080 const VkPushConstantRange push_constant_ranges[] = {
1081 {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
1082 {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
1083 };
1084 int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
1085
1086 result = radv_CreateDescriptorSetLayout(
1087 radv_device_to_handle(device),
1088 &(VkDescriptorSetLayoutCreateInfo){
1089 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1090 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1091 .bindingCount = 1,
1092 .pBindings =
1093 (VkDescriptorSetLayoutBinding[]){
1094 {.binding = 0,
1095 .descriptorType = desc_type,
1096 .descriptorCount = 1,
1097 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1098 .pImmutableSamplers = NULL},
1099 }},
1100 &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].ds_layouts[idx]);
1101 if (result != VK_SUCCESS)
1102 goto fail;
1103
1104 result = radv_CreatePipelineLayout(
1105 radv_device_to_handle(device),
1106 &(VkPipelineLayoutCreateInfo){
1107 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1108 .setLayoutCount = 1,
1109 .pSetLayouts = &device->meta_state.blit2d[log2_samples].ds_layouts[idx],
1110 .pushConstantRangeCount = num_push_constant_range,
1111 .pPushConstantRanges = push_constant_ranges,
1112 },
1113 &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].p_layouts[idx]);
1114 if (result != VK_SUCCESS)
1115 goto fail;
1116 return VK_SUCCESS;
1117 fail:
1118 return result;
1119 }
1120
1121 VkResult
radv_device_init_meta_blit2d_state(struct radv_device * device,bool on_demand)1122 radv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand)
1123 {
1124 VkResult result;
1125
1126 for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; log2_samples++) {
1127 for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
1128 /* Don't need to handle copies between buffers and multisample images. */
1129 if (src == BLIT2D_SRC_TYPE_BUFFER && log2_samples > 0)
1130 continue;
1131
1132 /* There are no multisampled 3D images. */
1133 if (src == BLIT2D_SRC_TYPE_IMAGE_3D && log2_samples > 0)
1134 continue;
1135
1136 result = meta_blit2d_create_pipe_layout(device, src, log2_samples);
1137 if (result != VK_SUCCESS)
1138 return result;
1139
1140 if (on_demand)
1141 continue;
1142
1143 for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
1144 result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j],
1145 log2_samples);
1146 if (result != VK_SUCCESS)
1147 return result;
1148 }
1149
1150 result = blit2d_init_depth_only_pipeline(device, src, log2_samples);
1151 if (result != VK_SUCCESS)
1152 return result;
1153
1154 result = blit2d_init_stencil_only_pipeline(device, src, log2_samples);
1155 if (result != VK_SUCCESS)
1156 return result;
1157 }
1158 }
1159
1160 return VK_SUCCESS;
1161 }
1162