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