2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 #include "tu_private.h"
32 tu_CreateRenderPass(VkDevice _device
,
33 const VkRenderPassCreateInfo
*pCreateInfo
,
34 const VkAllocationCallbacks
*pAllocator
,
35 VkRenderPass
*pRenderPass
)
37 TU_FROM_HANDLE(tu_device
, device
, _device
);
38 struct tu_render_pass
*pass
;
40 size_t attachments_offset
;
41 VkRenderPassMultiviewCreateInfoKHR
*multiview_info
= NULL
;
43 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
46 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
47 attachments_offset
= size
;
48 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
51 &device
->alloc
, pAllocator
, size
, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
53 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
55 memset(pass
, 0, size
);
56 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
57 pass
->subpass_count
= pCreateInfo
->subpassCount
;
58 pass
->attachments
= (void *)pass
+ attachments_offset
;
60 vk_foreach_struct(ext
, pCreateInfo
->pNext
)
63 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR
:
64 multiview_info
= (VkRenderPassMultiviewCreateInfoKHR
*)ext
;
71 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
72 struct tu_render_pass_attachment
*att
= &pass
->attachments
[i
];
74 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
75 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
76 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
77 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
78 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
79 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
80 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
81 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
83 uint32_t subpass_attachment_count
= 0;
84 struct tu_subpass_attachment
*p
;
85 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
86 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
88 subpass_attachment_count
+=
89 desc
->inputAttachmentCount
+ desc
->colorAttachmentCount
+
90 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
91 (desc
->pDepthStencilAttachment
!= NULL
);
94 if (subpass_attachment_count
) {
95 pass
->subpass_attachments
= vk_alloc2(
98 subpass_attachment_count
* sizeof(struct tu_subpass_attachment
),
100 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
101 if (pass
->subpass_attachments
== NULL
) {
102 vk_free2(&device
->alloc
, pAllocator
, pass
);
103 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
106 pass
->subpass_attachments
= NULL
;
108 p
= pass
->subpass_attachments
;
109 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
110 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
111 uint32_t color_sample_count
= 1, depth_sample_count
= 1;
112 struct tu_subpass
*subpass
= &pass
->subpasses
[i
];
114 subpass
->input_count
= desc
->inputAttachmentCount
;
115 subpass
->color_count
= desc
->colorAttachmentCount
;
117 subpass
->view_mask
= multiview_info
->pViewMasks
[i
];
119 if (desc
->inputAttachmentCount
> 0) {
120 subpass
->input_attachments
= p
;
121 p
+= desc
->inputAttachmentCount
;
123 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
124 subpass
->input_attachments
[j
] = (struct tu_subpass_attachment
){
125 .attachment
= desc
->pInputAttachments
[j
].attachment
,
126 .layout
= desc
->pInputAttachments
[j
].layout
,
128 if (desc
->pInputAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
)
129 pass
->attachments
[desc
->pInputAttachments
[j
].attachment
]
130 .view_mask
|= subpass
->view_mask
;
134 if (desc
->colorAttachmentCount
> 0) {
135 subpass
->color_attachments
= p
;
136 p
+= desc
->colorAttachmentCount
;
138 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
139 subpass
->color_attachments
[j
] = (struct tu_subpass_attachment
){
140 .attachment
= desc
->pColorAttachments
[j
].attachment
,
141 .layout
= desc
->pColorAttachments
[j
].layout
,
143 if (desc
->pColorAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
) {
144 pass
->attachments
[desc
->pColorAttachments
[j
].attachment
]
145 .view_mask
|= subpass
->view_mask
;
148 ->pAttachments
[desc
->pColorAttachments
[j
].attachment
]
154 subpass
->has_resolve
= false;
155 if (desc
->pResolveAttachments
) {
156 subpass
->resolve_attachments
= p
;
157 p
+= desc
->colorAttachmentCount
;
159 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
160 uint32_t a
= desc
->pResolveAttachments
[j
].attachment
;
161 subpass
->resolve_attachments
[j
] = (struct tu_subpass_attachment
){
162 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
163 .layout
= desc
->pResolveAttachments
[j
].layout
,
165 if (a
!= VK_ATTACHMENT_UNUSED
) {
166 subpass
->has_resolve
= true;
167 pass
->attachments
[desc
->pResolveAttachments
[j
].attachment
]
168 .view_mask
|= subpass
->view_mask
;
173 if (desc
->pDepthStencilAttachment
) {
174 subpass
->depth_stencil_attachment
= (struct tu_subpass_attachment
){
175 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
176 .layout
= desc
->pDepthStencilAttachment
->layout
,
178 if (desc
->pDepthStencilAttachment
->attachment
!=
179 VK_ATTACHMENT_UNUSED
) {
180 pass
->attachments
[desc
->pDepthStencilAttachment
->attachment
]
181 .view_mask
|= subpass
->view_mask
;
184 ->pAttachments
[desc
->pDepthStencilAttachment
->attachment
]
188 subpass
->depth_stencil_attachment
.attachment
= VK_ATTACHMENT_UNUSED
;
191 subpass
->max_sample_count
= MAX2(color_sample_count
, depth_sample_count
);
194 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
195 uint32_t dst
= pCreateInfo
->pDependencies
[i
].dstSubpass
;
196 if (dst
== VK_SUBPASS_EXTERNAL
) {
197 pass
->end_barrier
.src_stage_mask
=
198 pCreateInfo
->pDependencies
[i
].srcStageMask
;
199 pass
->end_barrier
.src_access_mask
=
200 pCreateInfo
->pDependencies
[i
].srcAccessMask
;
201 pass
->end_barrier
.dst_access_mask
=
202 pCreateInfo
->pDependencies
[i
].dstAccessMask
;
204 pass
->subpasses
[dst
].start_barrier
.src_stage_mask
=
205 pCreateInfo
->pDependencies
[i
].srcStageMask
;
206 pass
->subpasses
[dst
].start_barrier
.src_access_mask
=
207 pCreateInfo
->pDependencies
[i
].srcAccessMask
;
208 pass
->subpasses
[dst
].start_barrier
.dst_access_mask
=
209 pCreateInfo
->pDependencies
[i
].dstAccessMask
;
213 *pRenderPass
= tu_render_pass_to_handle(pass
);
219 tu_CreateRenderPass2KHR(VkDevice _device
,
220 const VkRenderPassCreateInfo2KHR
*pCreateInfo
,
221 const VkAllocationCallbacks
*pAllocator
,
222 VkRenderPass
*pRenderPass
)
224 TU_FROM_HANDLE(tu_device
, device
, _device
);
225 struct tu_render_pass
*pass
;
227 size_t attachments_offset
;
229 assert(pCreateInfo
->sType
==
230 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR
);
232 size
= sizeof(*pass
);
233 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
234 attachments_offset
= size
;
235 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
238 &device
->alloc
, pAllocator
, size
, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
240 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
242 memset(pass
, 0, size
);
243 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
244 pass
->subpass_count
= pCreateInfo
->subpassCount
;
245 pass
->attachments
= (void *)pass
+ attachments_offset
;
247 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
248 struct tu_render_pass_attachment
*att
= &pass
->attachments
[i
];
250 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
251 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
252 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
253 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
254 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
255 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
256 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
257 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
259 uint32_t subpass_attachment_count
= 0;
260 struct tu_subpass_attachment
*p
;
261 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
262 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
264 subpass_attachment_count
+=
265 desc
->inputAttachmentCount
+ desc
->colorAttachmentCount
+
266 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
267 (desc
->pDepthStencilAttachment
!= NULL
);
270 if (subpass_attachment_count
) {
271 pass
->subpass_attachments
= vk_alloc2(
274 subpass_attachment_count
* sizeof(struct tu_subpass_attachment
),
276 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
277 if (pass
->subpass_attachments
== NULL
) {
278 vk_free2(&device
->alloc
, pAllocator
, pass
);
279 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
282 pass
->subpass_attachments
= NULL
;
284 p
= pass
->subpass_attachments
;
285 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
286 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
287 uint32_t color_sample_count
= 1, depth_sample_count
= 1;
288 struct tu_subpass
*subpass
= &pass
->subpasses
[i
];
290 subpass
->input_count
= desc
->inputAttachmentCount
;
291 subpass
->color_count
= desc
->colorAttachmentCount
;
292 subpass
->view_mask
= desc
->viewMask
;
294 if (desc
->inputAttachmentCount
> 0) {
295 subpass
->input_attachments
= p
;
296 p
+= desc
->inputAttachmentCount
;
298 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
299 subpass
->input_attachments
[j
] = (struct tu_subpass_attachment
){
300 .attachment
= desc
->pInputAttachments
[j
].attachment
,
301 .layout
= desc
->pInputAttachments
[j
].layout
,
303 if (desc
->pInputAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
)
304 pass
->attachments
[desc
->pInputAttachments
[j
].attachment
]
305 .view_mask
|= subpass
->view_mask
;
309 if (desc
->colorAttachmentCount
> 0) {
310 subpass
->color_attachments
= p
;
311 p
+= desc
->colorAttachmentCount
;
313 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
314 subpass
->color_attachments
[j
] = (struct tu_subpass_attachment
){
315 .attachment
= desc
->pColorAttachments
[j
].attachment
,
316 .layout
= desc
->pColorAttachments
[j
].layout
,
318 if (desc
->pColorAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
) {
319 pass
->attachments
[desc
->pColorAttachments
[j
].attachment
]
320 .view_mask
|= subpass
->view_mask
;
323 ->pAttachments
[desc
->pColorAttachments
[j
].attachment
]
329 subpass
->has_resolve
= false;
330 if (desc
->pResolveAttachments
) {
331 subpass
->resolve_attachments
= p
;
332 p
+= desc
->colorAttachmentCount
;
334 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
335 uint32_t a
= desc
->pResolveAttachments
[j
].attachment
;
336 subpass
->resolve_attachments
[j
] = (struct tu_subpass_attachment
){
337 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
338 .layout
= desc
->pResolveAttachments
[j
].layout
,
340 if (a
!= VK_ATTACHMENT_UNUSED
) {
341 subpass
->has_resolve
= true;
342 pass
->attachments
[desc
->pResolveAttachments
[j
].attachment
]
343 .view_mask
|= subpass
->view_mask
;
348 if (desc
->pDepthStencilAttachment
) {
349 subpass
->depth_stencil_attachment
= (struct tu_subpass_attachment
){
350 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
351 .layout
= desc
->pDepthStencilAttachment
->layout
,
353 if (desc
->pDepthStencilAttachment
->attachment
!=
354 VK_ATTACHMENT_UNUSED
) {
355 pass
->attachments
[desc
->pDepthStencilAttachment
->attachment
]
356 .view_mask
|= subpass
->view_mask
;
359 ->pAttachments
[desc
->pDepthStencilAttachment
->attachment
]
363 subpass
->depth_stencil_attachment
.attachment
= VK_ATTACHMENT_UNUSED
;
366 subpass
->max_sample_count
= MAX2(color_sample_count
, depth_sample_count
);
369 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
370 uint32_t dst
= pCreateInfo
->pDependencies
[i
].dstSubpass
;
371 if (dst
== VK_SUBPASS_EXTERNAL
) {
372 pass
->end_barrier
.src_stage_mask
=
373 pCreateInfo
->pDependencies
[i
].srcStageMask
;
374 pass
->end_barrier
.src_access_mask
=
375 pCreateInfo
->pDependencies
[i
].srcAccessMask
;
376 pass
->end_barrier
.dst_access_mask
=
377 pCreateInfo
->pDependencies
[i
].dstAccessMask
;
379 pass
->subpasses
[dst
].start_barrier
.src_stage_mask
=
380 pCreateInfo
->pDependencies
[i
].srcStageMask
;
381 pass
->subpasses
[dst
].start_barrier
.src_access_mask
=
382 pCreateInfo
->pDependencies
[i
].srcAccessMask
;
383 pass
->subpasses
[dst
].start_barrier
.dst_access_mask
=
384 pCreateInfo
->pDependencies
[i
].dstAccessMask
;
388 *pRenderPass
= tu_render_pass_to_handle(pass
);
394 tu_DestroyRenderPass(VkDevice _device
,
396 const VkAllocationCallbacks
*pAllocator
)
398 TU_FROM_HANDLE(tu_device
, device
, _device
);
399 TU_FROM_HANDLE(tu_render_pass
, pass
, _pass
);
403 vk_free2(&device
->alloc
, pAllocator
, pass
->subpass_attachments
);
404 vk_free2(&device
->alloc
, pAllocator
, pass
);
408 tu_GetRenderAreaGranularity(VkDevice device
,
409 VkRenderPass renderPass
,
410 VkExtent2D
*pGranularity
)
412 pGranularity
->width
= 1;
413 pGranularity
->height
= 1;