1 /*
2 * Copyright 2018 Collabora Ltd.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "zink_render_pass.h"
25
26 #include "zink_screen.h"
27
28 #include "util/u_memory.h"
29 #include "util/u_string.h"
30
31 static VkRenderPass
create_render_pass(VkDevice dev,struct zink_render_pass_state * state)32 create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
33 {
34
35 VkAttachmentReference color_refs[PIPE_MAX_COLOR_BUFS], zs_ref;
36 VkAttachmentDescription attachments[PIPE_MAX_COLOR_BUFS + 1];
37
38 for (int i = 0; i < state->num_cbufs; i++) {
39 struct zink_rt_attrib *rt = state->rts + i;
40 attachments[i].flags = 0;
41 attachments[i].format = rt->format;
42 attachments[i].samples = rt->samples;
43 attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
44 attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
45 attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
46 attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
47 attachments[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
48 attachments[i].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
49 color_refs[i].attachment = i;
50 color_refs[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
51 }
52
53 int num_attachments = state->num_cbufs;
54 if (state->have_zsbuf) {
55 struct zink_rt_attrib *rt = state->rts + state->num_cbufs;
56 attachments[num_attachments].flags = 0;
57 attachments[num_attachments].format = rt->format;
58 attachments[num_attachments].samples = rt->samples;
59 attachments[num_attachments].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
60 attachments[num_attachments].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
61 attachments[num_attachments].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
62 attachments[num_attachments].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
63 attachments[num_attachments].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
64 attachments[num_attachments].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
65
66 zs_ref.attachment = num_attachments++;
67 zs_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
68 }
69
70 VkSubpassDescription subpass = {};
71 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
72 subpass.colorAttachmentCount = state->num_cbufs;
73 subpass.pColorAttachments = color_refs;
74 subpass.pDepthStencilAttachment = state->have_zsbuf ? &zs_ref : NULL;
75
76 VkRenderPassCreateInfo rpci = {};
77 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
78 rpci.attachmentCount = num_attachments;
79 rpci.pAttachments = attachments;
80 rpci.subpassCount = 1;
81 rpci.pSubpasses = &subpass;
82
83 VkRenderPass render_pass;
84 if (vkCreateRenderPass(dev, &rpci, NULL, &render_pass) != VK_SUCCESS)
85 return VK_NULL_HANDLE;
86
87 return render_pass;
88 }
89
90 struct zink_render_pass *
zink_create_render_pass(struct zink_screen * screen,struct zink_render_pass_state * state)91 zink_create_render_pass(struct zink_screen *screen,
92 struct zink_render_pass_state *state)
93 {
94 struct zink_render_pass *rp = CALLOC_STRUCT(zink_render_pass);
95 if (!rp)
96 goto fail;
97
98 pipe_reference_init(&rp->reference, 1);
99
100 rp->render_pass = create_render_pass(screen->dev, state);
101 if (!rp->render_pass)
102 goto fail;
103
104 return rp;
105
106 fail:
107 if (rp)
108 zink_destroy_render_pass(screen, rp);
109 return NULL;
110 }
111
112 void
zink_destroy_render_pass(struct zink_screen * screen,struct zink_render_pass * rp)113 zink_destroy_render_pass(struct zink_screen *screen,
114 struct zink_render_pass *rp)
115 {
116 vkDestroyRenderPass(screen->dev, rp->render_pass, NULL);
117 FREE(rp);
118 }
119
120 void
debug_describe_zink_render_pass(char * buf,const struct zink_render_pass * ptr)121 debug_describe_zink_render_pass(char* buf, const struct zink_render_pass *ptr)
122 {
123 sprintf(buf, "zink_render_pass");
124 }
125