4fab5d1b3dd9c5f2f88e996398eab01998ddd61f
[mesa.git] / src / intel / vulkan / anv_meta_blit2d.c
1 /*
2 * Copyright © 2016 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 "anv_meta.h"
25 #include "nir/nir_builder.h"
26
27 static VkFormat
28 vk_format_for_size(int bs)
29 {
30 /* The choice of UNORM and UINT formats is very intentional here. Most of
31 * the time, we want to use a UINT format to avoid any rounding error in
32 * the blit. For stencil blits, R8_UINT is required by the hardware.
33 * (It's the only format allowed in conjunction with W-tiling.) Also we
34 * intentionally use the 4-channel formats whenever we can. This is so
35 * that, when we do a RGB <-> RGBX copy, the two formats will line up even
36 * though one of them is 3/4 the size of the other. The choice of UNORM
37 * vs. UINT is also very intentional because Haswell doesn't handle 8 or
38 * 16-bit RGB UINT formats at all so we have to use UNORM there.
39 * Fortunately, the only time we should ever use two different formats in
40 * the table below is for RGB -> RGBA blits and so we will never have any
41 * UNORM/UINT mismatch.
42 */
43 switch (bs) {
44 case 1: return VK_FORMAT_R8_UINT;
45 case 2: return VK_FORMAT_R8G8_UINT;
46 case 3: return VK_FORMAT_R8G8B8_UNORM;
47 case 4: return VK_FORMAT_R8G8B8A8_UNORM;
48 case 6: return VK_FORMAT_R16G16B16_UNORM;
49 case 8: return VK_FORMAT_R16G16B16A16_UNORM;
50 case 12: return VK_FORMAT_R32G32B32_UINT;
51 case 16: return VK_FORMAT_R32G32B32A32_UINT;
52 default:
53 unreachable("Invalid format block size");
54 }
55 }
56
57 static void
58 meta_emit_blit2d(struct anv_cmd_buffer *cmd_buffer,
59 struct anv_image_view *src_iview,
60 VkOffset3D src_offset,
61 VkExtent3D src_extent,
62 struct anv_image_view *dest_iview,
63 VkOffset3D dest_offset,
64 VkExtent3D dest_extent)
65 {
66 struct anv_device *device = cmd_buffer->device;
67
68 struct blit_vb_data {
69 float pos[2];
70 float tex_coord[3];
71 } *vb_data;
72
73 unsigned vb_size = sizeof(struct anv_vue_header) + 3 * sizeof(*vb_data);
74
75 struct anv_state vb_state =
76 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, vb_size, 16);
77 memset(vb_state.map, 0, sizeof(struct anv_vue_header));
78 vb_data = vb_state.map + sizeof(struct anv_vue_header);
79
80 vb_data[0] = (struct blit_vb_data) {
81 .pos = {
82 dest_offset.x + dest_extent.width,
83 dest_offset.y + dest_extent.height,
84 },
85 .tex_coord = {
86 src_offset.x + src_extent.width,
87 src_offset.y + src_extent.height,
88 src_offset.z,
89 },
90 };
91
92 vb_data[1] = (struct blit_vb_data) {
93 .pos = {
94 dest_offset.x,
95 dest_offset.y + dest_extent.height,
96 },
97 .tex_coord = {
98 src_offset.x,
99 src_offset.y + src_extent.height,
100 src_offset.z,
101 },
102 };
103
104 vb_data[2] = (struct blit_vb_data) {
105 .pos = {
106 dest_offset.x,
107 dest_offset.y,
108 },
109 .tex_coord = {
110 src_offset.x,
111 src_offset.y,
112 src_offset.z,
113 },
114 };
115
116 anv_state_clflush(vb_state);
117
118 struct anv_buffer vertex_buffer = {
119 .device = device,
120 .size = vb_size,
121 .bo = &device->dynamic_state_block_pool.bo,
122 .offset = vb_state.offset,
123 };
124
125 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
126 (VkBuffer[]) {
127 anv_buffer_to_handle(&vertex_buffer),
128 anv_buffer_to_handle(&vertex_buffer)
129 },
130 (VkDeviceSize[]) {
131 0,
132 sizeof(struct anv_vue_header),
133 });
134
135 VkDescriptorPool desc_pool;
136 anv_CreateDescriptorPool(anv_device_to_handle(device),
137 &(const VkDescriptorPoolCreateInfo) {
138 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
139 .pNext = NULL,
140 .flags = 0,
141 .maxSets = 1,
142 .poolSizeCount = 1,
143 .pPoolSizes = (VkDescriptorPoolSize[]) {
144 {
145 .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
146 .descriptorCount = 1
147 },
148 }
149 }, &cmd_buffer->pool->alloc, &desc_pool);
150
151 VkDescriptorSet set;
152 anv_AllocateDescriptorSets(anv_device_to_handle(device),
153 &(VkDescriptorSetAllocateInfo) {
154 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
155 .descriptorPool = desc_pool,
156 .descriptorSetCount = 1,
157 .pSetLayouts = &device->meta_state.blit2d.ds_layout
158 }, &set);
159
160 anv_UpdateDescriptorSets(anv_device_to_handle(device),
161 1, /* writeCount */
162 (VkWriteDescriptorSet[]) {
163 {
164 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
165 .dstSet = set,
166 .dstBinding = 0,
167 .dstArrayElement = 0,
168 .descriptorCount = 1,
169 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
170 .pImageInfo = (VkDescriptorImageInfo[]) {
171 {
172 .sampler = NULL,
173 .imageView = anv_image_view_to_handle(src_iview),
174 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
175 },
176 }
177 }
178 }, 0, NULL);
179
180 VkFramebuffer fb;
181 anv_CreateFramebuffer(anv_device_to_handle(device),
182 &(VkFramebufferCreateInfo) {
183 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
184 .attachmentCount = 1,
185 .pAttachments = (VkImageView[]) {
186 anv_image_view_to_handle(dest_iview),
187 },
188 .width = dest_iview->extent.width,
189 .height = dest_iview->extent.height,
190 .layers = 1
191 }, &cmd_buffer->pool->alloc, &fb);
192
193 ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
194 &(VkRenderPassBeginInfo) {
195 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
196 .renderPass = device->meta_state.blit2d.render_pass,
197 .framebuffer = fb,
198 .renderArea = {
199 .offset = { dest_offset.x, dest_offset.y },
200 .extent = { dest_extent.width, dest_extent.height },
201 },
202 .clearValueCount = 0,
203 .pClearValues = NULL,
204 }, VK_SUBPASS_CONTENTS_INLINE);
205
206 VkPipeline pipeline = device->meta_state.blit2d.pipeline_2d_src;
207
208 if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(pipeline)) {
209 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
210 VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
211 }
212
213 anv_CmdSetViewport(anv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
214 &(VkViewport) {
215 .x = 0.0f,
216 .y = 0.0f,
217 .width = dest_iview->extent.width,
218 .height = dest_iview->extent.height,
219 .minDepth = 0.0f,
220 .maxDepth = 1.0f,
221 });
222
223 anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
224 VK_PIPELINE_BIND_POINT_GRAPHICS,
225 device->meta_state.blit2d.pipeline_layout, 0, 1,
226 &set, 0, NULL);
227
228 ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
229
230 ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
231
232 /* At the point where we emit the draw call, all data from the
233 * descriptor sets, etc. has been used. We are free to delete it.
234 */
235 anv_DestroyDescriptorPool(anv_device_to_handle(device),
236 desc_pool, &cmd_buffer->pool->alloc);
237 anv_DestroyFramebuffer(anv_device_to_handle(device), fb,
238 &cmd_buffer->pool->alloc);
239 }
240
241 void
242 anv_meta_end_blit2d(struct anv_cmd_buffer *cmd_buffer,
243 struct anv_meta_saved_state *save)
244 {
245 anv_meta_restore(save, cmd_buffer);
246 }
247
248 void
249 anv_meta_begin_blit2d(struct anv_cmd_buffer *cmd_buffer,
250 struct anv_meta_saved_state *save)
251 {
252 anv_meta_save(save, cmd_buffer,
253 (1 << VK_DYNAMIC_STATE_VIEWPORT));
254 }
255
256 void
257 anv_meta_blit2d(struct anv_cmd_buffer *cmd_buffer,
258 struct anv_meta_blit2d_surf *src,
259 struct anv_meta_blit2d_surf *dst,
260 unsigned num_rects,
261 struct anv_meta_blit2d_rect *rects)
262 {
263 VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
264 VkFormat src_format = vk_format_for_size(src->bs);
265 VkFormat dst_format = vk_format_for_size(dst->bs);
266 VkImageUsageFlags src_usage = VK_IMAGE_USAGE_SAMPLED_BIT;
267 VkImageUsageFlags dst_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
268
269 for (unsigned r = 0; r < num_rects; ++r) {
270
271 /* Create VkImages */
272 VkImageCreateInfo image_info = {
273 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
274 .imageType = VK_IMAGE_TYPE_2D,
275 .format = 0, /* TEMPLATE */
276 .extent = {
277 .width = 0, /* TEMPLATE */
278 .height = 0, /* TEMPLATE */
279 .depth = 1,
280 },
281 .mipLevels = 1,
282 .arrayLayers = 1,
283 .samples = 1,
284 .tiling = 0, /* TEMPLATE */
285 .usage = 0, /* TEMPLATE */
286 };
287 struct anv_image_create_info anv_image_info = {
288 .vk_info = &image_info,
289 .isl_tiling_flags = 0, /* TEMPLATE */
290 };
291
292 /* The image height is the rect height + src/dst y-offset from the
293 * tile-aligned base address.
294 */
295 struct isl_tile_info tile_info;
296
297 anv_image_info.isl_tiling_flags = 1 << src->tiling;
298 image_info.tiling = src->tiling == ISL_TILING_LINEAR ?
299 VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
300 image_info.usage = src_usage;
301 image_info.format = src_format,
302 isl_tiling_get_info(&cmd_buffer->device->isl_dev, src->tiling, src->bs,
303 &tile_info);
304 image_info.extent.height = rects[r].height +
305 rects[r].src_y % tile_info.height;
306 image_info.extent.width = src->pitch / src->bs;
307 VkImage src_image;
308 anv_image_create(vk_device, &anv_image_info,
309 &cmd_buffer->pool->alloc, &src_image);
310
311 anv_image_info.isl_tiling_flags = 1 << dst->tiling;
312 image_info.tiling = dst->tiling == ISL_TILING_LINEAR ?
313 VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
314 image_info.usage = dst_usage;
315 image_info.format = dst_format,
316 isl_tiling_get_info(&cmd_buffer->device->isl_dev, dst->tiling, dst->bs,
317 &tile_info);
318 image_info.extent.height = rects[r].height +
319 rects[r].dst_y % tile_info.height;
320 image_info.extent.width = dst->pitch / dst->bs;
321 VkImage dst_image;
322 anv_image_create(vk_device, &anv_image_info,
323 &cmd_buffer->pool->alloc, &dst_image);
324
325 /* We could use a vk call to bind memory, but that would require
326 * creating a dummy memory object etc. so there's really no point.
327 */
328 anv_image_from_handle(src_image)->bo = src->bo;
329 anv_image_from_handle(src_image)->offset = src->base_offset;
330 anv_image_from_handle(dst_image)->bo = dst->bo;
331 anv_image_from_handle(dst_image)->offset = dst->base_offset;
332
333 /* Create VkImageViews */
334 VkImageViewCreateInfo iview_info = {
335 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
336 .image = 0, /* TEMPLATE */
337 .viewType = VK_IMAGE_VIEW_TYPE_2D,
338 .format = 0, /* TEMPLATE */
339 .subresourceRange = {
340 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
341 .baseMipLevel = 0,
342 .levelCount = 1,
343 .baseArrayLayer = 0,
344 .layerCount = 1
345 },
346 };
347 uint32_t img_o = 0;
348
349 iview_info.image = src_image;
350 iview_info.format = src_format;
351 VkOffset3D src_offset_el = {0};
352 isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
353 &anv_image_from_handle(src_image)->
354 color_surface.isl,
355 rects[r].src_x,
356 rects[r].src_y,
357 &img_o,
358 (uint32_t*)&src_offset_el.x,
359 (uint32_t*)&src_offset_el.y);
360
361 struct anv_image_view src_iview;
362 anv_image_view_init(&src_iview, cmd_buffer->device,
363 &iview_info, cmd_buffer, img_o, src_usage);
364
365 iview_info.image = dst_image;
366 iview_info.format = dst_format;
367 VkOffset3D dst_offset_el = {0};
368 isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
369 &anv_image_from_handle(dst_image)->
370 color_surface.isl,
371 rects[r].dst_x,
372 rects[r].dst_y,
373 &img_o,
374 (uint32_t*)&dst_offset_el.x,
375 (uint32_t*)&dst_offset_el.y);
376 struct anv_image_view dst_iview;
377 anv_image_view_init(&dst_iview, cmd_buffer->device,
378 &iview_info, cmd_buffer, img_o, dst_usage);
379
380 /* Perform blit */
381 meta_emit_blit2d(cmd_buffer,
382 &src_iview,
383 src_offset_el,
384 (VkExtent3D){rects[r].width, rects[r].height, 1},
385 &dst_iview,
386 dst_offset_el,
387 (VkExtent3D){rects[r].width, rects[r].height, 1});
388
389 anv_DestroyImage(vk_device, src_image, &cmd_buffer->pool->alloc);
390 anv_DestroyImage(vk_device, dst_image, &cmd_buffer->pool->alloc);
391 }
392 }
393
394
395 static nir_shader *
396 build_nir_vertex_shader(void)
397 {
398 const struct glsl_type *vec4 = glsl_vec4_type();
399 nir_builder b;
400
401 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, NULL);
402 b.shader->info.name = ralloc_strdup(b.shader, "meta_blit_vs");
403
404 nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
405 vec4, "a_pos");
406 pos_in->data.location = VERT_ATTRIB_GENERIC0;
407 nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out,
408 vec4, "gl_Position");
409 pos_out->data.location = VARYING_SLOT_POS;
410 nir_copy_var(&b, pos_out, pos_in);
411
412 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
413 vec4, "a_tex_pos");
414 tex_pos_in->data.location = VERT_ATTRIB_GENERIC1;
415 nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out,
416 vec4, "v_tex_pos");
417 tex_pos_out->data.location = VARYING_SLOT_VAR0;
418 tex_pos_out->data.interpolation = INTERP_QUALIFIER_SMOOTH;
419 nir_copy_var(&b, tex_pos_out, tex_pos_in);
420
421 return b.shader;
422 }
423
424 static nir_shader *
425 build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
426 {
427 const struct glsl_type *vec4 = glsl_vec4_type();
428 const struct glsl_type *vec3 = glsl_vector_type(GLSL_TYPE_FLOAT, 3);
429 nir_builder b;
430
431 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
432 b.shader->info.name = ralloc_strdup(b.shader, "meta_blit2d_fs");
433
434 nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
435 vec3, "v_tex_pos");
436 tex_pos_in->data.location = VARYING_SLOT_VAR0;
437 nir_ssa_def *const tex_pos = nir_f2i(&b, nir_load_var(&b, tex_pos_in));
438
439 const struct glsl_type *sampler_type =
440 glsl_sampler_type(tex_dim, false, tex_dim != GLSL_SAMPLER_DIM_3D,
441 glsl_get_base_type(vec4));
442 nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform,
443 sampler_type, "s_tex");
444 sampler->data.descriptor_set = 0;
445 sampler->data.binding = 0;
446
447 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);
448 tex->sampler_dim = tex_dim;
449 tex->op = nir_texop_txf;
450 tex->src[0].src_type = nir_tex_src_coord;
451 tex->src[0].src = nir_src_for_ssa(tex_pos);
452 tex->src[1].src_type = nir_tex_src_lod;
453 tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
454 tex->dest_type = nir_type_float; /* TODO */
455 tex->is_array = glsl_sampler_type_is_array(sampler_type);
456 tex->coord_components = tex_pos->num_components;
457 tex->texture = nir_deref_var_create(tex, sampler);
458 tex->sampler = NULL;
459
460 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, "tex");
461 nir_builder_instr_insert(&b, &tex->instr);
462
463 nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
464 vec4, "f_color");
465 color_out->data.location = FRAG_RESULT_DATA0;
466 nir_store_var(&b, color_out, &tex->dest.ssa, 4);
467
468 return b.shader;
469 }
470
471 void
472 anv_device_finish_meta_blit2d_state(struct anv_device *device)
473 {
474 anv_DestroyRenderPass(anv_device_to_handle(device),
475 device->meta_state.blit2d.render_pass,
476 &device->meta_state.alloc);
477 anv_DestroyPipeline(anv_device_to_handle(device),
478 device->meta_state.blit2d.pipeline_2d_src,
479 &device->meta_state.alloc);
480 anv_DestroyPipelineLayout(anv_device_to_handle(device),
481 device->meta_state.blit2d.pipeline_layout,
482 &device->meta_state.alloc);
483 anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
484 device->meta_state.blit2d.ds_layout,
485 &device->meta_state.alloc);
486 }
487
488 VkResult
489 anv_device_init_meta_blit2d_state(struct anv_device *device)
490 {
491 VkResult result;
492
493 result = anv_CreateRenderPass(anv_device_to_handle(device),
494 &(VkRenderPassCreateInfo) {
495 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
496 .attachmentCount = 1,
497 .pAttachments = &(VkAttachmentDescription) {
498 .format = VK_FORMAT_UNDEFINED, /* Our shaders don't care */
499 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
500 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
501 .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
502 .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
503 },
504 .subpassCount = 1,
505 .pSubpasses = &(VkSubpassDescription) {
506 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
507 .inputAttachmentCount = 0,
508 .colorAttachmentCount = 1,
509 .pColorAttachments = &(VkAttachmentReference) {
510 .attachment = 0,
511 .layout = VK_IMAGE_LAYOUT_GENERAL,
512 },
513 .pResolveAttachments = NULL,
514 .pDepthStencilAttachment = &(VkAttachmentReference) {
515 .attachment = VK_ATTACHMENT_UNUSED,
516 .layout = VK_IMAGE_LAYOUT_GENERAL,
517 },
518 .preserveAttachmentCount = 1,
519 .pPreserveAttachments = (uint32_t[]) { 0 },
520 },
521 .dependencyCount = 0,
522 }, &device->meta_state.alloc, &device->meta_state.blit2d.render_pass);
523 if (result != VK_SUCCESS)
524 goto fail;
525
526 /* We don't use a vertex shader for blitting, but instead build and pass
527 * the VUEs directly to the rasterization backend. However, we do need
528 * to provide GLSL source for the vertex shader so that the compiler
529 * does not dead-code our inputs.
530 */
531 struct anv_shader_module vs = {
532 .nir = build_nir_vertex_shader(),
533 };
534
535 struct anv_shader_module fs_2d = {
536 .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
537 };
538
539 VkPipelineVertexInputStateCreateInfo vi_create_info = {
540 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
541 .vertexBindingDescriptionCount = 2,
542 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
543 {
544 .binding = 0,
545 .stride = 0,
546 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
547 },
548 {
549 .binding = 1,
550 .stride = 5 * sizeof(float),
551 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
552 },
553 },
554 .vertexAttributeDescriptionCount = 3,
555 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
556 {
557 /* VUE Header */
558 .location = 0,
559 .binding = 0,
560 .format = VK_FORMAT_R32G32B32A32_UINT,
561 .offset = 0
562 },
563 {
564 /* Position */
565 .location = 1,
566 .binding = 1,
567 .format = VK_FORMAT_R32G32_SFLOAT,
568 .offset = 0
569 },
570 {
571 /* Texture Coordinate */
572 .location = 2,
573 .binding = 1,
574 .format = VK_FORMAT_R32G32B32_SFLOAT,
575 .offset = 8
576 }
577 }
578 };
579
580 VkDescriptorSetLayoutCreateInfo ds_layout_info = {
581 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
582 .bindingCount = 1,
583 .pBindings = (VkDescriptorSetLayoutBinding[]) {
584 {
585 .binding = 0,
586 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
587 .descriptorCount = 1,
588 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
589 .pImmutableSamplers = NULL
590 },
591 }
592 };
593 result = anv_CreateDescriptorSetLayout(anv_device_to_handle(device),
594 &ds_layout_info,
595 &device->meta_state.alloc,
596 &device->meta_state.blit2d.ds_layout);
597 if (result != VK_SUCCESS)
598 goto fail_render_pass;
599
600 result = anv_CreatePipelineLayout(anv_device_to_handle(device),
601 &(VkPipelineLayoutCreateInfo) {
602 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
603 .setLayoutCount = 1,
604 .pSetLayouts = &device->meta_state.blit2d.ds_layout,
605 },
606 &device->meta_state.alloc, &device->meta_state.blit2d.pipeline_layout);
607 if (result != VK_SUCCESS)
608 goto fail_descriptor_set_layout;
609
610 VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
611 {
612 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
613 .stage = VK_SHADER_STAGE_VERTEX_BIT,
614 .module = anv_shader_module_to_handle(&vs),
615 .pName = "main",
616 .pSpecializationInfo = NULL
617 }, {
618 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
619 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
620 .module = VK_NULL_HANDLE, /* TEMPLATE VALUE! FILL ME IN! */
621 .pName = "main",
622 .pSpecializationInfo = NULL
623 },
624 };
625
626 const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
627 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
628 .stageCount = ARRAY_SIZE(pipeline_shader_stages),
629 .pStages = pipeline_shader_stages,
630 .pVertexInputState = &vi_create_info,
631 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
632 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
633 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
634 .primitiveRestartEnable = false,
635 },
636 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
637 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
638 .viewportCount = 1,
639 .scissorCount = 1,
640 },
641 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
642 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
643 .rasterizerDiscardEnable = false,
644 .polygonMode = VK_POLYGON_MODE_FILL,
645 .cullMode = VK_CULL_MODE_NONE,
646 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
647 },
648 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
649 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
650 .rasterizationSamples = 1,
651 .sampleShadingEnable = false,
652 .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
653 },
654 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
655 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
656 .attachmentCount = 1,
657 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
658 { .colorWriteMask =
659 VK_COLOR_COMPONENT_A_BIT |
660 VK_COLOR_COMPONENT_R_BIT |
661 VK_COLOR_COMPONENT_G_BIT |
662 VK_COLOR_COMPONENT_B_BIT },
663 }
664 },
665 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
666 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
667 .dynamicStateCount = 9,
668 .pDynamicStates = (VkDynamicState[]) {
669 VK_DYNAMIC_STATE_VIEWPORT,
670 VK_DYNAMIC_STATE_SCISSOR,
671 VK_DYNAMIC_STATE_LINE_WIDTH,
672 VK_DYNAMIC_STATE_DEPTH_BIAS,
673 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
674 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
675 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
676 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
677 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
678 },
679 },
680 .flags = 0,
681 .layout = device->meta_state.blit2d.pipeline_layout,
682 .renderPass = device->meta_state.blit2d.render_pass,
683 .subpass = 0,
684 };
685
686 const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
687 .color_attachment_count = -1,
688 .use_repclear = false,
689 .disable_viewport = true,
690 .disable_scissor = true,
691 .disable_vs = true,
692 .use_rectlist = true
693 };
694
695 pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_2d);
696 result = anv_graphics_pipeline_create(anv_device_to_handle(device),
697 VK_NULL_HANDLE,
698 &vk_pipeline_info, &anv_pipeline_info,
699 &device->meta_state.alloc, &device->meta_state.blit2d.pipeline_2d_src);
700 if (result != VK_SUCCESS)
701 goto fail_pipeline_layout;
702
703 ralloc_free(vs.nir);
704 ralloc_free(fs_2d.nir);
705
706 return VK_SUCCESS;
707
708 fail_pipeline_layout:
709 anv_DestroyPipelineLayout(anv_device_to_handle(device),
710 device->meta_state.blit2d.pipeline_layout,
711 &device->meta_state.alloc);
712 fail_descriptor_set_layout:
713 anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
714 device->meta_state.blit2d.ds_layout,
715 &device->meta_state.alloc);
716 fail_render_pass:
717 anv_DestroyRenderPass(anv_device_to_handle(device),
718 device->meta_state.blit2d.render_pass,
719 &device->meta_state.alloc);
720
721 ralloc_free(vs.nir);
722 ralloc_free(fs_2d.nir);
723 fail:
724 return result;
725 }