Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/amd/vulkan/radv_meta_blit2d.c
7233 views
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
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
VkImageViewType view_type = cmd_buffer->device->physical_device->rad_info.chip_class < GFX9
56
? VK_IMAGE_VIEW_TYPE_2D
57
: radv_meta_get_view_type(surf->image);
58
59
if (depth_format)
60
format = depth_format;
61
else
62
format = surf->format;
63
64
radv_image_view_init(iview, cmd_buffer->device,
65
&(VkImageViewCreateInfo){
66
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
67
.image = radv_image_to_handle(surf->image),
68
.viewType = view_type,
69
.format = format,
70
.subresourceRange = {.aspectMask = aspects,
71
.baseMipLevel = surf->level,
72
.levelCount = 1,
73
.baseArrayLayer = surf->layer,
74
.layerCount = 1},
75
},
76
NULL);
77
}
78
79
static void
80
create_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src,
81
struct radv_buffer_view *bview, VkFormat depth_format)
82
{
83
VkFormat format;
84
85
if (depth_format)
86
format = depth_format;
87
else
88
format = src->format;
89
radv_buffer_view_init(bview, cmd_buffer->device,
90
&(VkBufferViewCreateInfo){
91
.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
92
.flags = 0,
93
.buffer = radv_buffer_to_handle(src->buffer),
94
.format = format,
95
.offset = src->offset,
96
.range = VK_WHOLE_SIZE,
97
});
98
}
99
100
struct blit2d_src_temps {
101
struct radv_image_view iview;
102
struct radv_buffer_view bview;
103
};
104
105
static void
106
blit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
107
struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp,
108
enum blit2d_src_type src_type, VkFormat depth_format, VkImageAspectFlagBits aspects,
109
uint32_t log2_samples)
110
{
111
struct radv_device *device = cmd_buffer->device;
112
113
if (src_type == BLIT2D_SRC_TYPE_BUFFER) {
114
create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format);
115
116
radv_meta_push_descriptor_set(
117
cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
118
device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
119
1, /* descriptorWriteCount */
120
(VkWriteDescriptorSet[]){
121
{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
122
.dstBinding = 0,
123
.dstArrayElement = 0,
124
.descriptorCount = 1,
125
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
126
.pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(&tmp->bview)}}});
127
128
radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
129
device->meta_state.blit2d[log2_samples].p_layouts[src_type],
130
VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch);
131
} else {
132
create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects);
133
134
if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
135
radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
136
device->meta_state.blit2d[log2_samples].p_layouts[src_type],
137
VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_img->layer);
138
139
radv_meta_push_descriptor_set(
140
cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
141
device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
142
1, /* descriptorWriteCount */
143
(VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
144
.dstBinding = 0,
145
.dstArrayElement = 0,
146
.descriptorCount = 1,
147
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
148
.pImageInfo = (VkDescriptorImageInfo[]){
149
{
150
.sampler = VK_NULL_HANDLE,
151
.imageView = radv_image_view_to_handle(&tmp->iview),
152
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
153
},
154
}}});
155
}
156
}
157
158
struct blit2d_dst_temps {
159
VkImage image;
160
struct radv_image_view iview;
161
VkFramebuffer fb;
162
};
163
164
static void
165
blit2d_bind_dst(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *dst,
166
uint32_t width, uint32_t height, VkFormat depth_format,
167
struct blit2d_dst_temps *tmp, VkImageAspectFlagBits aspects)
168
{
169
create_iview(cmd_buffer, dst, &tmp->iview, depth_format, aspects);
170
171
radv_CreateFramebuffer(
172
radv_device_to_handle(cmd_buffer->device),
173
&(VkFramebufferCreateInfo){.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
174
.attachmentCount = 1,
175
.pAttachments =
176
(VkImageView[]){
177
radv_image_view_to_handle(&tmp->iview),
178
},
179
.width = width,
180
.height = height,
181
.layers = 1},
182
&cmd_buffer->pool->alloc, &tmp->fb);
183
}
184
185
static void
186
bind_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type, unsigned fs_key,
187
uint32_t log2_samples)
188
{
189
VkPipeline pipeline =
190
cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key];
191
192
radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
193
pipeline);
194
}
195
196
static void
197
bind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
198
uint32_t log2_samples)
199
{
200
VkPipeline pipeline =
201
cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type];
202
203
radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
204
pipeline);
205
}
206
207
static void
208
bind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
209
uint32_t log2_samples)
210
{
211
VkPipeline pipeline =
212
cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type];
213
214
radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
215
pipeline);
216
}
217
218
static void
219
radv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer,
220
struct radv_meta_blit2d_surf *src_img,
221
struct radv_meta_blit2d_buffer *src_buf,
222
struct radv_meta_blit2d_surf *dst, unsigned num_rects,
223
struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type,
224
uint32_t log2_samples)
225
{
226
struct radv_device *device = cmd_buffer->device;
227
228
for (unsigned r = 0; r < num_rects; ++r) {
229
u_foreach_bit(i, dst->aspect_mask)
230
{
231
unsigned aspect_mask = 1u << i;
232
unsigned src_aspect_mask = aspect_mask;
233
VkFormat depth_format = 0;
234
if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
235
depth_format = vk_format_stencil_only(dst->image->vk_format);
236
else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
237
depth_format = vk_format_depth_only(dst->image->vk_format);
238
else if (src_img)
239
src_aspect_mask = src_img->aspect_mask;
240
241
struct blit2d_src_temps src_temps;
242
blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format,
243
src_aspect_mask, log2_samples);
244
245
struct blit2d_dst_temps dst_temps;
246
blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width,
247
rects[r].dst_y + rects[r].height, depth_format, &dst_temps, aspect_mask);
248
249
float vertex_push_constants[4] = {
250
rects[r].src_x,
251
rects[r].src_y,
252
rects[r].src_x + rects[r].width,
253
rects[r].src_y + rects[r].height,
254
};
255
256
radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
257
device->meta_state.blit2d[log2_samples].p_layouts[src_type],
258
VK_SHADER_STAGE_VERTEX_BIT, 0, 16, vertex_push_constants);
259
260
if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT ||
261
aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
262
aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT ||
263
aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
264
unsigned fs_key = radv_format_meta_fs_key(device, dst_temps.iview.vk_format);
265
unsigned dst_layout = radv_meta_dst_layout_from_layout(dst->current_layout);
266
267
if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] ==
268
VK_NULL_HANDLE) {
269
VkResult ret = blit2d_init_color_pipeline(
270
device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples);
271
if (ret != VK_SUCCESS) {
272
cmd_buffer->record_result = ret;
273
goto fail_pipeline;
274
}
275
}
276
277
radv_cmd_buffer_begin_render_pass(
278
cmd_buffer,
279
&(VkRenderPassBeginInfo){
280
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
281
.renderPass = device->meta_state.blit2d_render_passes[fs_key][dst_layout],
282
.framebuffer = dst_temps.fb,
283
.renderArea =
284
{
285
.offset =
286
{
287
rects[r].dst_x,
288
rects[r].dst_y,
289
},
290
.extent = {rects[r].width, rects[r].height},
291
},
292
.clearValueCount = 0,
293
.pClearValues = NULL,
294
},
295
&(struct radv_extra_render_pass_begin_info){.disable_dcc =
296
dst->disable_compression});
297
298
radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
299
300
bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples);
301
} else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
302
enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
303
304
if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] ==
305
VK_NULL_HANDLE) {
306
VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples);
307
if (ret != VK_SUCCESS) {
308
cmd_buffer->record_result = ret;
309
goto fail_pipeline;
310
}
311
}
312
313
radv_cmd_buffer_begin_render_pass(
314
cmd_buffer,
315
&(VkRenderPassBeginInfo){
316
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
317
.renderPass = device->meta_state.blit2d_depth_only_rp[ds_layout],
318
.framebuffer = dst_temps.fb,
319
.renderArea =
320
{
321
.offset =
322
{
323
rects[r].dst_x,
324
rects[r].dst_y,
325
},
326
.extent = {rects[r].width, rects[r].height},
327
},
328
.clearValueCount = 0,
329
.pClearValues = NULL,
330
},
331
NULL);
332
333
radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
334
335
bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
336
337
} else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
338
enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
339
340
if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] ==
341
VK_NULL_HANDLE) {
342
VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples);
343
if (ret != VK_SUCCESS) {
344
cmd_buffer->record_result = ret;
345
goto fail_pipeline;
346
}
347
}
348
349
radv_cmd_buffer_begin_render_pass(
350
cmd_buffer,
351
&(VkRenderPassBeginInfo){
352
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
353
.renderPass = device->meta_state.blit2d_stencil_only_rp[ds_layout],
354
.framebuffer = dst_temps.fb,
355
.renderArea =
356
{
357
.offset =
358
{
359
rects[r].dst_x,
360
rects[r].dst_y,
361
},
362
.extent = {rects[r].width, rects[r].height},
363
},
364
.clearValueCount = 0,
365
.pClearValues = NULL,
366
},
367
NULL);
368
369
radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
370
371
bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
372
} else
373
unreachable("Processing blit2d with multiple aspects.");
374
375
radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
376
&(VkViewport){.x = rects[r].dst_x,
377
.y = rects[r].dst_y,
378
.width = rects[r].width,
379
.height = rects[r].height,
380
.minDepth = 0.0f,
381
.maxDepth = 1.0f});
382
383
radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
384
&(VkRect2D){
385
.offset = (VkOffset2D){rects[r].dst_x, rects[r].dst_y},
386
.extent = (VkExtent2D){rects[r].width, rects[r].height},
387
});
388
389
radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
390
radv_cmd_buffer_end_render_pass(cmd_buffer);
391
392
fail_pipeline:
393
/* At the point where we emit the draw call, all data from the
394
* descriptor sets, etc. has been used. We are free to delete it.
395
*/
396
radv_DestroyFramebuffer(radv_device_to_handle(device), dst_temps.fb,
397
&cmd_buffer->pool->alloc);
398
}
399
}
400
}
401
402
void
403
radv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
404
struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
405
unsigned num_rects, struct radv_meta_blit2d_rect *rects)
406
{
407
bool use_3d = cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9 &&
408
(src_img && src_img->image->type == VK_IMAGE_TYPE_3D);
409
enum blit2d_src_type src_type = src_buf ? BLIT2D_SRC_TYPE_BUFFER
410
: use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D
411
: BLIT2D_SRC_TYPE_IMAGE;
412
radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, num_rects, rects, src_type,
413
src_img ? util_logbase2(src_img->image->info.samples) : 0);
414
}
415
416
static nir_shader *
417
build_nir_vertex_shader(void)
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 = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL, "meta_blit2d_vs");
422
423
nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
424
pos_out->data.location = VARYING_SLOT_POS;
425
426
nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos");
427
tex_pos_out->data.location = VARYING_SLOT_VAR0;
428
tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
429
430
nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b);
431
nir_store_var(&b, pos_out, outvec, 0xf);
432
433
nir_ssa_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
434
nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(&b);
435
436
/* vertex 0 - src_x, src_y */
437
/* vertex 1 - src_x, src_y+h */
438
/* vertex 2 - src_x+w, src_y */
439
/* so channel 0 is vertex_id != 2 ? src_x : src_x + w
440
channel 1 is vertex id != 1 ? src_y : src_y + w */
441
442
nir_ssa_def *c0cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 2));
443
nir_ssa_def *c1cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 1));
444
445
nir_ssa_def *comp[2];
446
comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
447
448
comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
449
nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 2);
450
nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3);
451
return b.shader;
452
}
453
454
typedef nir_ssa_def *(*texel_fetch_build_func)(struct nir_builder *, struct radv_device *,
455
nir_ssa_def *, bool, bool);
456
457
static nir_ssa_def *
458
build_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
459
bool is_3d, bool is_multisampled)
460
{
461
enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D
462
: is_multisampled ? GLSL_SAMPLER_DIM_MS
463
: GLSL_SAMPLER_DIM_2D;
464
const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT);
465
nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
466
sampler->data.descriptor_set = 0;
467
sampler->data.binding = 0;
468
469
nir_ssa_def *tex_pos_3d = NULL;
470
nir_ssa_def *sample_idx = NULL;
471
if (is_3d) {
472
nir_ssa_def *layer =
473
nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
474
475
nir_ssa_def *chans[3];
476
chans[0] = nir_channel(b, tex_pos, 0);
477
chans[1] = nir_channel(b, tex_pos, 1);
478
chans[2] = layer;
479
tex_pos_3d = nir_vec(b, chans, 3);
480
}
481
if (is_multisampled) {
482
sample_idx = nir_load_sample_id(b);
483
}
484
485
nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
486
487
nir_tex_instr *tex = nir_tex_instr_create(b->shader, is_multisampled ? 4 : 3);
488
tex->sampler_dim = dim;
489
tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
490
tex->src[0].src_type = nir_tex_src_coord;
491
tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : tex_pos);
492
tex->src[1].src_type = is_multisampled ? nir_tex_src_ms_index : nir_tex_src_lod;
493
tex->src[1].src = nir_src_for_ssa(is_multisampled ? sample_idx : nir_imm_int(b, 0));
494
tex->src[2].src_type = nir_tex_src_texture_deref;
495
tex->src[2].src = nir_src_for_ssa(tex_deref);
496
if (is_multisampled) {
497
tex->src[3].src_type = nir_tex_src_lod;
498
tex->src[3].src = nir_src_for_ssa(nir_imm_int(b, 0));
499
}
500
tex->dest_type = nir_type_uint32;
501
tex->is_array = false;
502
tex->coord_components = is_3d ? 3 : 2;
503
504
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
505
nir_builder_instr_insert(b, &tex->instr);
506
507
return &tex->dest.ssa;
508
}
509
510
static nir_ssa_def *
511
build_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
512
bool is_3d, bool is_multisampled)
513
{
514
const struct glsl_type *sampler_type =
515
glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT);
516
nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
517
sampler->data.descriptor_set = 0;
518
sampler->data.binding = 0;
519
520
nir_ssa_def *width = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
521
522
nir_ssa_def *pos_x = nir_channel(b, tex_pos, 0);
523
nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1);
524
pos_y = nir_imul(b, pos_y, width);
525
pos_x = nir_iadd(b, pos_x, pos_y);
526
527
nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
528
529
nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2);
530
tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
531
tex->op = nir_texop_txf;
532
tex->src[0].src_type = nir_tex_src_coord;
533
tex->src[0].src = nir_src_for_ssa(pos_x);
534
tex->src[1].src_type = nir_tex_src_texture_deref;
535
tex->src[1].src = nir_src_for_ssa(tex_deref);
536
tex->dest_type = nir_type_uint32;
537
tex->is_array = false;
538
tex->coord_components = 1;
539
540
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
541
nir_builder_instr_insert(b, &tex->instr);
542
543
return &tex->dest.ssa;
544
}
545
546
static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
547
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
548
.vertexBindingDescriptionCount = 0,
549
.vertexAttributeDescriptionCount = 0,
550
};
551
552
static nir_shader *
553
build_nir_copy_fragment_shader(struct radv_device *device, texel_fetch_build_func txf_func,
554
const char *name, bool is_3d, bool is_multisampled)
555
{
556
const struct glsl_type *vec4 = glsl_vec4_type();
557
const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
558
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
559
560
nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
561
tex_pos_in->data.location = VARYING_SLOT_VAR0;
562
563
nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
564
color_out->data.location = FRAG_RESULT_DATA0;
565
566
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
567
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
568
569
nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
570
nir_store_var(&b, color_out, color, 0xf);
571
572
return b.shader;
573
}
574
575
static nir_shader *
576
build_nir_copy_fragment_shader_depth(struct radv_device *device, texel_fetch_build_func txf_func,
577
const char *name, bool is_3d, bool is_multisampled)
578
{
579
const struct glsl_type *vec4 = glsl_vec4_type();
580
const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
581
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
582
583
nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
584
tex_pos_in->data.location = VARYING_SLOT_VAR0;
585
586
nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
587
color_out->data.location = FRAG_RESULT_DEPTH;
588
589
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
590
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
591
592
nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
593
nir_store_var(&b, color_out, color, 0x1);
594
595
return b.shader;
596
}
597
598
static nir_shader *
599
build_nir_copy_fragment_shader_stencil(struct radv_device *device, texel_fetch_build_func txf_func,
600
const char *name, bool is_3d, bool is_multisampled)
601
{
602
const struct glsl_type *vec4 = glsl_vec4_type();
603
const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
604
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
605
606
nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
607
tex_pos_in->data.location = VARYING_SLOT_VAR0;
608
609
nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
610
color_out->data.location = FRAG_RESULT_STENCIL;
611
612
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
613
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
614
615
nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
616
nir_store_var(&b, color_out, color, 0x1);
617
618
return b.shader;
619
}
620
621
void
622
radv_device_finish_meta_blit2d_state(struct radv_device *device)
623
{
624
struct radv_meta_state *state = &device->meta_state;
625
626
for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
627
for (unsigned k = 0; k < RADV_META_DST_LAYOUT_COUNT; ++k) {
628
radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_render_passes[j][k],
629
&state->alloc);
630
}
631
}
632
633
for (enum radv_blit_ds_layout j = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; j < RADV_BLIT_DS_LAYOUT_COUNT;
634
j++) {
635
radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_depth_only_rp[j],
636
&state->alloc);
637
radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_stencil_only_rp[j],
638
&state->alloc);
639
}
640
641
for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; ++log2_samples) {
642
for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
643
radv_DestroyPipelineLayout(radv_device_to_handle(device),
644
state->blit2d[log2_samples].p_layouts[src], &state->alloc);
645
radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
646
state->blit2d[log2_samples].ds_layouts[src],
647
&state->alloc);
648
649
for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
650
radv_DestroyPipeline(radv_device_to_handle(device),
651
state->blit2d[log2_samples].pipelines[src][j], &state->alloc);
652
}
653
654
radv_DestroyPipeline(radv_device_to_handle(device),
655
state->blit2d[log2_samples].depth_only_pipeline[src], &state->alloc);
656
radv_DestroyPipeline(radv_device_to_handle(device),
657
state->blit2d[log2_samples].stencil_only_pipeline[src],
658
&state->alloc);
659
}
660
}
661
}
662
663
static VkResult
664
blit2d_init_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
665
VkFormat format, uint32_t log2_samples)
666
{
667
VkResult result;
668
unsigned fs_key = radv_format_meta_fs_key(device, format);
669
const char *name;
670
671
mtx_lock(&device->meta_state.mtx);
672
if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) {
673
mtx_unlock(&device->meta_state.mtx);
674
return VK_SUCCESS;
675
}
676
677
texel_fetch_build_func src_func;
678
switch (src_type) {
679
case BLIT2D_SRC_TYPE_IMAGE:
680
src_func = build_nir_texel_fetch;
681
name = "meta_blit2d_image_fs";
682
break;
683
case BLIT2D_SRC_TYPE_IMAGE_3D:
684
src_func = build_nir_texel_fetch;
685
name = "meta_blit3d_image_fs";
686
break;
687
case BLIT2D_SRC_TYPE_BUFFER:
688
src_func = build_nir_buffer_fetch;
689
name = "meta_blit2d_buffer_fs";
690
break;
691
default:
692
unreachable("unknown blit src type\n");
693
break;
694
}
695
696
const VkPipelineVertexInputStateCreateInfo *vi_create_info;
697
nir_shader *fs = build_nir_copy_fragment_shader(
698
device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
699
nir_shader *vs = build_nir_vertex_shader();
700
701
vi_create_info = &normal_vi_create_info;
702
703
VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
704
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
705
.stage = VK_SHADER_STAGE_VERTEX_BIT,
706
.module = vk_shader_module_handle_from_nir(vs),
707
.pName = "main",
708
.pSpecializationInfo = NULL},
709
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
710
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
711
.module = vk_shader_module_handle_from_nir(fs),
712
.pName = "main",
713
.pSpecializationInfo = NULL},
714
};
715
716
for (unsigned dst_layout = 0; dst_layout < RADV_META_DST_LAYOUT_COUNT; ++dst_layout) {
717
if (!device->meta_state.blit2d_render_passes[fs_key][dst_layout]) {
718
VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout);
719
720
result = radv_CreateRenderPass2(
721
radv_device_to_handle(device),
722
&(VkRenderPassCreateInfo2){
723
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
724
.attachmentCount = 1,
725
.pAttachments =
726
&(VkAttachmentDescription2){
727
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
728
.format = format,
729
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
730
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
731
.initialLayout = layout,
732
.finalLayout = layout,
733
},
734
.subpassCount = 1,
735
.pSubpasses =
736
&(VkSubpassDescription2){
737
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
738
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
739
.inputAttachmentCount = 0,
740
.colorAttachmentCount = 1,
741
.pColorAttachments =
742
&(VkAttachmentReference2){
743
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
744
.attachment = 0,
745
.layout = layout,
746
},
747
.pResolveAttachments = NULL,
748
.pDepthStencilAttachment =
749
&(VkAttachmentReference2){
750
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
751
.attachment = VK_ATTACHMENT_UNUSED,
752
.layout = layout,
753
},
754
.preserveAttachmentCount = 0,
755
.pPreserveAttachments = NULL,
756
},
757
.dependencyCount = 2,
758
.pDependencies =
759
(VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
760
.srcSubpass = VK_SUBPASS_EXTERNAL,
761
.dstSubpass = 0,
762
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
763
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
764
.srcAccessMask = 0,
765
.dstAccessMask = 0,
766
.dependencyFlags = 0},
767
{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
768
.srcSubpass = 0,
769
.dstSubpass = VK_SUBPASS_EXTERNAL,
770
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
771
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
772
.srcAccessMask = 0,
773
.dstAccessMask = 0,
774
.dependencyFlags = 0}},
775
},
776
&device->meta_state.alloc,
777
&device->meta_state.blit2d_render_passes[fs_key][dst_layout]);
778
}
779
}
780
781
const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
782
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
783
.stageCount = ARRAY_SIZE(pipeline_shader_stages),
784
.pStages = pipeline_shader_stages,
785
.pVertexInputState = vi_create_info,
786
.pInputAssemblyState =
787
&(VkPipelineInputAssemblyStateCreateInfo){
788
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
789
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
790
.primitiveRestartEnable = false,
791
},
792
.pViewportState =
793
&(VkPipelineViewportStateCreateInfo){
794
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
795
.viewportCount = 1,
796
.scissorCount = 1,
797
},
798
.pRasterizationState =
799
&(VkPipelineRasterizationStateCreateInfo){
800
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
801
.rasterizerDiscardEnable = false,
802
.polygonMode = VK_POLYGON_MODE_FILL,
803
.cullMode = VK_CULL_MODE_NONE,
804
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
805
.pMultisampleState =
806
&(VkPipelineMultisampleStateCreateInfo){
807
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
808
.rasterizationSamples = 1 << log2_samples,
809
.sampleShadingEnable = log2_samples > 1,
810
.minSampleShading = 1.0,
811
.pSampleMask = (VkSampleMask[]){UINT32_MAX},
812
},
813
.pColorBlendState =
814
&(VkPipelineColorBlendStateCreateInfo){
815
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
816
.attachmentCount = 1,
817
.pAttachments =
818
(VkPipelineColorBlendAttachmentState[]){
819
{.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |
820
VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},
821
}},
822
.pDynamicState =
823
&(VkPipelineDynamicStateCreateInfo){
824
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
825
.dynamicStateCount = 9,
826
.pDynamicStates =
827
(VkDynamicState[]){
828
VK_DYNAMIC_STATE_VIEWPORT,
829
VK_DYNAMIC_STATE_SCISSOR,
830
VK_DYNAMIC_STATE_LINE_WIDTH,
831
VK_DYNAMIC_STATE_DEPTH_BIAS,
832
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
833
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
834
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
835
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
836
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
837
},
838
},
839
.flags = 0,
840
.layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
841
.renderPass = device->meta_state.blit2d_render_passes[fs_key][0],
842
.subpass = 0,
843
};
844
845
const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
846
847
result = radv_graphics_pipeline_create(
848
radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
849
&vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
850
&device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]);
851
852
ralloc_free(vs);
853
ralloc_free(fs);
854
855
mtx_unlock(&device->meta_state.mtx);
856
return result;
857
}
858
859
static VkResult
860
blit2d_init_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
861
uint32_t log2_samples)
862
{
863
VkResult result;
864
const char *name;
865
866
mtx_lock(&device->meta_state.mtx);
867
if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) {
868
mtx_unlock(&device->meta_state.mtx);
869
return VK_SUCCESS;
870
}
871
872
texel_fetch_build_func src_func;
873
switch (src_type) {
874
case BLIT2D_SRC_TYPE_IMAGE:
875
src_func = build_nir_texel_fetch;
876
name = "meta_blit2d_depth_image_fs";
877
break;
878
case BLIT2D_SRC_TYPE_IMAGE_3D:
879
src_func = build_nir_texel_fetch;
880
name = "meta_blit3d_depth_image_fs";
881
break;
882
case BLIT2D_SRC_TYPE_BUFFER:
883
src_func = build_nir_buffer_fetch;
884
name = "meta_blit2d_depth_buffer_fs";
885
break;
886
default:
887
unreachable("unknown blit src type\n");
888
break;
889
}
890
891
const VkPipelineVertexInputStateCreateInfo *vi_create_info;
892
nir_shader *fs = build_nir_copy_fragment_shader_depth(
893
device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
894
nir_shader *vs = build_nir_vertex_shader();
895
896
vi_create_info = &normal_vi_create_info;
897
898
VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
899
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
900
.stage = VK_SHADER_STAGE_VERTEX_BIT,
901
.module = vk_shader_module_handle_from_nir(vs),
902
.pName = "main",
903
.pSpecializationInfo = NULL},
904
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
905
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
906
.module = vk_shader_module_handle_from_nir(fs),
907
.pName = "main",
908
.pSpecializationInfo = NULL},
909
};
910
911
for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
912
ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
913
if (!device->meta_state.blit2d_depth_only_rp[ds_layout]) {
914
VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
915
result = radv_CreateRenderPass2(
916
radv_device_to_handle(device),
917
&(VkRenderPassCreateInfo2){
918
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
919
.attachmentCount = 1,
920
.pAttachments =
921
&(VkAttachmentDescription2){
922
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
923
.format = VK_FORMAT_D32_SFLOAT,
924
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
925
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
926
.initialLayout = layout,
927
.finalLayout = layout,
928
},
929
.subpassCount = 1,
930
.pSubpasses =
931
&(VkSubpassDescription2){
932
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
933
.inputAttachmentCount = 0,
934
.colorAttachmentCount = 0,
935
.pColorAttachments = NULL,
936
.pResolveAttachments = NULL,
937
.pDepthStencilAttachment =
938
&(VkAttachmentReference2){
939
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
940
.attachment = 0,
941
.layout = layout,
942
},
943
.preserveAttachmentCount = 0,
944
.pPreserveAttachments = NULL,
945
},
946
.dependencyCount = 2,
947
.pDependencies =
948
(VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
949
.srcSubpass = VK_SUBPASS_EXTERNAL,
950
.dstSubpass = 0,
951
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
952
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
953
.srcAccessMask = 0,
954
.dstAccessMask = 0,
955
.dependencyFlags = 0},
956
{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
957
.srcSubpass = 0,
958
.dstSubpass = VK_SUBPASS_EXTERNAL,
959
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
960
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
961
.srcAccessMask = 0,
962
.dstAccessMask = 0,
963
.dependencyFlags = 0}},
964
},
965
&device->meta_state.alloc, &device->meta_state.blit2d_depth_only_rp[ds_layout]);
966
}
967
}
968
969
const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
970
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
971
.stageCount = ARRAY_SIZE(pipeline_shader_stages),
972
.pStages = pipeline_shader_stages,
973
.pVertexInputState = vi_create_info,
974
.pInputAssemblyState =
975
&(VkPipelineInputAssemblyStateCreateInfo){
976
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
977
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
978
.primitiveRestartEnable = false,
979
},
980
.pViewportState =
981
&(VkPipelineViewportStateCreateInfo){
982
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
983
.viewportCount = 1,
984
.scissorCount = 1,
985
},
986
.pRasterizationState =
987
&(VkPipelineRasterizationStateCreateInfo){
988
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
989
.rasterizerDiscardEnable = false,
990
.polygonMode = VK_POLYGON_MODE_FILL,
991
.cullMode = VK_CULL_MODE_NONE,
992
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
993
.pMultisampleState =
994
&(VkPipelineMultisampleStateCreateInfo){
995
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
996
.rasterizationSamples = 1 << log2_samples,
997
.sampleShadingEnable = false,
998
.pSampleMask = (VkSampleMask[]){UINT32_MAX},
999
},
1000
.pColorBlendState =
1001
&(VkPipelineColorBlendStateCreateInfo){
1002
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1003
.attachmentCount = 0,
1004
.pAttachments = NULL,
1005
},
1006
.pDepthStencilState =
1007
&(VkPipelineDepthStencilStateCreateInfo){
1008
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1009
.depthTestEnable = true,
1010
.depthWriteEnable = true,
1011
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
1012
},
1013
.pDynamicState =
1014
&(VkPipelineDynamicStateCreateInfo){
1015
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1016
.dynamicStateCount = 9,
1017
.pDynamicStates =
1018
(VkDynamicState[]){
1019
VK_DYNAMIC_STATE_VIEWPORT,
1020
VK_DYNAMIC_STATE_SCISSOR,
1021
VK_DYNAMIC_STATE_LINE_WIDTH,
1022
VK_DYNAMIC_STATE_DEPTH_BIAS,
1023
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1024
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1025
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
1026
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
1027
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
1028
},
1029
},
1030
.flags = 0,
1031
.layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1032
.renderPass = device->meta_state.blit2d_depth_only_rp[0],
1033
.subpass = 0,
1034
};
1035
1036
const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
1037
1038
result = radv_graphics_pipeline_create(
1039
radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
1040
&vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
1041
&device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]);
1042
1043
ralloc_free(vs);
1044
ralloc_free(fs);
1045
1046
mtx_unlock(&device->meta_state.mtx);
1047
return result;
1048
}
1049
1050
static VkResult
1051
blit2d_init_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
1052
uint32_t log2_samples)
1053
{
1054
VkResult result;
1055
const char *name;
1056
1057
mtx_lock(&device->meta_state.mtx);
1058
if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) {
1059
mtx_unlock(&device->meta_state.mtx);
1060
return VK_SUCCESS;
1061
}
1062
1063
texel_fetch_build_func src_func;
1064
switch (src_type) {
1065
case BLIT2D_SRC_TYPE_IMAGE:
1066
src_func = build_nir_texel_fetch;
1067
name = "meta_blit2d_stencil_image_fs";
1068
break;
1069
case BLIT2D_SRC_TYPE_IMAGE_3D:
1070
src_func = build_nir_texel_fetch;
1071
name = "meta_blit3d_stencil_image_fs";
1072
break;
1073
case BLIT2D_SRC_TYPE_BUFFER:
1074
src_func = build_nir_buffer_fetch;
1075
name = "meta_blit2d_stencil_buffer_fs";
1076
break;
1077
default:
1078
unreachable("unknown blit src type\n");
1079
break;
1080
}
1081
1082
const VkPipelineVertexInputStateCreateInfo *vi_create_info;
1083
nir_shader *fs = build_nir_copy_fragment_shader_stencil(
1084
device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
1085
nir_shader *vs = build_nir_vertex_shader();
1086
1087
vi_create_info = &normal_vi_create_info;
1088
1089
VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
1090
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1091
.stage = VK_SHADER_STAGE_VERTEX_BIT,
1092
.module = vk_shader_module_handle_from_nir(vs),
1093
.pName = "main",
1094
.pSpecializationInfo = NULL},
1095
{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1096
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
1097
.module = vk_shader_module_handle_from_nir(fs),
1098
.pName = "main",
1099
.pSpecializationInfo = NULL},
1100
};
1101
1102
for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
1103
ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
1104
if (!device->meta_state.blit2d_stencil_only_rp[ds_layout]) {
1105
VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
1106
result = radv_CreateRenderPass2(
1107
radv_device_to_handle(device),
1108
&(VkRenderPassCreateInfo2){
1109
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
1110
.attachmentCount = 1,
1111
.pAttachments =
1112
&(VkAttachmentDescription2){
1113
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
1114
.format = VK_FORMAT_S8_UINT,
1115
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1116
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1117
.initialLayout = layout,
1118
.finalLayout = layout,
1119
},
1120
.subpassCount = 1,
1121
.pSubpasses =
1122
&(VkSubpassDescription2){
1123
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
1124
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1125
.inputAttachmentCount = 0,
1126
.colorAttachmentCount = 0,
1127
.pColorAttachments = NULL,
1128
.pResolveAttachments = NULL,
1129
.pDepthStencilAttachment =
1130
&(VkAttachmentReference2){
1131
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
1132
.attachment = 0,
1133
.layout = layout,
1134
},
1135
.preserveAttachmentCount = 0,
1136
.pPreserveAttachments = NULL,
1137
},
1138
.dependencyCount = 2,
1139
.pDependencies =
1140
(VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
1141
.srcSubpass = VK_SUBPASS_EXTERNAL,
1142
.dstSubpass = 0,
1143
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1144
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1145
.srcAccessMask = 0,
1146
.dstAccessMask = 0,
1147
.dependencyFlags = 0},
1148
{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
1149
.srcSubpass = 0,
1150
.dstSubpass = VK_SUBPASS_EXTERNAL,
1151
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1152
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
1153
.srcAccessMask = 0,
1154
.dstAccessMask = 0,
1155
.dependencyFlags = 0}},
1156
},
1157
&device->meta_state.alloc, &device->meta_state.blit2d_stencil_only_rp[ds_layout]);
1158
}
1159
}
1160
1161
const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
1162
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1163
.stageCount = ARRAY_SIZE(pipeline_shader_stages),
1164
.pStages = pipeline_shader_stages,
1165
.pVertexInputState = vi_create_info,
1166
.pInputAssemblyState =
1167
&(VkPipelineInputAssemblyStateCreateInfo){
1168
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1169
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1170
.primitiveRestartEnable = false,
1171
},
1172
.pViewportState =
1173
&(VkPipelineViewportStateCreateInfo){
1174
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1175
.viewportCount = 1,
1176
.scissorCount = 1,
1177
},
1178
.pRasterizationState =
1179
&(VkPipelineRasterizationStateCreateInfo){
1180
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1181
.rasterizerDiscardEnable = false,
1182
.polygonMode = VK_POLYGON_MODE_FILL,
1183
.cullMode = VK_CULL_MODE_NONE,
1184
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
1185
.pMultisampleState =
1186
&(VkPipelineMultisampleStateCreateInfo){
1187
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1188
.rasterizationSamples = 1 << log2_samples,
1189
.sampleShadingEnable = false,
1190
.pSampleMask = (VkSampleMask[]){UINT32_MAX},
1191
},
1192
.pColorBlendState =
1193
&(VkPipelineColorBlendStateCreateInfo){
1194
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1195
.attachmentCount = 0,
1196
.pAttachments = NULL,
1197
},
1198
.pDepthStencilState =
1199
&(VkPipelineDepthStencilStateCreateInfo){
1200
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1201
.depthTestEnable = false,
1202
.depthWriteEnable = false,
1203
.stencilTestEnable = true,
1204
.front = {.failOp = VK_STENCIL_OP_REPLACE,
1205
.passOp = VK_STENCIL_OP_REPLACE,
1206
.depthFailOp = VK_STENCIL_OP_REPLACE,
1207
.compareOp = VK_COMPARE_OP_ALWAYS,
1208
.compareMask = 0xff,
1209
.writeMask = 0xff,
1210
.reference = 0},
1211
.back = {.failOp = VK_STENCIL_OP_REPLACE,
1212
.passOp = VK_STENCIL_OP_REPLACE,
1213
.depthFailOp = VK_STENCIL_OP_REPLACE,
1214
.compareOp = VK_COMPARE_OP_ALWAYS,
1215
.compareMask = 0xff,
1216
.writeMask = 0xff,
1217
.reference = 0},
1218
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
1219
},
1220
.pDynamicState =
1221
&(VkPipelineDynamicStateCreateInfo){
1222
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1223
.dynamicStateCount = 6,
1224
.pDynamicStates =
1225
(VkDynamicState[]){
1226
VK_DYNAMIC_STATE_VIEWPORT,
1227
VK_DYNAMIC_STATE_SCISSOR,
1228
VK_DYNAMIC_STATE_LINE_WIDTH,
1229
VK_DYNAMIC_STATE_DEPTH_BIAS,
1230
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1231
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1232
},
1233
},
1234
.flags = 0,
1235
.layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1236
.renderPass = device->meta_state.blit2d_stencil_only_rp[0],
1237
.subpass = 0,
1238
};
1239
1240
const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
1241
1242
result = radv_graphics_pipeline_create(
1243
radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
1244
&vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
1245
&device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]);
1246
1247
ralloc_free(vs);
1248
ralloc_free(fs);
1249
1250
mtx_unlock(&device->meta_state.mtx);
1251
return result;
1252
}
1253
1254
static VkResult
1255
meta_blit2d_create_pipe_layout(struct radv_device *device, int idx, uint32_t log2_samples)
1256
{
1257
VkResult result;
1258
VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER)
1259
? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
1260
: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1261
const VkPushConstantRange push_constant_ranges[] = {
1262
{VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
1263
{VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
1264
};
1265
int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
1266
1267
result = radv_CreateDescriptorSetLayout(
1268
radv_device_to_handle(device),
1269
&(VkDescriptorSetLayoutCreateInfo){
1270
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1271
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1272
.bindingCount = 1,
1273
.pBindings =
1274
(VkDescriptorSetLayoutBinding[]){
1275
{.binding = 0,
1276
.descriptorType = desc_type,
1277
.descriptorCount = 1,
1278
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
1279
.pImmutableSamplers = NULL},
1280
}},
1281
&device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].ds_layouts[idx]);
1282
if (result != VK_SUCCESS)
1283
goto fail;
1284
1285
result = radv_CreatePipelineLayout(
1286
radv_device_to_handle(device),
1287
&(VkPipelineLayoutCreateInfo){
1288
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1289
.setLayoutCount = 1,
1290
.pSetLayouts = &device->meta_state.blit2d[log2_samples].ds_layouts[idx],
1291
.pushConstantRangeCount = num_push_constant_range,
1292
.pPushConstantRanges = push_constant_ranges,
1293
},
1294
&device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].p_layouts[idx]);
1295
if (result != VK_SUCCESS)
1296
goto fail;
1297
return VK_SUCCESS;
1298
fail:
1299
return result;
1300
}
1301
1302
VkResult
1303
radv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand)
1304
{
1305
VkResult result;
1306
bool create_3d = device->physical_device->rad_info.chip_class >= GFX9;
1307
1308
for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; log2_samples++) {
1309
for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
1310
if (src == BLIT2D_SRC_TYPE_IMAGE_3D && !create_3d)
1311
continue;
1312
1313
/* Don't need to handle copies between buffers and multisample images. */
1314
if (src == BLIT2D_SRC_TYPE_BUFFER && log2_samples > 0)
1315
continue;
1316
1317
result = meta_blit2d_create_pipe_layout(device, src, log2_samples);
1318
if (result != VK_SUCCESS)
1319
goto fail;
1320
1321
if (on_demand)
1322
continue;
1323
1324
for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
1325
result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j],
1326
log2_samples);
1327
if (result != VK_SUCCESS)
1328
goto fail;
1329
}
1330
1331
result = blit2d_init_depth_only_pipeline(device, src, log2_samples);
1332
if (result != VK_SUCCESS)
1333
goto fail;
1334
1335
result = blit2d_init_stencil_only_pipeline(device, src, log2_samples);
1336
if (result != VK_SUCCESS)
1337
goto fail;
1338
}
1339
}
1340
1341
return VK_SUCCESS;
1342
1343
fail:
1344
radv_device_finish_meta_blit2d_state(device);
1345
return result;
1346
}
1347
1348