1 /*
2 * Copyright 2020 Valve Corporation
3 * SPDX-License-Identifier: MIT
4 *
5 * Authors:
6 * Jonathan Marek <jonathan@marek.ca>
7 */
8
9 #include <vulkan/vulkan.h>
10 #include <vulkan/vk_android_native_buffer.h> /* android tu_entrypoints.h depends on this */
11 #include <assert.h>
12
13 #include "tu_entrypoints.h"
14 #include "vk_util.h"
15
16 void
tu_GetPhysicalDeviceFeatures(VkPhysicalDevice pdev,VkPhysicalDeviceFeatures * features)17 tu_GetPhysicalDeviceFeatures(VkPhysicalDevice pdev, VkPhysicalDeviceFeatures *features)
18 {
19 VkPhysicalDeviceFeatures2 features2;
20 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
21 features2.pNext = NULL;
22 tu_GetPhysicalDeviceFeatures2(pdev, &features2);
23 *features = features2.features;
24 }
25
26 void
tu_GetPhysicalDeviceProperties(VkPhysicalDevice pdev,VkPhysicalDeviceProperties * props)27 tu_GetPhysicalDeviceProperties(VkPhysicalDevice pdev, VkPhysicalDeviceProperties *props)
28 {
29 VkPhysicalDeviceProperties2 props2;
30 props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
31 props2.pNext = NULL;
32 tu_GetPhysicalDeviceProperties2(pdev, &props2);
33 *props = props2.properties;
34 }
35
36 void
tu_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice pdev,uint32_t * count,VkQueueFamilyProperties * props)37 tu_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice pdev,
38 uint32_t *count,
39 VkQueueFamilyProperties *props)
40 {
41 if (!props)
42 return tu_GetPhysicalDeviceQueueFamilyProperties2(pdev, count, NULL);
43
44 VkQueueFamilyProperties2 props2[*count];
45 for (uint32_t i = 0; i < *count; i++) {
46 props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
47 props2[i].pNext = NULL;
48 }
49 tu_GetPhysicalDeviceQueueFamilyProperties2(pdev, count, props2);
50 for (uint32_t i = 0; i < *count; i++)
51 props[i] = props2[i].queueFamilyProperties;
52 }
53
54 void
tu_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice pdev,VkPhysicalDeviceMemoryProperties * props)55 tu_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice pdev, VkPhysicalDeviceMemoryProperties *props)
56 {
57 VkPhysicalDeviceMemoryProperties2 props2;
58 props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
59 props2.pNext = NULL;
60 tu_GetPhysicalDeviceMemoryProperties2(pdev, &props2);
61 *props = props2.memoryProperties;
62 }
63
64 void
tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice pdev,VkFormat format,VkFormatProperties * props)65 tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice pdev, VkFormat format, VkFormatProperties *props)
66 {
67 VkFormatProperties2 props2 = { .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 };
68 tu_GetPhysicalDeviceFormatProperties2(pdev, format, &props2);
69 *props = props2.formatProperties;
70 }
71
72 VkResult
tu_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice pdev,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * props)73 tu_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice pdev,
74 VkFormat format,
75 VkImageType type,
76 VkImageTiling tiling,
77 VkImageUsageFlags usage,
78 VkImageCreateFlags flags,
79 VkImageFormatProperties *props)
80 {
81 VkImageFormatProperties2 props2 = { .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 };
82 VkResult result = tu_GetPhysicalDeviceImageFormatProperties2(pdev, &(VkPhysicalDeviceImageFormatInfo2) {
83 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
84 .format = format,
85 .type = type,
86 .tiling = tiling,
87 .usage = usage,
88 .flags = flags
89 }, &props2);
90 *props = props2.imageFormatProperties;
91 return result;
92 }
93
94 void
tu_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice pdev,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * count,VkSparseImageFormatProperties * props)95 tu_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice pdev,
96 VkFormat format,
97 VkImageType type,
98 VkSampleCountFlagBits samples,
99 VkImageUsageFlags usage,
100 VkImageTiling tiling,
101 uint32_t *count,
102 VkSparseImageFormatProperties *props)
103 {
104 const VkPhysicalDeviceSparseImageFormatInfo2 info = {
105 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
106 .format = format,
107 .type = type,
108 .samples = samples,
109 .usage = usage,
110 .tiling = tiling,
111 };
112
113 if (!props)
114 return tu_GetPhysicalDeviceSparseImageFormatProperties2(pdev, &info, count, NULL);
115
116 VkSparseImageFormatProperties2 props2[*count];
117 for (uint32_t i = 0; i < *count; i++) {
118 props2[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
119 props2[i].pNext = NULL;
120 }
121 tu_GetPhysicalDeviceSparseImageFormatProperties2(pdev, &info, count, props2);
122 for (uint32_t i = 0; i < *count; i++)
123 props[i] = props2[i].properties;
124 }
125
126 void
tu_GetDeviceQueue(VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)127 tu_GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue)
128 {
129 tu_GetDeviceQueue2(device, &(VkDeviceQueueInfo2) {
130 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
131 .queueFamilyIndex = queueFamilyIndex,
132 .queueIndex = queueIndex
133 }, pQueue);
134 }
135
136 void
tu_GetBufferMemoryRequirements(VkDevice device,VkBuffer buffer,VkMemoryRequirements * reqs)137 tu_GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *reqs)
138 {
139 VkMemoryRequirements2 reqs2 = { .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
140 tu_GetBufferMemoryRequirements2(device, &(VkBufferMemoryRequirementsInfo2) {
141 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
142 .buffer = buffer
143 }, &reqs2);
144 *reqs = reqs2.memoryRequirements;
145 }
146
147 void
tu_GetImageMemoryRequirements(VkDevice device,VkImage image,VkMemoryRequirements * reqs)148 tu_GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *reqs)
149 {
150 VkMemoryRequirements2 reqs2 = { .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
151 tu_GetImageMemoryRequirements2(device, &(VkImageMemoryRequirementsInfo2) {
152 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
153 .image = image
154 }, &reqs2);
155 *reqs = reqs2.memoryRequirements;
156 }
157
158 void
tu_GetImageSparseMemoryRequirements(VkDevice device,VkImage image,uint32_t * count,VkSparseImageMemoryRequirements * reqs)159 tu_GetImageSparseMemoryRequirements(VkDevice device,
160 VkImage image,
161 uint32_t *count,
162 VkSparseImageMemoryRequirements *reqs)
163 {
164 const VkImageSparseMemoryRequirementsInfo2 info = {
165 .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
166 .image = image
167 };
168
169 if (!reqs)
170 return tu_GetImageSparseMemoryRequirements2(device, &info, count, NULL);
171
172 VkSparseImageMemoryRequirements2 reqs2[*count];
173 for (uint32_t i = 0; i < *count; i++) {
174 reqs2[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
175 reqs2[i].pNext = NULL;
176 }
177 tu_GetImageSparseMemoryRequirements2(device, &info, count, reqs2);
178 for (uint32_t i = 0; i < *count; i++)
179 reqs[i] = reqs2[i].memoryRequirements;
180 }
181
182 VkResult
tu_BindBufferMemory(VkDevice device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize offset)183 tu_BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize offset)
184 {
185 return tu_BindBufferMemory2(device, 1, &(VkBindBufferMemoryInfo) {
186 .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
187 .buffer = buffer,
188 .memory = memory,
189 .memoryOffset = offset
190 });
191 }
192
193 VkResult
tu_BindImageMemory(VkDevice device,VkImage image,VkDeviceMemory memory,VkDeviceSize offset)194 tu_BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize offset)
195 {
196 return tu_BindImageMemory2(device, 1, &(VkBindImageMemoryInfo) {
197 .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
198 .image = image,
199 .memory = memory,
200 .memoryOffset = offset
201 });
202 }
203
204 static void
translate_references(VkAttachmentReference2 ** reference_ptr,const VkAttachmentReference * reference,uint32_t count)205 translate_references(VkAttachmentReference2 **reference_ptr,
206 const VkAttachmentReference *reference,
207 uint32_t count)
208 {
209 VkAttachmentReference2 *reference2 = *reference_ptr;
210 *reference_ptr += count;
211 for (uint32_t i = 0; i < count; i++) {
212 reference2[i] = (VkAttachmentReference2) {
213 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
214 .pNext = NULL,
215 .attachment = reference[i].attachment,
216 .layout = reference[i].layout,
217 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
218 };
219 }
220 }
221
222 VkResult
tu_CreateRenderPass(VkDevice device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)223 tu_CreateRenderPass(VkDevice device,
224 const VkRenderPassCreateInfo *pCreateInfo,
225 const VkAllocationCallbacks *pAllocator,
226 VkRenderPass *pRenderPass)
227 {
228 /* note: these counts shouldn't be excessively high, so allocating it all
229 * on the stack should be OK..
230 * also note preserve attachments aren't translated, currently unused
231 */
232 VkAttachmentDescription2 attachments[pCreateInfo->attachmentCount];
233 VkSubpassDescription2 subpasses[pCreateInfo->subpassCount];
234 VkSubpassDependency2 dependencies[pCreateInfo->dependencyCount];
235 uint32_t reference_count = 0;
236 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
237 reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount;
238 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
239 if (pCreateInfo->pSubpasses[i].pResolveAttachments)
240 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
241 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment)
242 reference_count += 1;
243 }
244 VkAttachmentReference2 reference[reference_count];
245 VkAttachmentReference2 *reference_ptr = reference;
246
247 VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
248 vk_foreach_struct(ext, pCreateInfo->pNext) {
249 if (ext->sType == VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO) {
250 multiview_info = (VkRenderPassMultiviewCreateInfo*) ext;
251 break;
252 }
253 }
254
255 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
256 attachments[i] = (VkAttachmentDescription2) {
257 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
258 .pNext = NULL,
259 .flags = pCreateInfo->pAttachments[i].flags,
260 .format = pCreateInfo->pAttachments[i].format,
261 .samples = pCreateInfo->pAttachments[i].samples,
262 .loadOp = pCreateInfo->pAttachments[i].loadOp,
263 .storeOp = pCreateInfo->pAttachments[i].storeOp,
264 .stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp,
265 .stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp,
266 .initialLayout = pCreateInfo->pAttachments[i].initialLayout,
267 .finalLayout = pCreateInfo->pAttachments[i].finalLayout,
268 };
269 }
270
271 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
272 subpasses[i] = (VkSubpassDescription2) {
273 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
274 .pNext = NULL,
275 .flags = pCreateInfo->pSubpasses[i].flags,
276 .pipelineBindPoint = pCreateInfo->pSubpasses[i].pipelineBindPoint,
277 .viewMask = 0,
278 .inputAttachmentCount = pCreateInfo->pSubpasses[i].inputAttachmentCount,
279 .colorAttachmentCount = pCreateInfo->pSubpasses[i].colorAttachmentCount,
280 };
281
282 if (multiview_info && multiview_info->subpassCount)
283 subpasses[i].viewMask = multiview_info->pViewMasks[i];
284
285 subpasses[i].pInputAttachments = reference_ptr;
286 translate_references(&reference_ptr,
287 pCreateInfo->pSubpasses[i].pInputAttachments,
288 subpasses[i].inputAttachmentCount);
289 subpasses[i].pColorAttachments = reference_ptr;
290 translate_references(&reference_ptr,
291 pCreateInfo->pSubpasses[i].pColorAttachments,
292 subpasses[i].colorAttachmentCount);
293 subpasses[i].pResolveAttachments = NULL;
294 if (pCreateInfo->pSubpasses[i].pResolveAttachments) {
295 subpasses[i].pResolveAttachments = reference_ptr;
296 translate_references(&reference_ptr,
297 pCreateInfo->pSubpasses[i].pResolveAttachments,
298 subpasses[i].colorAttachmentCount);
299 }
300 subpasses[i].pDepthStencilAttachment = NULL;
301 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) {
302 subpasses[i].pDepthStencilAttachment = reference_ptr;
303 translate_references(&reference_ptr,
304 pCreateInfo->pSubpasses[i].pDepthStencilAttachment,
305 1);
306 }
307 }
308
309 assert(reference_ptr == reference + reference_count);
310
311 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
312 dependencies[i] = (VkSubpassDependency2) {
313 .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
314 .pNext = NULL,
315 .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass,
316 .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass,
317 .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask,
318 .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask,
319 .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask,
320 .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask,
321 .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags,
322 .viewOffset = 0,
323 };
324
325 if (multiview_info && multiview_info->dependencyCount)
326 dependencies[i].viewOffset = multiview_info->pViewOffsets[i];
327 }
328
329 VkRenderPassCreateInfo2 create_info = {
330 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
331 .pNext = pCreateInfo->pNext,
332 .flags = pCreateInfo->flags,
333 .attachmentCount = pCreateInfo->attachmentCount,
334 .pAttachments = attachments,
335 .subpassCount = pCreateInfo->subpassCount,
336 .pSubpasses = subpasses,
337 .dependencyCount = pCreateInfo->dependencyCount,
338 .pDependencies = dependencies,
339 };
340
341 if (multiview_info) {
342 create_info.correlatedViewMaskCount = multiview_info->correlationMaskCount;
343 create_info.pCorrelatedViewMasks = multiview_info->pCorrelationMasks;
344 }
345
346 return tu_CreateRenderPass2(device, &create_info, pAllocator, pRenderPass);
347 }
348
349 void
tu_CmdBeginRenderPass(VkCommandBuffer cmd,const VkRenderPassBeginInfo * info,VkSubpassContents contents)350 tu_CmdBeginRenderPass(VkCommandBuffer cmd, const VkRenderPassBeginInfo *info, VkSubpassContents contents)
351 {
352 return tu_CmdBeginRenderPass2(cmd, info, &(VkSubpassBeginInfo) {
353 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
354 .contents = contents
355 });
356 }
357
358 void
tu_CmdNextSubpass(VkCommandBuffer cmd,VkSubpassContents contents)359 tu_CmdNextSubpass(VkCommandBuffer cmd, VkSubpassContents contents)
360 {
361 return tu_CmdNextSubpass2(cmd, &(VkSubpassBeginInfo) {
362 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
363 .contents = contents
364 }, &(VkSubpassEndInfoKHR) {
365 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
366 });
367 }
368
369 void
tu_CmdEndRenderPass(VkCommandBuffer cmd)370 tu_CmdEndRenderPass(VkCommandBuffer cmd)
371 {
372 return tu_CmdEndRenderPass2(cmd, &(VkSubpassEndInfoKHR) {
373 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
374 });
375 }
376