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