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 "radv_private.h"
31 VkResult
radv_CreateRenderPass(
33 const VkRenderPassCreateInfo
* pCreateInfo
,
34 const VkAllocationCallbacks
* pAllocator
,
35 VkRenderPass
* pRenderPass
)
37 RADV_FROM_HANDLE(radv_device
, device
, _device
);
38 struct radv_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]);
50 pass
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
51 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
) {
62 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR
:
63 multiview_info
= ( VkRenderPassMultiviewCreateInfoKHR
*)ext
;
70 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
71 struct radv_render_pass_attachment
*att
= &pass
->attachments
[i
];
73 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
74 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
75 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
76 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
77 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
78 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
79 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
80 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
82 uint32_t subpass_attachment_count
= 0;
83 struct radv_subpass_attachment
*p
;
84 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
85 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
87 subpass_attachment_count
+=
88 desc
->inputAttachmentCount
+
89 desc
->colorAttachmentCount
+
90 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
91 (desc
->pDepthStencilAttachment
!= NULL
);
94 if (subpass_attachment_count
) {
95 pass
->subpass_attachments
=
96 vk_alloc2(&device
->alloc
, pAllocator
,
97 subpass_attachment_count
* sizeof(struct radv_subpass_attachment
), 8,
98 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
99 if (pass
->subpass_attachments
== NULL
) {
100 vk_free2(&device
->alloc
, pAllocator
, pass
);
101 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
104 pass
->subpass_attachments
= NULL
;
106 p
= pass
->subpass_attachments
;
107 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
108 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
109 uint32_t color_sample_count
= 1, depth_sample_count
= 1;
110 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
112 subpass
->input_count
= desc
->inputAttachmentCount
;
113 subpass
->color_count
= desc
->colorAttachmentCount
;
115 subpass
->view_mask
= multiview_info
->pViewMasks
[i
];
117 if (desc
->inputAttachmentCount
> 0) {
118 subpass
->input_attachments
= p
;
119 p
+= desc
->inputAttachmentCount
;
121 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
122 subpass
->input_attachments
[j
] = (struct radv_subpass_attachment
) {
123 .attachment
= desc
->pInputAttachments
[j
].attachment
,
124 .layout
= desc
->pInputAttachments
[j
].layout
,
126 if (desc
->pInputAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
)
127 pass
->attachments
[desc
->pInputAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
131 if (desc
->colorAttachmentCount
> 0) {
132 subpass
->color_attachments
= p
;
133 p
+= desc
->colorAttachmentCount
;
135 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
136 subpass
->color_attachments
[j
] = (struct radv_subpass_attachment
) {
137 .attachment
= desc
->pColorAttachments
[j
].attachment
,
138 .layout
= desc
->pColorAttachments
[j
].layout
,
140 if (desc
->pColorAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
) {
141 pass
->attachments
[desc
->pColorAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
142 color_sample_count
= pCreateInfo
->pAttachments
[desc
->pColorAttachments
[j
].attachment
].samples
;
147 subpass
->has_resolve
= false;
148 if (desc
->pResolveAttachments
) {
149 subpass
->resolve_attachments
= p
;
150 p
+= desc
->colorAttachmentCount
;
152 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
153 uint32_t a
= desc
->pResolveAttachments
[j
].attachment
;
154 subpass
->resolve_attachments
[j
] = (struct radv_subpass_attachment
) {
155 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
156 .layout
= desc
->pResolveAttachments
[j
].layout
,
158 if (a
!= VK_ATTACHMENT_UNUSED
) {
159 subpass
->has_resolve
= true;
160 pass
->attachments
[desc
->pResolveAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
165 if (desc
->pDepthStencilAttachment
) {
166 subpass
->depth_stencil_attachment
= (struct radv_subpass_attachment
) {
167 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
168 .layout
= desc
->pDepthStencilAttachment
->layout
,
170 if (desc
->pDepthStencilAttachment
->attachment
!= VK_ATTACHMENT_UNUSED
) {
171 pass
->attachments
[desc
->pDepthStencilAttachment
->attachment
].view_mask
|= subpass
->view_mask
;
172 depth_sample_count
= pCreateInfo
->pAttachments
[desc
->pDepthStencilAttachment
->attachment
].samples
;
175 subpass
->depth_stencil_attachment
.attachment
= VK_ATTACHMENT_UNUSED
;
178 subpass
->max_sample_count
= MAX2(color_sample_count
,
182 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
183 uint32_t src
= pCreateInfo
->pDependencies
[i
].srcSubpass
;
184 uint32_t dst
= pCreateInfo
->pDependencies
[i
].dstSubpass
;
186 /* Ignore subpass self-dependencies as they allow the app to
187 * call vkCmdPipelineBarrier() inside the render pass and the
188 * driver should only do the barrier when called, not when
189 * starting the render pass.
194 if (dst
== VK_SUBPASS_EXTERNAL
) {
195 pass
->end_barrier
.src_stage_mask
= pCreateInfo
->pDependencies
[i
].srcStageMask
;
196 pass
->end_barrier
.src_access_mask
= pCreateInfo
->pDependencies
[i
].srcAccessMask
;
197 pass
->end_barrier
.dst_access_mask
= pCreateInfo
->pDependencies
[i
].dstAccessMask
;
199 pass
->subpasses
[dst
].start_barrier
.src_stage_mask
= pCreateInfo
->pDependencies
[i
].srcStageMask
;
200 pass
->subpasses
[dst
].start_barrier
.src_access_mask
= pCreateInfo
->pDependencies
[i
].srcAccessMask
;
201 pass
->subpasses
[dst
].start_barrier
.dst_access_mask
= pCreateInfo
->pDependencies
[i
].dstAccessMask
;
205 *pRenderPass
= radv_render_pass_to_handle(pass
);
210 VkResult
radv_CreateRenderPass2KHR(
212 const VkRenderPassCreateInfo2KHR
* pCreateInfo
,
213 const VkAllocationCallbacks
* pAllocator
,
214 VkRenderPass
* pRenderPass
)
216 RADV_FROM_HANDLE(radv_device
, device
, _device
);
217 struct radv_render_pass
*pass
;
219 size_t attachments_offset
;
221 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR
);
223 size
= sizeof(*pass
);
224 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
225 attachments_offset
= size
;
226 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
228 pass
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
229 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
231 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
233 memset(pass
, 0, size
);
234 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
235 pass
->subpass_count
= pCreateInfo
->subpassCount
;
236 pass
->attachments
= (void *) pass
+ attachments_offset
;
238 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
239 struct radv_render_pass_attachment
*att
= &pass
->attachments
[i
];
241 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
242 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
243 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
244 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
245 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
246 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
247 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
248 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
250 uint32_t subpass_attachment_count
= 0;
251 struct radv_subpass_attachment
*p
;
252 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
253 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
255 subpass_attachment_count
+=
256 desc
->inputAttachmentCount
+
257 desc
->colorAttachmentCount
+
258 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
259 (desc
->pDepthStencilAttachment
!= NULL
);
262 if (subpass_attachment_count
) {
263 pass
->subpass_attachments
=
264 vk_alloc2(&device
->alloc
, pAllocator
,
265 subpass_attachment_count
* sizeof(struct radv_subpass_attachment
), 8,
266 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
267 if (pass
->subpass_attachments
== NULL
) {
268 vk_free2(&device
->alloc
, pAllocator
, pass
);
269 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
272 pass
->subpass_attachments
= NULL
;
274 p
= pass
->subpass_attachments
;
275 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
276 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
277 uint32_t color_sample_count
= 1, depth_sample_count
= 1;
278 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
280 subpass
->input_count
= desc
->inputAttachmentCount
;
281 subpass
->color_count
= desc
->colorAttachmentCount
;
282 subpass
->view_mask
= desc
->viewMask
;
284 if (desc
->inputAttachmentCount
> 0) {
285 subpass
->input_attachments
= p
;
286 p
+= desc
->inputAttachmentCount
;
288 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
289 subpass
->input_attachments
[j
] = (struct radv_subpass_attachment
) {
290 .attachment
= desc
->pInputAttachments
[j
].attachment
,
291 .layout
= desc
->pInputAttachments
[j
].layout
,
293 if (desc
->pInputAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
)
294 pass
->attachments
[desc
->pInputAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
298 if (desc
->colorAttachmentCount
> 0) {
299 subpass
->color_attachments
= p
;
300 p
+= desc
->colorAttachmentCount
;
302 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
303 subpass
->color_attachments
[j
] = (struct radv_subpass_attachment
) {
304 .attachment
= desc
->pColorAttachments
[j
].attachment
,
305 .layout
= desc
->pColorAttachments
[j
].layout
,
307 if (desc
->pColorAttachments
[j
].attachment
!= VK_ATTACHMENT_UNUSED
) {
308 pass
->attachments
[desc
->pColorAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
309 color_sample_count
= pCreateInfo
->pAttachments
[desc
->pColorAttachments
[j
].attachment
].samples
;
314 subpass
->has_resolve
= false;
315 if (desc
->pResolveAttachments
) {
316 subpass
->resolve_attachments
= p
;
317 p
+= desc
->colorAttachmentCount
;
319 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
320 uint32_t a
= desc
->pResolveAttachments
[j
].attachment
;
321 subpass
->resolve_attachments
[j
] = (struct radv_subpass_attachment
) {
322 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
323 .layout
= desc
->pResolveAttachments
[j
].layout
,
325 if (a
!= VK_ATTACHMENT_UNUSED
) {
326 subpass
->has_resolve
= true;
327 pass
->attachments
[desc
->pResolveAttachments
[j
].attachment
].view_mask
|= subpass
->view_mask
;
332 if (desc
->pDepthStencilAttachment
) {
333 subpass
->depth_stencil_attachment
= (struct radv_subpass_attachment
) {
334 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
335 .layout
= desc
->pDepthStencilAttachment
->layout
,
337 if (desc
->pDepthStencilAttachment
->attachment
!= VK_ATTACHMENT_UNUSED
) {
338 pass
->attachments
[desc
->pDepthStencilAttachment
->attachment
].view_mask
|= subpass
->view_mask
;
339 depth_sample_count
= pCreateInfo
->pAttachments
[desc
->pDepthStencilAttachment
->attachment
].samples
;
342 subpass
->depth_stencil_attachment
.attachment
= VK_ATTACHMENT_UNUSED
;
345 subpass
->max_sample_count
= MAX2(color_sample_count
,
349 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
350 uint32_t src
= pCreateInfo
->pDependencies
[i
].srcSubpass
;
351 uint32_t dst
= pCreateInfo
->pDependencies
[i
].dstSubpass
;
353 /* Ignore subpass self-dependencies as they allow the app to
354 * call vkCmdPipelineBarrier() inside the render pass and the
355 * driver should only do the barrier when called, not when
356 * starting the render pass.
361 if (dst
== VK_SUBPASS_EXTERNAL
) {
362 pass
->end_barrier
.src_stage_mask
= pCreateInfo
->pDependencies
[i
].srcStageMask
;
363 pass
->end_barrier
.src_access_mask
= pCreateInfo
->pDependencies
[i
].srcAccessMask
;
364 pass
->end_barrier
.dst_access_mask
= pCreateInfo
->pDependencies
[i
].dstAccessMask
;
366 pass
->subpasses
[dst
].start_barrier
.src_stage_mask
= pCreateInfo
->pDependencies
[i
].srcStageMask
;
367 pass
->subpasses
[dst
].start_barrier
.src_access_mask
= pCreateInfo
->pDependencies
[i
].srcAccessMask
;
368 pass
->subpasses
[dst
].start_barrier
.dst_access_mask
= pCreateInfo
->pDependencies
[i
].dstAccessMask
;
372 *pRenderPass
= radv_render_pass_to_handle(pass
);
377 void radv_DestroyRenderPass(
380 const VkAllocationCallbacks
* pAllocator
)
382 RADV_FROM_HANDLE(radv_device
, device
, _device
);
383 RADV_FROM_HANDLE(radv_render_pass
, pass
, _pass
);
387 vk_free2(&device
->alloc
, pAllocator
, pass
->subpass_attachments
);
388 vk_free2(&device
->alloc
, pAllocator
, pass
);
391 void radv_GetRenderAreaGranularity(
393 VkRenderPass renderPass
,
394 VkExtent2D
* pGranularity
)
396 pGranularity
->width
= 1;
397 pGranularity
->height
= 1;