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
25 * DEALINGS IN THE SOFTWARE.
27 #include "tu_private.h"
30 #include "vk_format.h"
32 static void update_samples(struct tu_subpass
*subpass
,
33 VkSampleCountFlagBits samples
)
35 assert(subpass
->samples
== 0 || subpass
->samples
== samples
);
36 subpass
->samples
= samples
;
40 tu_CreateRenderPass(VkDevice _device
,
41 const VkRenderPassCreateInfo
*pCreateInfo
,
42 const VkAllocationCallbacks
*pAllocator
,
43 VkRenderPass
*pRenderPass
)
45 TU_FROM_HANDLE(tu_device
, device
, _device
);
46 struct tu_render_pass
*pass
;
48 size_t attachments_offset
;
50 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
51 assert(pCreateInfo
->attachmentCount
< MAX_ATTACHMENTS
);
54 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
55 attachments_offset
= size
;
56 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
58 pass
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
59 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
61 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
63 memset(pass
, 0, size
);
64 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
65 pass
->subpass_count
= pCreateInfo
->subpassCount
;
66 pass
->attachments
= (void *) pass
+ attachments_offset
;
68 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
69 struct tu_render_pass_attachment
*att
= &pass
->attachments
[i
];
71 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
72 att
->cpp
= vk_format_get_blocksize(att
->format
) *
73 pCreateInfo
->pAttachments
[i
].samples
;
74 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
75 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
76 att
->store_op
= pCreateInfo
->pAttachments
[i
].storeOp
;
77 if (pCreateInfo
->pAttachments
[i
].stencilStoreOp
== VK_ATTACHMENT_STORE_OP_STORE
&&
78 vk_format_has_stencil(att
->format
))
79 att
->store_op
= VK_ATTACHMENT_STORE_OP_STORE
;
82 uint32_t subpass_attachment_count
= 0;
83 struct tu_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
+ desc
->colorAttachmentCount
+
89 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0);
92 if (subpass_attachment_count
) {
93 pass
->subpass_attachments
= vk_alloc2(
94 &device
->alloc
, pAllocator
,
95 subpass_attachment_count
* sizeof(struct tu_subpass_attachment
), 8,
96 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
97 if (pass
->subpass_attachments
== NULL
) {
98 vk_free2(&device
->alloc
, pAllocator
, pass
);
99 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
102 pass
->subpass_attachments
= NULL
;
104 p
= pass
->subpass_attachments
;
105 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
106 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
107 struct tu_subpass
*subpass
= &pass
->subpasses
[i
];
109 subpass
->input_count
= desc
->inputAttachmentCount
;
110 subpass
->color_count
= desc
->colorAttachmentCount
;
111 subpass
->samples
= 0;
113 if (desc
->inputAttachmentCount
> 0) {
114 subpass
->input_attachments
= p
;
115 p
+= desc
->inputAttachmentCount
;
117 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
118 uint32_t a
= desc
->pInputAttachments
[j
].attachment
;
119 subpass
->input_attachments
[j
].attachment
= a
;
120 if (a
!= VK_ATTACHMENT_UNUSED
)
121 pass
->attachments
[a
].needs_gmem
= true;
125 if (desc
->colorAttachmentCount
> 0) {
126 subpass
->color_attachments
= p
;
127 p
+= desc
->colorAttachmentCount
;
129 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
130 uint32_t a
= desc
->pColorAttachments
[j
].attachment
;
131 subpass
->color_attachments
[j
].attachment
= a
;
133 if (a
!= VK_ATTACHMENT_UNUSED
) {
134 pass
->attachments
[a
].needs_gmem
= true;
135 update_samples(subpass
, pCreateInfo
->pAttachments
[a
].samples
);
140 subpass
->resolve_attachments
= desc
->pResolveAttachments
? p
: NULL
;
141 if (desc
->pResolveAttachments
) {
142 p
+= desc
->colorAttachmentCount
;
143 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
144 subpass
->resolve_attachments
[j
].attachment
=
145 desc
->pResolveAttachments
[j
].attachment
;
149 uint32_t a
= desc
->pDepthStencilAttachment
?
150 desc
->pDepthStencilAttachment
->attachment
: VK_ATTACHMENT_UNUSED
;
151 subpass
->depth_stencil_attachment
.attachment
= a
;
152 if (a
!= VK_ATTACHMENT_UNUSED
) {
153 pass
->attachments
[a
].needs_gmem
= true;
154 update_samples(subpass
, pCreateInfo
->pAttachments
[a
].samples
);
157 subpass
->samples
= subpass
->samples
?: 1;
160 *pRenderPass
= tu_render_pass_to_handle(pass
);
166 tu_CreateRenderPass2KHR(VkDevice _device
,
167 const VkRenderPassCreateInfo2KHR
*pCreateInfo
,
168 const VkAllocationCallbacks
*pAllocator
,
169 VkRenderPass
*pRenderPass
)
171 TU_FROM_HANDLE(tu_device
, device
, _device
);
172 struct tu_render_pass
*pass
;
174 size_t attachments_offset
;
176 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR
);
177 assert(pCreateInfo
->attachmentCount
< MAX_ATTACHMENTS
);
179 size
= sizeof(*pass
);
180 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
181 attachments_offset
= size
;
182 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
184 pass
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
185 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
187 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
189 memset(pass
, 0, size
);
190 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
191 pass
->subpass_count
= pCreateInfo
->subpassCount
;
192 pass
->attachments
= (void *) pass
+ attachments_offset
;
194 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
195 struct tu_render_pass_attachment
*att
= &pass
->attachments
[i
];
197 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
198 att
->cpp
= vk_format_get_blocksize(att
->format
) *
199 pCreateInfo
->pAttachments
[i
].samples
;
200 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
201 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
202 att
->store_op
= pCreateInfo
->pAttachments
[i
].storeOp
;
203 att
->stencil_store_op
= pCreateInfo
->pAttachments
[i
].stencilStoreOp
;
204 if (pCreateInfo
->pAttachments
[i
].stencilStoreOp
== VK_ATTACHMENT_STORE_OP_STORE
&&
205 vk_format_has_stencil(att
->format
))
206 att
->store_op
= VK_ATTACHMENT_STORE_OP_STORE
;
208 uint32_t subpass_attachment_count
= 0;
209 struct tu_subpass_attachment
*p
;
210 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
211 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
213 subpass_attachment_count
+=
214 desc
->inputAttachmentCount
+ desc
->colorAttachmentCount
+
215 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0);
218 if (subpass_attachment_count
) {
219 pass
->subpass_attachments
= vk_alloc2(
220 &device
->alloc
, pAllocator
,
221 subpass_attachment_count
* sizeof(struct tu_subpass_attachment
), 8,
222 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
223 if (pass
->subpass_attachments
== NULL
) {
224 vk_free2(&device
->alloc
, pAllocator
, pass
);
225 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
228 pass
->subpass_attachments
= NULL
;
230 p
= pass
->subpass_attachments
;
231 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
232 const VkSubpassDescription2KHR
*desc
= &pCreateInfo
->pSubpasses
[i
];
233 struct tu_subpass
*subpass
= &pass
->subpasses
[i
];
235 subpass
->input_count
= desc
->inputAttachmentCount
;
236 subpass
->color_count
= desc
->colorAttachmentCount
;
237 subpass
->samples
= 0;
239 if (desc
->inputAttachmentCount
> 0) {
240 subpass
->input_attachments
= p
;
241 p
+= desc
->inputAttachmentCount
;
243 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
244 uint32_t a
= desc
->pInputAttachments
[j
].attachment
;
245 subpass
->input_attachments
[j
].attachment
= a
;
246 if (a
!= VK_ATTACHMENT_UNUSED
)
247 pass
->attachments
[a
].needs_gmem
= true;
251 if (desc
->colorAttachmentCount
> 0) {
252 subpass
->color_attachments
= p
;
253 p
+= desc
->colorAttachmentCount
;
255 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
256 uint32_t a
= desc
->pColorAttachments
[j
].attachment
;
257 subpass
->color_attachments
[j
].attachment
= a
;
259 if (a
!= VK_ATTACHMENT_UNUSED
) {
260 pass
->attachments
[a
].needs_gmem
= true;
261 update_samples(subpass
, pCreateInfo
->pAttachments
[a
].samples
);
266 subpass
->resolve_attachments
= desc
->pResolveAttachments
? p
: NULL
;
267 if (desc
->pResolveAttachments
) {
268 p
+= desc
->colorAttachmentCount
;
269 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
270 subpass
->resolve_attachments
[j
].attachment
=
271 desc
->pResolveAttachments
[j
].attachment
;
276 uint32_t a
= desc
->pDepthStencilAttachment
?
277 desc
->pDepthStencilAttachment
->attachment
: VK_ATTACHMENT_UNUSED
;
278 subpass
->depth_stencil_attachment
.attachment
= a
;
279 if (a
!= VK_ATTACHMENT_UNUSED
) {
280 pass
->attachments
[a
].needs_gmem
= true;
281 update_samples(subpass
, pCreateInfo
->pAttachments
[a
].samples
);
284 subpass
->samples
= subpass
->samples
?: 1;
287 *pRenderPass
= tu_render_pass_to_handle(pass
);
293 tu_DestroyRenderPass(VkDevice _device
,
295 const VkAllocationCallbacks
*pAllocator
)
297 TU_FROM_HANDLE(tu_device
, device
, _device
);
298 TU_FROM_HANDLE(tu_render_pass
, pass
, _pass
);
302 vk_free2(&device
->alloc
, pAllocator
, pass
->subpass_attachments
);
303 vk_free2(&device
->alloc
, pAllocator
, pass
);
307 tu_GetRenderAreaGranularity(VkDevice _device
,
308 VkRenderPass renderPass
,
309 VkExtent2D
*pGranularity
)
311 TU_FROM_HANDLE(tu_device
, device
, _device
);
313 pGranularity
->width
= device
->physical_device
->tile_align_w
;
314 pGranularity
->height
= device
->physical_device
->tile_align_h
;