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