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