1// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VkBuffer.hpp"
16#include "VkBufferView.hpp"
17#include "VkCommandBuffer.hpp"
18#include "VkCommandPool.hpp"
19#include "VkConfig.h"
20#include "VkDebug.hpp"
21#include "VkDescriptorPool.hpp"
22#include "VkDescriptorSetLayout.hpp"
23#include "VkDescriptorUpdateTemplate.hpp"
24#include "VkDestroy.h"
25#include "VkDevice.hpp"
26#include "VkDeviceMemory.hpp"
27#include "VkEvent.hpp"
28#include "VkFence.hpp"
29#include "VkFramebuffer.hpp"
30#include "VkGetProcAddress.h"
31#include "VkImage.hpp"
32#include "VkImageView.hpp"
33#include "VkInstance.hpp"
34#include "VkPhysicalDevice.hpp"
35#include "VkPipeline.hpp"
36#include "VkPipelineCache.hpp"
37#include "VkPipelineLayout.hpp"
38#include "VkQueryPool.hpp"
39#include "VkQueue.hpp"
40#include "VkSampler.hpp"
41#include "VkSemaphore.hpp"
42#include "VkShaderModule.hpp"
43#include "VkRenderPass.hpp"
44
45#if defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_MACOS_MVK)
46#include "WSI/MetalSurface.h"
47#endif
48
49#ifdef VK_USE_PLATFORM_XCB_KHR
50#include "WSI/XcbSurfaceKHR.hpp"
51#endif
52
53#ifdef VK_USE_PLATFORM_XLIB_KHR
54#include "WSI/XlibSurfaceKHR.hpp"
55#endif
56
57#ifdef VK_USE_PLATFORM_WIN32_KHR
58#include "WSI/Win32SurfaceKHR.hpp"
59#endif
60
61#ifdef __ANDROID__
62#include <android/log.h>
63#include "System/GrallocAndroid.hpp"
64#include <sync/sync.h>
65#include "commit.h"
66#endif
67
68#include "WSI/VkSwapchainKHR.hpp"
69
70#include "Reactor/Nucleus.hpp"
71
72#include "marl/scheduler.h"
73#include "marl/thread.h"
74
75#include "System/CPUID.hpp"
76
77#include <algorithm>
78#include <cstring>
79#include <string>
80#include <map>
81
82namespace
83{
84
85// Enable commit_id.py and #include commit.h for other platforms.
86#if defined(__ANDROID__) && defined(ENABLE_BUILD_VERSION_OUTPUT)
87void logBuildVersionInformation()
88{
89 // TODO(b/144093703): Don't call __android_log_print() directly
90 __android_log_print(ANDROID_LOG_INFO, "SwiftShader", "SwiftShader Version: %s", SWIFTSHADER_VERSION_STRING);
91}
92#endif // __ANDROID__ && ENABLE_BUILD_VERSION_OUTPUT
93
94
95bool HasExtensionProperty(const char* extensionName, const VkExtensionProperties* extensionProperties, uint32_t extensionPropertiesCount)
96{
97 for(uint32_t j = 0; j < extensionPropertiesCount; ++j)
98 {
99 if(strcmp(extensionName, extensionProperties[j].extensionName) == 0)
100 {
101 return true;
102 }
103 }
104
105 return false;
106}
107
108// setReactorDefaultConfig() sets the default configuration for Vulkan's use of
109// Reactor.
110void setReactorDefaultConfig()
111{
112 auto cfg = rr::Config::Edit()
113 .set(rr::Optimization::Level::Default)
114 .clearOptimizationPasses()
115 .add(rr::Optimization::Pass::ScalarReplAggregates)
116 .add(rr::Optimization::Pass::SCCP)
117 .add(rr::Optimization::Pass::CFGSimplification)
118 .add(rr::Optimization::Pass::EarlyCSEPass)
119 .add(rr::Optimization::Pass::CFGSimplification)
120 .add(rr::Optimization::Pass::InstructionCombining);
121
122 rr::Nucleus::adjustDefaultConfig(cfg);
123}
124
125void setCPUDefaults()
126{
127 sw::CPUID::setEnableSSE4_1(true);
128 sw::CPUID::setEnableSSSE3(true);
129 sw::CPUID::setEnableSSE3(true);
130 sw::CPUID::setEnableSSE2(true);
131 sw::CPUID::setEnableSSE(true);
132}
133
134std::shared_ptr<marl::Scheduler> getOrCreateScheduler()
135{
136 static std::mutex mutex;
137 static std::weak_ptr<marl::Scheduler> schedulerWeak;
138 std::unique_lock<std::mutex> lock(mutex);
139 auto scheduler = schedulerWeak.lock();
140 if (!scheduler)
141 {
142 scheduler = std::make_shared<marl::Scheduler>();
143 scheduler->setThreadInitializer([] {
144 sw::CPUID::setFlushToZero(true);
145 sw::CPUID::setDenormalsAreZero(true);
146 });
147 scheduler->setWorkerThreadCount(std::min<size_t>(marl::Thread::numLogicalCPUs(), 16));
148 schedulerWeak = scheduler;
149 }
150 return scheduler;
151}
152
153// initializeLibrary() is called by vkCreateInstance() to perform one-off global
154// initialization of the swiftshader driver.
155void initializeLibrary()
156{
157 static bool doOnce = [] {
158#if defined(__ANDROID__) && defined(ENABLE_BUILD_VERSION_OUTPUT)
159 logBuildVersionInformation();
160#endif // __ANDROID__ && ENABLE_BUILD_VERSION_OUTPUT
161 setReactorDefaultConfig();
162 setCPUDefaults();
163 return true;
164 }();
165 (void)doOnce;
166}
167
168}
169
170extern "C"
171{
172VK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName)
173{
174 TRACE("(VkInstance instance = %p, const char* pName = %p)", instance, pName);
175
176 return vk::GetInstanceProcAddr(vk::Cast(instance), pName);
177}
178
179VK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
180{
181 *pSupportedVersion = 3;
182 return VK_SUCCESS;
183}
184
185static const VkExtensionProperties instanceExtensionProperties[] =
186{
187 { VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION },
188 { VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION },
189 { VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION },
190 { VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION },
191 { VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION },
192#ifndef __ANDROID__
193 { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION },
194#endif
195#ifdef VK_USE_PLATFORM_XCB_KHR
196 { VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_SPEC_VERSION },
197#endif
198#ifdef VK_USE_PLATFORM_XLIB_KHR
199 { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION },
200#endif
201#ifdef VK_USE_PLATFORM_MACOS_MVK
202 { VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
203#endif
204#ifdef VK_USE_PLATFORM_METAL_EXT
205 { VK_EXT_METAL_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_SPEC_VERSION },
206#endif
207#ifdef VK_USE_PLATFORM_WIN32_KHR
208 { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION },
209#endif
210};
211
212static const VkExtensionProperties deviceExtensionProperties[] =
213{
214 { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION },
215 // Vulkan 1.1 promoted extensions
216 { VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION },
217 { VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_SPEC_VERSION },
218 { VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION },
219 { VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION },
220 { VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_SPEC_VERSION },
221 { VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_SPEC_VERSION },
222 { VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION },
223 { VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION },
224 { VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION },
225 { VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_MAINTENANCE1_SPEC_VERSION },
226 { VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_KHR_MAINTENANCE2_SPEC_VERSION },
227 { VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_MAINTENANCE3_SPEC_VERSION },
228 { VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION },
229 { VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION },
230 { VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION },
231 // Only 1.1 core version of this is supported. The extension has additional requirements
232 //{ VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION },
233 { VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION },
234 // Only 1.1 core version of this is supported. The extension has additional requirements
235 //{ VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION },
236 { VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION },
237 // The following extension is only used to add support for Bresenham lines
238 { VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION },
239#ifndef __ANDROID__
240 // We fully support the KHR_swapchain v70 additions, so just track the spec version.
241 { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION },
242#else
243 // We only support V7 of this extension. Missing functionality: in V8,
244 // it becomes possible to pass a VkNativeBufferANDROID structure to
245 // vkBindImageMemory2. Android's swapchain implementation does this in
246 // order to support passing VkBindImageMemorySwapchainInfoKHR
247 // (from KHR_swapchain v70) to vkBindImageMemory2.
248 { VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME, 7 },
249#endif
250#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
251 { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION },
252#endif
253#if SWIFTSHADER_EXTERNAL_MEMORY_LINUX_MEMFD
254 { VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION },
255#endif
256#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
257 { VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION },
258#endif
259 { VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION },
260};
261
262VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
263{
264 TRACE("(const VkInstanceCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkInstance* pInstance = %p)",
265 pCreateInfo, pAllocator, pInstance);
266
267 initializeLibrary();
268
269 if(pCreateInfo->enabledLayerCount)
270 {
271 UNIMPLEMENTED("pCreateInfo->enabledLayerCount");
272 }
273
274 uint32_t extensionPropertiesCount = sizeof(instanceExtensionProperties) / sizeof(instanceExtensionProperties[0]);
275 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i)
276 {
277 if (!HasExtensionProperty(pCreateInfo->ppEnabledExtensionNames[i], instanceExtensionProperties, extensionPropertiesCount))
278 {
279 return VK_ERROR_EXTENSION_NOT_PRESENT;
280 }
281 }
282
283 if(pCreateInfo->pNext)
284 {
285 switch(*reinterpret_cast<const VkStructureType*>(pCreateInfo->pNext))
286 {
287 case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO:
288 // According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
289 // "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
290 // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
291 // internal use by the loader, and do not have corresponding
292 // Vulkan structures in this Specification."
293 break;
294 default:
295 UNIMPLEMENTED("pCreateInfo->pNext");
296 }
297 }
298
299 *pInstance = VK_NULL_HANDLE;
300 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
301
302 VkResult result = vk::DispatchablePhysicalDevice::Create(pAllocator, pCreateInfo, &physicalDevice);
303 if(result != VK_SUCCESS)
304 {
305 return result;
306 }
307
308 result = vk::DispatchableInstance::Create(pAllocator, pCreateInfo, pInstance, physicalDevice);
309 if(result != VK_SUCCESS)
310 {
311 vk::destroy(physicalDevice, pAllocator);
312 return result;
313 }
314
315 return result;
316}
317
318VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
319{
320 TRACE("(VkInstance instance = %p, const VkAllocationCallbacks* pAllocator = %p)", instance, pAllocator);
321
322 vk::destroy(instance, pAllocator);
323}
324
325VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
326{
327 TRACE("(VkInstance instance = %p, uint32_t* pPhysicalDeviceCount = %p, VkPhysicalDevice* pPhysicalDevices = %p)",
328 instance, pPhysicalDeviceCount, pPhysicalDevices);
329
330 return vk::Cast(instance)->getPhysicalDevices(pPhysicalDeviceCount, pPhysicalDevices);
331}
332
333VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
334{
335 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceFeatures* pFeatures = %p)",
336 physicalDevice, pFeatures);
337
338 *pFeatures = vk::Cast(physicalDevice)->getFeatures();
339}
340
341VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
342{
343 TRACE("GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice = %p, VkFormat format = %d, VkFormatProperties* pFormatProperties = %p)",
344 physicalDevice, (int)format, pFormatProperties);
345
346 vk::Cast(physicalDevice)->getFormatProperties(format, pFormatProperties);
347}
348
349VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
350{
351 TRACE("(VkPhysicalDevice physicalDevice = %p, VkFormat format = %d, VkImageType type = %d, VkImageTiling tiling = %d, VkImageUsageFlags usage = %d, VkImageCreateFlags flags = %d, VkImageFormatProperties* pImageFormatProperties = %p)",
352 physicalDevice, (int)format, (int)type, (int)tiling, usage, flags, pImageFormatProperties);
353
354 // "If the combination of parameters to vkGetPhysicalDeviceImageFormatProperties is not supported by the implementation
355 // for use in vkCreateImage, then all members of VkImageFormatProperties will be filled with zero."
356 memset(pImageFormatProperties, 0, sizeof(VkImageFormatProperties));
357
358 VkFormatProperties properties;
359 vk::Cast(physicalDevice)->getFormatProperties(format, &properties);
360
361 VkFormatFeatureFlags features;
362 switch (tiling)
363 {
364 case VK_IMAGE_TILING_LINEAR:
365 features = properties.linearTilingFeatures;
366 break;
367
368 case VK_IMAGE_TILING_OPTIMAL:
369 features = properties.optimalTilingFeatures;
370 break;
371
372 default:
373 UNIMPLEMENTED("tiling");
374 features = 0;
375 }
376
377 if (features == 0)
378 {
379 return VK_ERROR_FORMAT_NOT_SUPPORTED;
380 }
381
382 // Check for usage conflict with features
383 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
384 {
385 return VK_ERROR_FORMAT_NOT_SUPPORTED;
386 }
387
388 if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
389 {
390 return VK_ERROR_FORMAT_NOT_SUPPORTED;
391 }
392
393 if ((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
394 {
395 return VK_ERROR_FORMAT_NOT_SUPPORTED;
396 }
397
398 if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
399 {
400 return VK_ERROR_FORMAT_NOT_SUPPORTED;
401 }
402
403 if ((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
404 {
405 return VK_ERROR_FORMAT_NOT_SUPPORTED;
406 }
407
408 if ((usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
409 {
410 return VK_ERROR_FORMAT_NOT_SUPPORTED;
411 }
412
413 if ((usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
414 {
415 return VK_ERROR_FORMAT_NOT_SUPPORTED;
416 }
417
418 auto allRecognizedUsageBits = VK_IMAGE_USAGE_SAMPLED_BIT |
419 VK_IMAGE_USAGE_STORAGE_BIT |
420 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
421 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
422 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
423 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
424 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
425 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
426 ASSERT(!(usage & ~(allRecognizedUsageBits)));
427
428 // "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
429 // compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
430 if(tiling == VK_IMAGE_TILING_LINEAR)
431 {
432 if(type != VK_IMAGE_TYPE_2D)
433 {
434 return VK_ERROR_FORMAT_NOT_SUPPORTED;
435 }
436
437 if(vk::Format(format).isDepth() || vk::Format(format).isStencil())
438 {
439 return VK_ERROR_FORMAT_NOT_SUPPORTED;
440 }
441 }
442
443 // "Images created with a format from one of those listed in Formats requiring sampler Y'CBCR conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
444 // have further restrictions on their limits and capabilities compared to images created with other formats."
445 if(vk::Format(format).isYcbcrFormat())
446 {
447 if(type != VK_IMAGE_TYPE_2D)
448 {
449 return VK_ERROR_FORMAT_NOT_SUPPORTED;
450 }
451 }
452
453 vk::Cast(physicalDevice)->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
454
455 return VK_SUCCESS;
456}
457
458VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
459{
460 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceProperties* pProperties = %p)",
461 physicalDevice, pProperties);
462
463 *pProperties = vk::Cast(physicalDevice)->getProperties();
464}
465
466VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties)
467{
468 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t* pQueueFamilyPropertyCount = %p, VkQueueFamilyProperties* pQueueFamilyProperties = %p))", physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
469
470 if(!pQueueFamilyProperties)
471 {
472 *pQueueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
473 }
474 else
475 {
476 vk::Cast(physicalDevice)->getQueueFamilyProperties(*pQueueFamilyPropertyCount, pQueueFamilyProperties);
477 }
478}
479
480VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties)
481{
482 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceMemoryProperties* pMemoryProperties = %p)", physicalDevice, pMemoryProperties);
483
484 *pMemoryProperties = vk::Cast(physicalDevice)->getMemoryProperties();
485}
486
487VK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName)
488{
489 TRACE("(VkInstance instance = %p, const char* pName = %p)", instance, pName);
490
491 return vk::GetInstanceProcAddr(vk::Cast(instance), pName);
492}
493
494VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName)
495{
496 TRACE("(VkDevice device = %p, const char* pName = %p)", device, pName);
497
498 return vk::GetDeviceProcAddr(vk::Cast(device), pName);
499}
500
501VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
502{
503 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkDeviceCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDevice* pDevice = %p)",
504 physicalDevice, pCreateInfo, pAllocator, pDevice);
505
506 if(pCreateInfo->enabledLayerCount)
507 {
508 // "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
509 UNIMPLEMENTED("pCreateInfo->enabledLayerCount"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
510 }
511
512 uint32_t extensionPropertiesCount = sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0]);
513 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i)
514 {
515 if (!HasExtensionProperty(pCreateInfo->ppEnabledExtensionNames[i], deviceExtensionProperties, extensionPropertiesCount))
516 {
517 return VK_ERROR_EXTENSION_NOT_PRESENT;
518 }
519 }
520
521 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
522
523 const VkPhysicalDeviceFeatures *enabledFeatures = pCreateInfo->pEnabledFeatures;
524
525 while(extensionCreateInfo)
526 {
527 // Casting to a long since some structures, such as
528 // VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT
529 // are not enumerated in the official Vulkan header
530 switch((long)(extensionCreateInfo->sType))
531 {
532 case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
533 // According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
534 // "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
535 // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
536 // internal use by the loader, and do not have corresponding
537 // Vulkan structures in this Specification."
538 break;
539 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
540 {
541 ASSERT(!pCreateInfo->pEnabledFeatures); // "If the pNext chain includes a VkPhysicalDeviceFeatures2 structure, then pEnabledFeatures must be NULL"
542
543 const VkPhysicalDeviceFeatures2* physicalDeviceFeatures2 = reinterpret_cast<const VkPhysicalDeviceFeatures2*>(extensionCreateInfo);
544
545 enabledFeatures = &physicalDeviceFeatures2->features;
546 }
547 break;
548 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
549 {
550 const VkPhysicalDeviceSamplerYcbcrConversionFeatures* samplerYcbcrConversionFeatures = reinterpret_cast<const VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(extensionCreateInfo);
551
552 // YCbCr conversion is supported.
553 // samplerYcbcrConversionFeatures->samplerYcbcrConversion can be VK_TRUE or VK_FALSE.
554 // No action needs to be taken on our end in either case; it's the apps responsibility that
555 // "To create a sampler Y'CbCr conversion, the samplerYcbcrConversion feature must be enabled."
556 (void)samplerYcbcrConversionFeatures->samplerYcbcrConversion;
557 }
558 break;
559 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
560 {
561 const VkPhysicalDevice16BitStorageFeatures* storage16BitFeatures = reinterpret_cast<const VkPhysicalDevice16BitStorageFeatures*>(extensionCreateInfo);
562
563 if(storage16BitFeatures->storageBuffer16BitAccess == VK_TRUE ||
564 storage16BitFeatures->uniformAndStorageBuffer16BitAccess == VK_TRUE ||
565 storage16BitFeatures->storagePushConstant16 == VK_TRUE ||
566 storage16BitFeatures->storageInputOutput16 == VK_TRUE)
567 {
568 return VK_ERROR_FEATURE_NOT_PRESENT;
569 }
570 }
571 break;
572 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES:
573 {
574 const VkPhysicalDeviceVariablePointerFeatures* variablePointerFeatures = reinterpret_cast<const VkPhysicalDeviceVariablePointerFeatures*>(extensionCreateInfo);
575
576 if(variablePointerFeatures->variablePointersStorageBuffer == VK_TRUE ||
577 variablePointerFeatures->variablePointers == VK_TRUE)
578 {
579 return VK_ERROR_FEATURE_NOT_PRESENT;
580 }
581 }
582 break;
583 case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO:
584 {
585 const VkDeviceGroupDeviceCreateInfo* groupDeviceCreateInfo = reinterpret_cast<const VkDeviceGroupDeviceCreateInfo*>(extensionCreateInfo);
586
587 if((groupDeviceCreateInfo->physicalDeviceCount != 1) ||
588 (groupDeviceCreateInfo->pPhysicalDevices[0] != physicalDevice))
589 {
590 return VK_ERROR_FEATURE_NOT_PRESENT;
591 }
592 }
593 break;
594 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
595 {
596 const VkPhysicalDeviceMultiviewFeatures* multiviewFeatures = reinterpret_cast<const VkPhysicalDeviceMultiviewFeatures*>(extensionCreateInfo);
597
598 if (multiviewFeatures->multiviewGeometryShader ||
599 multiviewFeatures->multiviewTessellationShader)
600 {
601 return VK_ERROR_FEATURE_NOT_PRESENT;
602 }
603 }
604 break;
605 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:
606 {
607 const VkPhysicalDeviceShaderDrawParametersFeatures* shaderDrawParametersFeatures = reinterpret_cast<const VkPhysicalDeviceShaderDrawParametersFeatures*>(extensionCreateInfo);
608
609 if (shaderDrawParametersFeatures->shaderDrawParameters)
610 {
611 return VK_ERROR_FEATURE_NOT_PRESENT;
612 }
613 }
614 break;
615 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
616 {
617 const VkPhysicalDeviceLineRasterizationFeaturesEXT* lineRasterizationFeatures = reinterpret_cast<const VkPhysicalDeviceLineRasterizationFeaturesEXT*>(extensionCreateInfo);
618 if((lineRasterizationFeatures->smoothLines == VK_TRUE) ||
619 (lineRasterizationFeatures->stippledBresenhamLines == VK_TRUE) ||
620 (lineRasterizationFeatures->stippledRectangularLines == VK_TRUE) ||
621 (lineRasterizationFeatures->stippledSmoothLines == VK_TRUE))
622 {
623 return VK_ERROR_FEATURE_NOT_PRESENT;
624 }
625 }
626 break;
627 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
628 {
629 const VkPhysicalDeviceProvokingVertexFeaturesEXT* provokingVertexFeatures = reinterpret_cast<const VkPhysicalDeviceProvokingVertexFeaturesEXT*>(extensionCreateInfo);
630
631 // Provoking vertex is supported.
632 // provokingVertexFeatures->provokingVertexLast can be VK_TRUE or VK_FALSE.
633 // No action needs to be taken on our end in either case; it's the apps responsibility to check
634 // that the provokingVertexLast feature is enabled before using the provoking vertex convention.
635 (void)provokingVertexFeatures->provokingVertexLast;
636 }
637 break;
638 default:
639 // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
640 UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType)); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
641 break;
642 }
643
644 extensionCreateInfo = extensionCreateInfo->pNext;
645 }
646
647 ASSERT(pCreateInfo->queueCreateInfoCount > 0);
648
649 if(enabledFeatures)
650 {
651 if(!vk::Cast(physicalDevice)->hasFeatures(*enabledFeatures))
652 {
653 return VK_ERROR_FEATURE_NOT_PRESENT;
654 }
655 }
656
657 uint32_t queueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
658
659 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
660 {
661 const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
662 if(queueCreateInfo.pNext || queueCreateInfo.flags)
663 {
664 UNIMPLEMENTED("queueCreateInfo.pNext || queueCreateInfo.flags");
665 }
666
667 ASSERT(queueCreateInfo.queueFamilyIndex < queueFamilyPropertyCount);
668 (void)queueFamilyPropertyCount; // Silence unused variable warning
669 }
670
671 auto scheduler = getOrCreateScheduler();
672 return vk::DispatchableDevice::Create(pAllocator, pCreateInfo, pDevice, vk::Cast(physicalDevice), enabledFeatures, scheduler);
673}
674
675VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
676{
677 TRACE("(VkDevice device = %p, const VkAllocationCallbacks* pAllocator = %p)", device, pAllocator);
678
679 vk::destroy(device, pAllocator);
680}
681
682VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
683{
684 TRACE("(const char* pLayerName = %p, uint32_t* pPropertyCount = %p, VkExtensionProperties* pProperties = %p)",
685 pLayerName, pPropertyCount, pProperties);
686
687 uint32_t extensionPropertiesCount = sizeof(instanceExtensionProperties) / sizeof(instanceExtensionProperties[0]);
688
689 if(!pProperties)
690 {
691 *pPropertyCount = extensionPropertiesCount;
692 return VK_SUCCESS;
693 }
694
695 auto toCopy = std::min(*pPropertyCount, extensionPropertiesCount);
696 for(uint32_t i = 0; i < toCopy; i++)
697 {
698 pProperties[i] = instanceExtensionProperties[i];
699 }
700
701 *pPropertyCount = toCopy;
702 return (toCopy < extensionPropertiesCount) ? VK_INCOMPLETE : VK_SUCCESS;
703}
704
705VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
706{
707 TRACE("(VkPhysicalDevice physicalDevice = %p, const char* pLayerName, uint32_t* pPropertyCount = %p, VkExtensionProperties* pProperties = %p)", physicalDevice, pPropertyCount, pProperties);
708
709 uint32_t extensionPropertiesCount = sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0]);
710
711 if(!pProperties)
712 {
713 *pPropertyCount = extensionPropertiesCount;
714 return VK_SUCCESS;
715 }
716
717 auto toCopy = std::min(*pPropertyCount, extensionPropertiesCount);
718 for(uint32_t i = 0; i < toCopy; i++)
719 {
720 pProperties[i] = deviceExtensionProperties[i];
721 }
722
723 *pPropertyCount = toCopy;
724 return (toCopy < extensionPropertiesCount) ? VK_INCOMPLETE : VK_SUCCESS;
725}
726
727VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties)
728{
729 TRACE("(uint32_t* pPropertyCount = %p, VkLayerProperties* pProperties = %p)", pPropertyCount, pProperties);
730
731 if(!pProperties)
732 {
733 *pPropertyCount = 0;
734 return VK_SUCCESS;
735 }
736
737 return VK_SUCCESS;
738}
739
740VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties)
741{
742 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t* pPropertyCount = %p, VkLayerProperties* pProperties = %p)", physicalDevice, pPropertyCount, pProperties);
743
744 if(!pProperties)
745 {
746 *pPropertyCount = 0;
747 return VK_SUCCESS;
748 }
749
750 return VK_SUCCESS;
751}
752
753VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue)
754{
755 TRACE("(VkDevice device = %p, uint32_t queueFamilyIndex = %d, uint32_t queueIndex = %d, VkQueue* pQueue = %p)",
756 device, queueFamilyIndex, queueIndex, pQueue);
757
758 *pQueue = vk::Cast(device)->getQueue(queueFamilyIndex, queueIndex);
759}
760
761VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
762{
763 TRACE("(VkQueue queue = %p, uint32_t submitCount = %d, const VkSubmitInfo* pSubmits = %p, VkFence fence = %p)",
764 queue, submitCount, pSubmits, static_cast<void*>(fence));
765
766 return vk::Cast(queue)->submit(submitCount, pSubmits, vk::Cast(fence));
767}
768
769VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue)
770{
771 TRACE("(VkQueue queue = %p)", queue);
772
773 return vk::Cast(queue)->waitIdle();
774}
775
776VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device)
777{
778 TRACE("(VkDevice device = %p)", device);
779
780 return vk::Cast(device)->waitIdle();
781}
782
783VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
784{
785 TRACE("(VkDevice device = %p, const VkMemoryAllocateInfo* pAllocateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDeviceMemory* pMemory = %p)",
786 device, pAllocateInfo, pAllocator, pMemory);
787
788 const VkBaseInStructure* allocationInfo = reinterpret_cast<const VkBaseInStructure*>(pAllocateInfo->pNext);
789 while(allocationInfo)
790 {
791 switch(allocationInfo->sType)
792 {
793 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
794 // This can safely be ignored, as the Vulkan spec mentions:
795 // "If the pNext chain includes a VkMemoryDedicatedAllocateInfo structure, then that structure
796 // includes a handle of the sole buffer or image resource that the memory *can* be bound to."
797 break;
798 case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO:
799 // This extension controls on which physical devices the memory gets allocated.
800 // SwiftShader only has a single physical device, so this extension does nothing in this case.
801 break;
802#if SWIFTSHADER_EXTERNAL_MEMORY_LINUX_MEMFD
803 case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
804 {
805 auto* importInfo = reinterpret_cast<const VkImportMemoryFdInfoKHR *>(allocationInfo);
806 if (importInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
807 {
808 UNSUPPORTED("importInfo->handleType %u", importInfo->handleType);
809 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
810 }
811 break;
812 }
813 case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
814 {
815 auto* exportInfo = reinterpret_cast<const VkExportMemoryAllocateInfo *>(allocationInfo);
816 if (exportInfo->handleTypes != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
817 {
818 UNSUPPORTED("exportInfo->handleTypes %u", exportInfo->handleTypes);
819 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
820 }
821 break;
822 }
823#endif
824 default:
825 UNIMPLEMENTED("allocationInfo->sType %u", allocationInfo->sType);
826 break;
827 }
828
829 allocationInfo = allocationInfo->pNext;
830 }
831
832 VkResult result = vk::DeviceMemory::Create(pAllocator, pAllocateInfo, pMemory);
833 if(result != VK_SUCCESS)
834 {
835 return result;
836 }
837
838 // Make sure the memory allocation is done now so that OOM errors can be checked now
839 result = vk::Cast(*pMemory)->allocate();
840 if(result != VK_SUCCESS)
841 {
842 vk::destroy(*pMemory, pAllocator);
843 *pMemory = VK_NULL_HANDLE;
844 }
845
846 return result;
847}
848
849VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
850{
851 TRACE("(VkDevice device = %p, VkDeviceMemory memory = %p, const VkAllocationCallbacks* pAllocator = %p)",
852 device, static_cast<void*>(memory), pAllocator);
853
854 vk::destroy(memory, pAllocator);
855}
856
857#if SWIFTSHADER_EXTERNAL_MEMORY_LINUX_MEMFD
858VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR(VkDevice device, const VkMemoryGetFdInfoKHR* getFdInfo, int* pFd)
859{
860 TRACE("(VkDevice device = %p, const VkMemoryGetFdInfoKHR* getFdInfo = %p, int* pFd = %p",
861 device, getFdInfo, pFd);
862
863 if (getFdInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
864 {
865 UNSUPPORTED("pGetFdInfo->handleType %u", getFdInfo->handleType);
866 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
867 }
868 return vk::Cast(getFdInfo->memory)->exportFd(pFd);
869}
870
871VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties)
872{
873 TRACE("(VkDevice device = %p, VkExternalMemoryHandleTypeFlagBits handleType = %x, int fd = %d, VkMemoryFdPropertiesKHR* pMemoryFdProperties = %p)",
874 device, handleType, fd, pMemoryFdProperties);
875
876 if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
877 {
878 UNSUPPORTED("handleType %u", handleType);
879 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
880 }
881
882 if (fd < 0)
883 {
884 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
885 }
886
887 const VkPhysicalDeviceMemoryProperties& memoryProperties =
888 vk::Cast(device)->getPhysicalDevice()->getMemoryProperties();
889
890 // All SwiftShader memory types support this!
891 pMemoryFdProperties->memoryTypeBits = (1U << memoryProperties.memoryTypeCount) - 1U;
892
893 return VK_SUCCESS;
894}
895#endif // SWIFTSHADER_EXTERNAL_MEMORY_LINUX_MEMFD
896
897VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
898{
899 TRACE("(VkDevice device = %p, VkDeviceMemory memory = %p, VkDeviceSize offset = %d, VkDeviceSize size = %d, VkMemoryMapFlags flags = %d, void** ppData = %p)",
900 device, static_cast<void*>(memory), int(offset), int(size), flags, ppData);
901
902 return vk::Cast(memory)->map(offset, size, ppData);
903}
904
905VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
906{
907 TRACE("(VkDevice device = %p, VkDeviceMemory memory = %p)", device, static_cast<void*>(memory));
908
909 // Noop, memory will be released when the DeviceMemory object is released
910}
911
912VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
913{
914 TRACE("(VkDevice device = %p, uint32_t memoryRangeCount = %d, const VkMappedMemoryRange* pMemoryRanges = %p)",
915 device, memoryRangeCount, pMemoryRanges);
916
917 // Noop, host and device memory are the same to SwiftShader
918
919 return VK_SUCCESS;
920}
921
922VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
923{
924 TRACE("(VkDevice device = %p, uint32_t memoryRangeCount = %d, const VkMappedMemoryRange* pMemoryRanges = %p)",
925 device, memoryRangeCount, pMemoryRanges);
926
927 // Noop, host and device memory are the same to SwiftShader
928
929 return VK_SUCCESS;
930}
931
932VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice pDevice, VkDeviceMemory pMemory, VkDeviceSize* pCommittedMemoryInBytes)
933{
934 TRACE("(VkDevice device = %p, VkDeviceMemory memory = %p, VkDeviceSize* pCommittedMemoryInBytes = %p)",
935 pDevice, static_cast<void*>(pMemory), pCommittedMemoryInBytes);
936
937 auto memory = vk::Cast(pMemory);
938
939#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
940 const auto& memoryProperties = vk::Cast(pDevice)->getPhysicalDevice()->getMemoryProperties();
941 uint32_t typeIndex = memory->getMemoryTypeIndex();
942 ASSERT(typeIndex < memoryProperties.memoryTypeCount);
943 ASSERT(memoryProperties.memoryTypes[typeIndex].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
944#endif
945
946 *pCommittedMemoryInBytes = memory->getCommittedMemoryInBytes();
947}
948
949VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
950{
951 TRACE("(VkDevice device = %p, VkBuffer buffer = %p, VkDeviceMemory memory = %p, VkDeviceSize memoryOffset = %d)",
952 device, static_cast<void*>(buffer), static_cast<void*>(memory), int(memoryOffset));
953
954 if (!vk::Cast(buffer)->canBindToMemory(vk::Cast(memory)))
955 {
956 UNSUPPORTED("vkBindBufferMemory with invalid external memory");
957 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
958 }
959 vk::Cast(buffer)->bind(vk::Cast(memory), memoryOffset);
960 return VK_SUCCESS;
961}
962
963VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)
964{
965 TRACE("(VkDevice device = %p, VkImage image = %p, VkDeviceMemory memory = %p, VkDeviceSize memoryOffset = %d)",
966 device, static_cast<void*>(image), static_cast<void*>(memory), int(memoryOffset));
967
968 if (!vk::Cast(image)->canBindToMemory(vk::Cast(memory)))
969 {
970 UNSUPPORTED("vkBindImageMemory with invalid external memory");
971 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
972 }
973 vk::Cast(image)->bind(vk::Cast(memory), memoryOffset);
974 return VK_SUCCESS;
975}
976
977VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
978{
979 TRACE("(VkDevice device = %p, VkBuffer buffer = %p, VkMemoryRequirements* pMemoryRequirements = %p)",
980 device, static_cast<void*>(buffer), pMemoryRequirements);
981
982 *pMemoryRequirements = vk::Cast(buffer)->getMemoryRequirements();
983}
984
985VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements)
986{
987 TRACE("(VkDevice device = %p, VkImage image = %p, VkMemoryRequirements* pMemoryRequirements = %p)",
988 device, static_cast<void*>(image), pMemoryRequirements);
989
990 *pMemoryRequirements = vk::Cast(image)->getMemoryRequirements();
991}
992
993VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
994{
995 TRACE("(VkDevice device = %p, VkImage image = %p, uint32_t* pSparseMemoryRequirementCount = %p, VkSparseImageMemoryRequirements* pSparseMemoryRequirements = %p)",
996 device, static_cast<void*>(image), pSparseMemoryRequirementCount, pSparseMemoryRequirements);
997
998 // The 'sparseBinding' feature is not supported, so images can not be created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag.
999 // "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to."
1000 *pSparseMemoryRequirementCount = 0;
1001}
1002
1003VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
1004{
1005 TRACE("(VkPhysicalDevice physicalDevice = %p, VkFormat format = %d, VkImageType type = %d, VkSampleCountFlagBits samples = %d, VkImageUsageFlags usage = %d, VkImageTiling tiling = %d, uint32_t* pPropertyCount = %p, VkSparseImageFormatProperties* pProperties = %p)",
1006 physicalDevice, format, type, samples, usage, tiling, pPropertyCount, pProperties);
1007
1008 // We do not support sparse images.
1009 *pPropertyCount = 0;
1010}
1011
1012VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence)
1013{
1014 TRACE("()");
1015 UNIMPLEMENTED("vkQueueBindSparse");
1016 return VK_SUCCESS;
1017}
1018
1019VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence)
1020{
1021 TRACE("(VkDevice device = %p, const VkFenceCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkFence* pFence = %p)",
1022 device, pCreateInfo, pAllocator, pFence);
1023
1024 if(pCreateInfo->pNext)
1025 {
1026 UNIMPLEMENTED("pCreateInfo->pNext");
1027 }
1028
1029 return vk::Fence::Create(pAllocator, pCreateInfo, pFence);
1030}
1031
1032VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator)
1033{
1034 TRACE("(VkDevice device = %p, VkFence fence = %p, const VkAllocationCallbacks* pAllocator = %p)",
1035 device, static_cast<void*>(fence), pAllocator);
1036
1037 vk::destroy(fence, pAllocator);
1038}
1039
1040VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences)
1041{
1042 TRACE("(VkDevice device = %p, uint32_t fenceCount = %d, const VkFence* pFences = %p)",
1043 device, fenceCount, pFences);
1044
1045 for(uint32_t i = 0; i < fenceCount; i++)
1046 {
1047 vk::Cast(pFences[i])->reset();
1048 }
1049
1050 return VK_SUCCESS;
1051}
1052
1053VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence)
1054{
1055 TRACE("(VkDevice device = %p, VkFence fence = %p)", device, static_cast<void*>(fence));
1056
1057 return vk::Cast(fence)->getStatus();
1058}
1059
1060VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
1061{
1062 TRACE("(VkDevice device = %p, uint32_t fenceCount = %d, const VkFence* pFences = %p, VkBool32 waitAll = %d, uint64_t timeout = %d)",
1063 device, int(fenceCount), pFences, int(waitAll), int(timeout));
1064
1065 return vk::Cast(device)->waitForFences(fenceCount, pFences, waitAll, timeout);
1066}
1067
1068VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore)
1069{
1070 TRACE("(VkDevice device = %p, const VkSemaphoreCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSemaphore* pSemaphore = %p)",
1071 device, pCreateInfo, pAllocator, pSemaphore);
1072
1073 if(pCreateInfo->flags)
1074 {
1075 UNIMPLEMENTED("pCreateInfo->flags");
1076 }
1077
1078 return vk::Semaphore::Create(pAllocator, pCreateInfo, pSemaphore);
1079}
1080
1081VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
1082{
1083 TRACE("(VkDevice device = %p, VkSemaphore semaphore = %p, const VkAllocationCallbacks* pAllocator = %p)",
1084 device, static_cast<void*>(semaphore), pAllocator);
1085
1086 vk::destroy(semaphore, pAllocator);
1087}
1088
1089#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
1090VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd)
1091{
1092 TRACE("(VkDevice device = %p, const VkSemaphoreGetFdInfoKHR* pGetFdInfo = %p, int* pFd = %p)",
1093 device, static_cast<const void*>(pGetFdInfo), static_cast<void*>(pFd));
1094
1095 if (pGetFdInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
1096 {
1097 UNIMPLEMENTED("pGetFdInfo->handleType");
1098 }
1099
1100 return vk::Cast(pGetFdInfo->semaphore)->exportFd(pFd);
1101}
1102
1103VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreInfo)
1104{
1105 TRACE("(VkDevice device = %p, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreInfo = %p",
1106 device, static_cast<const void*>(pImportSemaphoreInfo));
1107
1108 if (pImportSemaphoreInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
1109 {
1110 UNIMPLEMENTED("pImportSemaphoreInfo->handleType");
1111 }
1112 bool temporaryImport = (pImportSemaphoreInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0;
1113
1114 return vk::Cast(pImportSemaphoreInfo->semaphore)->importFd(pImportSemaphoreInfo->fd, temporaryImport);
1115}
1116#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
1117
1118#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
1119VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
1120 VkDevice device,
1121 const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo)
1122{
1123 TRACE("(VkDevice device = %p, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo = %p)",
1124 device, pImportSemaphoreZirconHandleInfo);
1125
1126 if (pImportSemaphoreZirconHandleInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
1127 {
1128 UNIMPLEMENTED("pImportSemaphoreZirconHandleInfo->handleType");
1129 }
1130 bool temporaryImport = (pImportSemaphoreZirconHandleInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) != 0;
1131
1132 return vk::Cast(pImportSemaphoreZirconHandleInfo->semaphore)->importHandle(
1133 pImportSemaphoreZirconHandleInfo->handle,
1134 temporaryImport);
1135}
1136
1137VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA(
1138 VkDevice device,
1139 const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
1140 zx_handle_t* pZirconHandle)
1141{
1142 TRACE("(VkDevice device = %p, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo = %p, zx_handle_t* pZirconHandle = %p)",
1143 device, static_cast<const void*>(pGetZirconHandleInfo), static_cast<void*>(pZirconHandle));
1144
1145 if (pGetZirconHandleInfo->handleType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
1146 {
1147 UNIMPLEMENTED("pGetZirconHandleInfo->handleType");
1148 }
1149
1150 return vk::Cast(pGetZirconHandleInfo->semaphore)->exportHandle(pZirconHandle);
1151}
1152#endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
1153
1154VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent)
1155{
1156 TRACE("(VkDevice device = %p, const VkEventCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkEvent* pEvent = %p)",
1157 device, pCreateInfo, pAllocator, pEvent);
1158
1159 if(pCreateInfo->pNext || pCreateInfo->flags)
1160 {
1161 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1162 }
1163
1164 return vk::Event::Create(pAllocator, pCreateInfo, pEvent);
1165}
1166
1167VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator)
1168{
1169 TRACE("(VkDevice device = %p, VkEvent event = %p, const VkAllocationCallbacks* pAllocator = %p)",
1170 device, static_cast<void*>(event), pAllocator);
1171
1172 vk::destroy(event, pAllocator);
1173}
1174
1175VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event)
1176{
1177 TRACE("(VkDevice device = %p, VkEvent event = %p)", device, static_cast<void*>(event));
1178
1179 return vk::Cast(event)->getStatus();
1180}
1181
1182VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event)
1183{
1184 TRACE("(VkDevice device = %p, VkEvent event = %p)", device, static_cast<void*>(event));
1185
1186 vk::Cast(event)->signal();
1187
1188 return VK_SUCCESS;
1189}
1190
1191VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event)
1192{
1193 TRACE("(VkDevice device = %p, VkEvent event = %p)", device, static_cast<void*>(event));
1194
1195 vk::Cast(event)->reset();
1196
1197 return VK_SUCCESS;
1198}
1199
1200VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool)
1201{
1202 TRACE("(VkDevice device = %p, const VkQueryPoolCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkQueryPool* pQueryPool = %p)",
1203 device, pCreateInfo, pAllocator, pQueryPool);
1204
1205 if(pCreateInfo->pNext || pCreateInfo->flags)
1206 {
1207 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1208 }
1209
1210 return vk::QueryPool::Create(pAllocator, pCreateInfo, pQueryPool);
1211}
1212
1213VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
1214{
1215 TRACE("(VkDevice device = %p, VkQueryPool queryPool = %p, const VkAllocationCallbacks* pAllocator = %p)",
1216 device, static_cast<void*>(queryPool), pAllocator);
1217
1218 vk::destroy(queryPool, pAllocator);
1219}
1220
1221VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags)
1222{
1223 TRACE("(VkDevice device = %p, VkQueryPool queryPool = %p, uint32_t firstQuery = %d, uint32_t queryCount = %d, size_t dataSize = %d, void* pData = %p, VkDeviceSize stride = %d, VkQueryResultFlags flags = %d)",
1224 device, static_cast<void*>(queryPool), int(firstQuery), int(queryCount), int(dataSize), pData, int(stride), flags);
1225
1226 return vk::Cast(queryPool)->getResults(firstQuery, queryCount, dataSize, pData, stride, flags);
1227}
1228
1229VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer)
1230{
1231 TRACE("(VkDevice device = %p, const VkBufferCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkBuffer* pBuffer = %p)",
1232 device, pCreateInfo, pAllocator, pBuffer);
1233
1234 auto* nextInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1235 while (nextInfo)
1236 {
1237 switch (nextInfo->sType)
1238 {
1239 case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO:
1240 // Do nothing. Should be handled by vk::Buffer::Create().
1241 break;
1242 default:
1243 UNIMPLEMENTED("pCreateInfo->pNext sType=0x%X", nextInfo->sType);
1244 }
1245 nextInfo = nextInfo->pNext;
1246 }
1247
1248 return vk::Buffer::Create(pAllocator, pCreateInfo, pBuffer);
1249}
1250
1251VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
1252{
1253 TRACE("(VkDevice device = %p, VkBuffer buffer = %p, const VkAllocationCallbacks* pAllocator = %p)",
1254 device, static_cast<void*>(buffer), pAllocator);
1255
1256 vk::destroy(buffer, pAllocator);
1257}
1258
1259VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)
1260{
1261 TRACE("(VkDevice device = %p, const VkBufferViewCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkBufferView* pView = %p)",
1262 device, pCreateInfo, pAllocator, pView);
1263
1264 if(pCreateInfo->pNext || pCreateInfo->flags)
1265 {
1266 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1267 }
1268
1269 return vk::BufferView::Create(pAllocator, pCreateInfo, pView);
1270}
1271
1272VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
1273{
1274 TRACE("(VkDevice device = %p, VkBufferView bufferView = %p, const VkAllocationCallbacks* pAllocator = %p)",
1275 device, static_cast<void*>(bufferView), pAllocator);
1276
1277 vk::destroy(bufferView, pAllocator);
1278}
1279
1280VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
1281{
1282 TRACE("(VkDevice device = %p, const VkImageCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkImage* pImage = %p)",
1283 device, pCreateInfo, pAllocator, pImage);
1284
1285 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1286
1287#ifdef __ANDROID__
1288 vk::BackingMemory backmem;
1289 bool swapchainImage = false;
1290#endif
1291
1292 while(extensionCreateInfo)
1293 {
1294 switch((long)(extensionCreateInfo->sType))
1295 {
1296#ifdef __ANDROID__
1297 case VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID:
1298 {
1299 const VkSwapchainImageCreateInfoANDROID* swapImageCreateInfo = reinterpret_cast<const VkSwapchainImageCreateInfoANDROID*>(extensionCreateInfo);
1300 backmem.androidUsage = swapImageCreateInfo->usage;
1301 }
1302 break;
1303 case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID:
1304 {
1305 const VkNativeBufferANDROID* nativeBufferInfo = reinterpret_cast<const VkNativeBufferANDROID*>(extensionCreateInfo);
1306 backmem.nativeHandle = nativeBufferInfo->handle;
1307 backmem.stride = nativeBufferInfo->stride;
1308 swapchainImage = true;
1309 }
1310 break;
1311#endif
1312 case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO:
1313 // Do nothing. Should be handled by vk::Image::Create()
1314 break;
1315 case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
1316 /* Do nothing. We don't actually need the swapchain handle yet; we'll do all the work in vkBindImageMemory2. */
1317 break;
1318 default:
1319 // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
1320 UNIMPLEMENTED("extensionCreateInfo->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
1321 break;
1322 }
1323
1324 extensionCreateInfo = extensionCreateInfo->pNext;
1325 }
1326
1327 VkResult result = vk::Image::Create(pAllocator, pCreateInfo, pImage, vk::Cast(device));
1328
1329#ifdef __ANDROID__
1330 if (swapchainImage)
1331 {
1332 if (result != VK_SUCCESS)
1333 {
1334 return result;
1335 }
1336
1337 vk::Image* image = vk::Cast(*pImage);
1338 VkMemoryRequirements memRequirements = image->getMemoryRequirements();
1339
1340 VkMemoryAllocateInfo allocInfo = {};
1341 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1342 allocInfo.allocationSize = memRequirements.size;
1343 allocInfo.memoryTypeIndex = 0;
1344
1345 VkDeviceMemory devmem = { VK_NULL_HANDLE };
1346 result = vkAllocateMemory(device, &allocInfo, pAllocator, &devmem);
1347 if(result != VK_SUCCESS)
1348 {
1349 return result;
1350 }
1351
1352 vkBindImageMemory(device, *pImage, devmem, 0);
1353 backmem.externalMemory = true;
1354
1355 image->setBackingMemory(backmem);
1356 }
1357#endif
1358
1359 return result;
1360}
1361
1362VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
1363{
1364 TRACE("(VkDevice device = %p, VkImage image = %p, const VkAllocationCallbacks* pAllocator = %p)",
1365 device, static_cast<void*>(image), pAllocator);
1366
1367#ifdef __ANDROID__
1368 vk::Image* img = vk::Cast(image);
1369 if(img && img->hasExternalMemory())
1370 {
1371 vk::destroy(img->getExternalMemory(), pAllocator);
1372 }
1373#endif
1374
1375 vk::destroy(image, pAllocator);
1376}
1377
1378VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)
1379{
1380 TRACE("(VkDevice device = %p, VkImage image = %p, const VkImageSubresource* pSubresource = %p, VkSubresourceLayout* pLayout = %p)",
1381 device, static_cast<void*>(image), pSubresource, pLayout);
1382
1383 vk::Cast(image)->getSubresourceLayout(pSubresource, pLayout);
1384}
1385
1386VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
1387{
1388 TRACE("(VkDevice device = %p, const VkImageViewCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkImageView* pView = %p)",
1389 device, pCreateInfo, pAllocator, pView);
1390
1391 if(pCreateInfo->flags)
1392 {
1393 UNIMPLEMENTED("pCreateInfo->flags");
1394 }
1395
1396 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1397 const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
1398
1399 while(extensionCreateInfo)
1400 {
1401 switch(extensionCreateInfo->sType)
1402 {
1403 case VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR:
1404 {
1405 const VkImageViewUsageCreateInfo* multiviewCreateInfo = reinterpret_cast<const VkImageViewUsageCreateInfo*>(extensionCreateInfo);
1406 ASSERT(!(~vk::Cast(pCreateInfo->image)->getUsage() & multiviewCreateInfo->usage));
1407 }
1408 break;
1409 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
1410 {
1411 const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(extensionCreateInfo);
1412 ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion);
1413
1414 if(ycbcrConversion)
1415 {
1416 ASSERT((pCreateInfo->components.r == VK_COMPONENT_SWIZZLE_IDENTITY) &&
1417 (pCreateInfo->components.g == VK_COMPONENT_SWIZZLE_IDENTITY) &&
1418 (pCreateInfo->components.b == VK_COMPONENT_SWIZZLE_IDENTITY) &&
1419 (pCreateInfo->components.a == VK_COMPONENT_SWIZZLE_IDENTITY));
1420 }
1421 }
1422 break;
1423 default:
1424 UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
1425 break;
1426 }
1427
1428 extensionCreateInfo = extensionCreateInfo->pNext;
1429 }
1430
1431 return vk::ImageView::Create(pAllocator, pCreateInfo, pView, ycbcrConversion);
1432}
1433
1434VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
1435{
1436 TRACE("(VkDevice device = %p, VkImageView imageView = %p, const VkAllocationCallbacks* pAllocator = %p)",
1437 device, static_cast<void*>(imageView), pAllocator);
1438
1439 vk::destroy(imageView, pAllocator);
1440}
1441
1442VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule)
1443{
1444 TRACE("(VkDevice device = %p, const VkShaderModuleCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkShaderModule* pShaderModule = %p)",
1445 device, pCreateInfo, pAllocator, pShaderModule);
1446
1447 if(pCreateInfo->pNext || pCreateInfo->flags)
1448 {
1449 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1450 }
1451
1452 return vk::ShaderModule::Create(pAllocator, pCreateInfo, pShaderModule);
1453}
1454
1455VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
1456{
1457 TRACE("(VkDevice device = %p, VkShaderModule shaderModule = %p, const VkAllocationCallbacks* pAllocator = %p)",
1458 device, static_cast<void*>(shaderModule), pAllocator);
1459
1460 vk::destroy(shaderModule, pAllocator);
1461}
1462
1463VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)
1464{
1465 TRACE("(VkDevice device = %p, const VkPipelineCacheCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkPipelineCache* pPipelineCache = %p)",
1466 device, pCreateInfo, pAllocator, pPipelineCache);
1467
1468 if(pCreateInfo->pNext || pCreateInfo->flags)
1469 {
1470 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1471 }
1472
1473 return vk::PipelineCache::Create(pAllocator, pCreateInfo, pPipelineCache);
1474}
1475
1476VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
1477{
1478 TRACE("(VkDevice device = %p, VkPipelineCache pipelineCache = %p, const VkAllocationCallbacks* pAllocator = %p)",
1479 device, static_cast<void*>(pipelineCache), pAllocator);
1480
1481 vk::destroy(pipelineCache, pAllocator);
1482}
1483
1484VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData)
1485{
1486 TRACE("(VkDevice device = %p, VkPipelineCache pipelineCache = %p, size_t* pDataSize = %p, void* pData = %p)",
1487 device, static_cast<void*>(pipelineCache), pDataSize, pData);
1488
1489 return vk::Cast(pipelineCache)->getData(pDataSize, pData);
1490}
1491
1492VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
1493{
1494 TRACE("(VkDevice device = %p, VkPipelineCache dstCache = %p, uint32_t srcCacheCount = %d, const VkPipelineCache* pSrcCaches = %p)",
1495 device, static_cast<void*>(dstCache), int(srcCacheCount), pSrcCaches);
1496
1497 return vk::Cast(dstCache)->merge(srcCacheCount, pSrcCaches);
1498}
1499
1500VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
1501{
1502 TRACE("(VkDevice device = %p, VkPipelineCache pipelineCache = %p, uint32_t createInfoCount = %d, const VkGraphicsPipelineCreateInfo* pCreateInfos = %p, const VkAllocationCallbacks* pAllocator = %p, VkPipeline* pPipelines = %p)",
1503 device, static_cast<void*>(pipelineCache), int(createInfoCount), pCreateInfos, pAllocator, pPipelines);
1504
1505 VkResult errorResult = VK_SUCCESS;
1506 for(uint32_t i = 0; i < createInfoCount; i++)
1507 {
1508 VkResult result = vk::GraphicsPipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i], vk::Cast(device));
1509
1510 if(result == VK_SUCCESS)
1511 {
1512 static_cast<vk::GraphicsPipeline*>(vk::Cast(pPipelines[i]))->compileShaders(pAllocator, &pCreateInfos[i], vk::Cast(pipelineCache));
1513 }
1514 else
1515 {
1516 // According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
1517 // "When an application attempts to create many pipelines in a single command,
1518 // it is possible that some subset may fail creation. In that case, the
1519 // corresponding entries in the pPipelines output array will be filled with
1520 // VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
1521 // out of memory errors), the vkCreate*Pipelines commands will return an
1522 // error code. The implementation will attempt to create all pipelines, and
1523 // only return VK_NULL_HANDLE values for those that actually failed."
1524 pPipelines[i] = VK_NULL_HANDLE;
1525 errorResult = result;
1526 }
1527 }
1528
1529 return errorResult;
1530}
1531
1532VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
1533{
1534 TRACE("(VkDevice device = %p, VkPipelineCache pipelineCache = %p, uint32_t createInfoCount = %d, const VkComputePipelineCreateInfo* pCreateInfos = %p, const VkAllocationCallbacks* pAllocator = %p, VkPipeline* pPipelines = %p)",
1535 device, static_cast<void*>(pipelineCache), int(createInfoCount), pCreateInfos, pAllocator, pPipelines);
1536
1537 VkResult errorResult = VK_SUCCESS;
1538 for(uint32_t i = 0; i < createInfoCount; i++)
1539 {
1540 VkResult result = vk::ComputePipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i], vk::Cast(device));
1541
1542 if(result == VK_SUCCESS)
1543 {
1544 static_cast<vk::ComputePipeline*>(vk::Cast(pPipelines[i]))->compileShaders(pAllocator, &pCreateInfos[i], vk::Cast(pipelineCache));
1545 }
1546 else
1547 {
1548 // According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
1549 // "When an application attempts to create many pipelines in a single command,
1550 // it is possible that some subset may fail creation. In that case, the
1551 // corresponding entries in the pPipelines output array will be filled with
1552 // VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
1553 // out of memory errors), the vkCreate*Pipelines commands will return an
1554 // error code. The implementation will attempt to create all pipelines, and
1555 // only return VK_NULL_HANDLE values for those that actually failed."
1556 pPipelines[i] = VK_NULL_HANDLE;
1557 errorResult = result;
1558 }
1559 }
1560
1561 return errorResult;
1562}
1563
1564VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
1565{
1566 TRACE("(VkDevice device = %p, VkPipeline pipeline = %p, const VkAllocationCallbacks* pAllocator = %p)",
1567 device, static_cast<void*>(pipeline), pAllocator);
1568
1569 vk::destroy(pipeline, pAllocator);
1570}
1571
1572VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout)
1573{
1574 TRACE("(VkDevice device = %p, const VkPipelineLayoutCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkPipelineLayout* pPipelineLayout = %p)",
1575 device, pCreateInfo, pAllocator, pPipelineLayout);
1576
1577 if(pCreateInfo->pNext || pCreateInfo->flags)
1578 {
1579 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1580 }
1581
1582 return vk::PipelineLayout::Create(pAllocator, pCreateInfo, pPipelineLayout);
1583}
1584
1585VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
1586{
1587 TRACE("(VkDevice device = %p, VkPipelineLayout pipelineLayout = %p, const VkAllocationCallbacks* pAllocator = %p)",
1588 device, static_cast<void*>(pipelineLayout), pAllocator);
1589
1590 vk::destroy(pipelineLayout, pAllocator);
1591}
1592
1593VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler)
1594{
1595 TRACE("(VkDevice device = %p, const VkSamplerCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSampler* pSampler = %p)",
1596 device, pCreateInfo, pAllocator, pSampler);
1597
1598 if(pCreateInfo->flags)
1599 {
1600 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1601 }
1602
1603 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1604 const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
1605
1606 while(extensionCreateInfo)
1607 {
1608 switch(extensionCreateInfo->sType)
1609 {
1610 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
1611 {
1612 const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(extensionCreateInfo);
1613 ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion);
1614 }
1615 break;
1616 default:
1617 UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
1618 break;
1619 }
1620
1621 extensionCreateInfo = extensionCreateInfo->pNext;
1622 }
1623
1624 return vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, ycbcrConversion);
1625}
1626
1627VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
1628{
1629 TRACE("(VkDevice device = %p, VkSampler sampler = %p, const VkAllocationCallbacks* pAllocator = %p)",
1630 device, static_cast<void*>(sampler), pAllocator);
1631
1632 vk::destroy(sampler, pAllocator);
1633}
1634
1635VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout)
1636{
1637 TRACE("(VkDevice device = %p, const VkDescriptorSetLayoutCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDescriptorSetLayout* pSetLayout = %p)",
1638 device, pCreateInfo, pAllocator, pSetLayout);
1639
1640 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1641
1642 while(extensionCreateInfo)
1643 {
1644 switch(extensionCreateInfo->sType)
1645 {
1646 case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT:
1647 ASSERT(!vk::Cast(device)->hasExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME));
1648 break;
1649 default:
1650 UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
1651 break;
1652 }
1653
1654 extensionCreateInfo = extensionCreateInfo->pNext;
1655 }
1656
1657 return vk::DescriptorSetLayout::Create(pAllocator, pCreateInfo, pSetLayout);
1658}
1659
1660VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
1661{
1662 TRACE("(VkDevice device = %p, VkDescriptorSetLayout descriptorSetLayout = %p, const VkAllocationCallbacks* pAllocator = %p)",
1663 device, static_cast<void*>(descriptorSetLayout), pAllocator);
1664
1665 vk::destroy(descriptorSetLayout, pAllocator);
1666}
1667
1668VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool)
1669{
1670 TRACE("(VkDevice device = %p, const VkDescriptorPoolCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDescriptorPool* pDescriptorPool = %p)",
1671 device, pCreateInfo, pAllocator, pDescriptorPool);
1672
1673 if(pCreateInfo->pNext)
1674 {
1675 UNIMPLEMENTED("pCreateInfo->pNext");
1676 }
1677
1678 return vk::DescriptorPool::Create(pAllocator, pCreateInfo, pDescriptorPool);
1679}
1680
1681VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
1682{
1683 TRACE("(VkDevice device = %p, VkDescriptorPool descriptorPool = %p, const VkAllocationCallbacks* pAllocator = %p)",
1684 device, static_cast<void*>(descriptorPool), pAllocator);
1685
1686 vk::destroy(descriptorPool, pAllocator);
1687}
1688
1689VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
1690{
1691 TRACE("(VkDevice device = %p, VkDescriptorPool descriptorPool = %p, VkDescriptorPoolResetFlags flags = 0x%x)",
1692 device, static_cast<void*>(descriptorPool), int(flags));
1693
1694 if(flags)
1695 {
1696 UNIMPLEMENTED("flags");
1697 }
1698
1699 return vk::Cast(descriptorPool)->reset();
1700}
1701
1702VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
1703{
1704 TRACE("(VkDevice device = %p, const VkDescriptorSetAllocateInfo* pAllocateInfo = %p, VkDescriptorSet* pDescriptorSets = %p)",
1705 device, pAllocateInfo, pDescriptorSets);
1706
1707 if(pAllocateInfo->pNext)
1708 {
1709 UNIMPLEMENTED("pAllocateInfo->pNext");
1710 }
1711
1712 return vk::Cast(pAllocateInfo->descriptorPool)->allocateSets(
1713 pAllocateInfo->descriptorSetCount, pAllocateInfo->pSetLayouts, pDescriptorSets);
1714}
1715
1716VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets)
1717{
1718 TRACE("(VkDevice device = %p, VkDescriptorPool descriptorPool = %p, uint32_t descriptorSetCount = %d, const VkDescriptorSet* pDescriptorSets = %p)",
1719 device, static_cast<void*>(descriptorPool), descriptorSetCount, pDescriptorSets);
1720
1721 vk::Cast(descriptorPool)->freeSets(descriptorSetCount, pDescriptorSets);
1722
1723 return VK_SUCCESS;
1724}
1725
1726VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies)
1727{
1728 TRACE("(VkDevice device = %p, uint32_t descriptorWriteCount = %d, const VkWriteDescriptorSet* pDescriptorWrites = %p, uint32_t descriptorCopyCount = %d, const VkCopyDescriptorSet* pDescriptorCopies = %p)",
1729 device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
1730
1731 vk::Cast(device)->updateDescriptorSets(descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
1732}
1733
1734VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer)
1735{
1736 TRACE("(VkDevice device = %p, const VkFramebufferCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkFramebuffer* pFramebuffer = %p)",
1737 device, pCreateInfo, pAllocator, pFramebuffer);
1738
1739 if(pCreateInfo->pNext || pCreateInfo->flags)
1740 {
1741 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
1742 }
1743
1744 return vk::Framebuffer::Create(pAllocator, pCreateInfo, pFramebuffer);
1745}
1746
1747VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
1748{
1749 TRACE("(VkDevice device = %p, VkFramebuffer framebuffer = %p, const VkAllocationCallbacks* pAllocator = %p)",
1750 device, static_cast<void*>(framebuffer), pAllocator);
1751
1752 vk::destroy(framebuffer, pAllocator);
1753}
1754
1755VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
1756{
1757 TRACE("(VkDevice device = %p, const VkRenderPassCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkRenderPass* pRenderPass = %p)",
1758 device, pCreateInfo, pAllocator, pRenderPass);
1759
1760 if(pCreateInfo->flags)
1761 {
1762 UNIMPLEMENTED("pCreateInfo->flags");
1763 }
1764
1765 const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
1766
1767 while(extensionCreateInfo)
1768 {
1769 switch(extensionCreateInfo->sType)
1770 {
1771 case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
1772 {
1773 const VkRenderPassInputAttachmentAspectCreateInfo* inputAttachmentAspectCreateInfo = reinterpret_cast<const VkRenderPassInputAttachmentAspectCreateInfo*>(extensionCreateInfo);
1774
1775 for(uint32_t i = 0; i < inputAttachmentAspectCreateInfo->aspectReferenceCount; i++)
1776 {
1777 const VkInputAttachmentAspectReference& aspectReference = inputAttachmentAspectCreateInfo->pAspectReferences[i];
1778 ASSERT(aspectReference.subpass < pCreateInfo->subpassCount);
1779 const VkSubpassDescription& subpassDescription = pCreateInfo->pSubpasses[aspectReference.subpass];
1780 ASSERT(aspectReference.inputAttachmentIndex < subpassDescription.inputAttachmentCount);
1781 const VkAttachmentReference& attachmentReference = subpassDescription.pInputAttachments[aspectReference.inputAttachmentIndex];
1782 if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
1783 {
1784 // If the pNext chain includes an instance of VkRenderPassInputAttachmentAspectCreateInfo, for any
1785 // element of the pInputAttachments member of any element of pSubpasses where the attachment member
1786 // is not VK_ATTACHMENT_UNUSED, the aspectMask member of the corresponding element of
1787 // VkRenderPassInputAttachmentAspectCreateInfo::pAspectReferences must only include aspects that are
1788 // present in images of the format specified by the element of pAttachments at attachment
1789 vk::Format format(pCreateInfo->pAttachments[attachmentReference.attachment].format);
1790 bool isDepth = format.isDepth();
1791 bool isStencil = format.isStencil();
1792 ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) || (!isDepth && !isStencil));
1793 ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) || isDepth);
1794 ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) || isStencil);
1795 }
1796 }
1797 }
1798 break;
1799 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
1800 {
1801 const VkRenderPassMultiviewCreateInfo* multiviewCreateInfo = reinterpret_cast<const VkRenderPassMultiviewCreateInfo*>(extensionCreateInfo);
1802 ASSERT((multiviewCreateInfo->subpassCount == 0) || (multiviewCreateInfo->subpassCount == pCreateInfo->subpassCount));
1803 ASSERT((multiviewCreateInfo->dependencyCount == 0) || (multiviewCreateInfo->dependencyCount == pCreateInfo->dependencyCount));
1804
1805 bool zeroMask = (multiviewCreateInfo->pViewMasks[0] == 0);
1806 for(uint32_t i = 1; i < multiviewCreateInfo->subpassCount; i++)
1807 {
1808 ASSERT((multiviewCreateInfo->pViewMasks[i] == 0) == zeroMask);
1809 }
1810
1811 if(zeroMask)
1812 {
1813 ASSERT(multiviewCreateInfo->correlationMaskCount == 0);
1814 }
1815
1816 for(uint32_t i = 0; i < multiviewCreateInfo->dependencyCount; i++)
1817 {
1818 const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i];
1819 if(multiviewCreateInfo->pViewOffsets[i] != 0)
1820 {
1821 ASSERT(dependency.srcSubpass != dependency.dstSubpass);
1822 ASSERT(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT);
1823 }
1824 if(zeroMask)
1825 {
1826 ASSERT(!(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT));
1827 }
1828 }
1829
1830 // If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo,
1831 // each element of its pViewMask member must not include a bit at a position
1832 // greater than the value of VkPhysicalDeviceLimits::maxFramebufferLayers
1833 // pViewMask is a 32 bit value. If maxFramebufferLayers > 32, it's impossible
1834 // for pViewMask to contain a bit at an illegal position
1835 // Note: Verify pViewMask values instead if we hit this assert
1836 ASSERT(vk::Cast(device)->getPhysicalDevice()->getProperties().limits.maxFramebufferLayers >= 32);
1837 }
1838 break;
1839 default:
1840 UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
1841 break;
1842 }
1843
1844 extensionCreateInfo = extensionCreateInfo->pNext;
1845 }
1846
1847 return vk::RenderPass::Create(pAllocator, pCreateInfo, pRenderPass);
1848}
1849
1850VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
1851{
1852 TRACE("(VkDevice device = %p, VkRenderPass renderPass = %p, const VkAllocationCallbacks* pAllocator = %p)",
1853 device, static_cast<void*>(renderPass), pAllocator);
1854
1855 vk::destroy(renderPass, pAllocator);
1856}
1857
1858VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity)
1859{
1860 TRACE("(VkDevice device = %p, VkRenderPass renderPass = %p, VkExtent2D* pGranularity = %p)",
1861 device, static_cast<void*>(renderPass), pGranularity);
1862
1863 vk::Cast(renderPass)->getRenderAreaGranularity(pGranularity);
1864}
1865
1866VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool)
1867{
1868 TRACE("(VkDevice device = %p, const VkCommandPoolCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkCommandPool* pCommandPool = %p)",
1869 device, pCreateInfo, pAllocator, pCommandPool);
1870
1871 if(pCreateInfo->pNext)
1872 {
1873 UNIMPLEMENTED("pCreateInfo->pNext");
1874 }
1875
1876 return vk::CommandPool::Create(pAllocator, pCreateInfo, pCommandPool);
1877}
1878
1879VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
1880{
1881 TRACE("(VkDevice device = %p, VkCommandPool commandPool = %p, const VkAllocationCallbacks* pAllocator = %p)",
1882 device, static_cast<void*>(commandPool), pAllocator);
1883
1884 vk::destroy(commandPool, pAllocator);
1885}
1886
1887VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
1888{
1889 TRACE("(VkDevice device = %p, VkCommandPool commandPool = %p, VkCommandPoolResetFlags flags = %d)",
1890 device, static_cast<void*>(commandPool), int(flags));
1891
1892 return vk::Cast(commandPool)->reset(flags);
1893}
1894
1895VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
1896{
1897 TRACE("(VkDevice device = %p, const VkCommandBufferAllocateInfo* pAllocateInfo = %p, VkCommandBuffer* pCommandBuffers = %p)",
1898 device, pAllocateInfo, pCommandBuffers);
1899
1900 if(pAllocateInfo->pNext)
1901 {
1902 UNIMPLEMENTED("pAllocateInfo->pNext");
1903 }
1904
1905 return vk::Cast(pAllocateInfo->commandPool)->allocateCommandBuffers(
1906 pAllocateInfo->level, pAllocateInfo->commandBufferCount, pCommandBuffers);
1907}
1908
1909VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
1910{
1911 TRACE("(VkDevice device = %p, VkCommandPool commandPool = %p, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = %p)",
1912 device, static_cast<void*>(commandPool), int(commandBufferCount), pCommandBuffers);
1913
1914 vk::Cast(commandPool)->freeCommandBuffers(commandBufferCount, pCommandBuffers);
1915}
1916
1917VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo)
1918{
1919 TRACE("(VkCommandBuffer commandBuffer = %p, const VkCommandBufferBeginInfo* pBeginInfo = %p)",
1920 commandBuffer, pBeginInfo);
1921
1922 if(pBeginInfo->pNext)
1923 {
1924 UNIMPLEMENTED("pBeginInfo->pNext");
1925 }
1926
1927 return vk::Cast(commandBuffer)->begin(pBeginInfo->flags, pBeginInfo->pInheritanceInfo);
1928}
1929
1930VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer)
1931{
1932 TRACE("(VkCommandBuffer commandBuffer = %p)", commandBuffer);
1933
1934 return vk::Cast(commandBuffer)->end();
1935}
1936
1937VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags)
1938{
1939 TRACE("VkCommandBuffer commandBuffer = %p, VkCommandBufferResetFlags flags = %d", commandBuffer, int(flags));
1940
1941 return vk::Cast(commandBuffer)->reset(flags);
1942}
1943
1944VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
1945{
1946 TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineBindPoint pipelineBindPoint = %d, VkPipeline pipeline = %p)",
1947 commandBuffer, int(pipelineBindPoint), static_cast<void*>(pipeline));
1948
1949 vk::Cast(commandBuffer)->bindPipeline(pipelineBindPoint, vk::Cast(pipeline));
1950}
1951
1952VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
1953{
1954 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t firstViewport = %d, uint32_t viewportCount = %d, const VkViewport* pViewports = %p)",
1955 commandBuffer, int(firstViewport), int(viewportCount), pViewports);
1956
1957 vk::Cast(commandBuffer)->setViewport(firstViewport, viewportCount, pViewports);
1958}
1959
1960VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
1961{
1962 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t firstScissor = %d, uint32_t scissorCount = %d, const VkRect2D* pScissors = %p)",
1963 commandBuffer, int(firstScissor), int(scissorCount), pScissors);
1964
1965 vk::Cast(commandBuffer)->setScissor(firstScissor, scissorCount, pScissors);
1966}
1967
1968VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
1969{
1970 TRACE("(VkCommandBuffer commandBuffer = %p, float lineWidth = %f)", commandBuffer, lineWidth);
1971
1972 vk::Cast(commandBuffer)->setLineWidth(lineWidth);
1973}
1974
1975VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
1976{
1977 TRACE("(VkCommandBuffer commandBuffer = %p, float depthBiasConstantFactor = %f, float depthBiasClamp = %f, float depthBiasSlopeFactor = %f)",
1978 commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
1979
1980 vk::Cast(commandBuffer)->setDepthBias(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
1981}
1982
1983VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4])
1984{
1985 TRACE("(VkCommandBuffer commandBuffer = %p, const float blendConstants[4] = {%f, %f, %f, %f})",
1986 commandBuffer, blendConstants[0], blendConstants[1], blendConstants[2], blendConstants[3]);
1987
1988 vk::Cast(commandBuffer)->setBlendConstants(blendConstants);
1989}
1990
1991VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds)
1992{
1993 TRACE("(VkCommandBuffer commandBuffer = %p, float minDepthBounds = %f, float maxDepthBounds = %f)",
1994 commandBuffer, minDepthBounds, maxDepthBounds);
1995
1996 vk::Cast(commandBuffer)->setDepthBounds(minDepthBounds, maxDepthBounds);
1997}
1998
1999VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask)
2000{
2001 TRACE("(VkCommandBuffer commandBuffer = %p, VkStencilFaceFlags faceMask = %d, uint32_t compareMask = %d)",
2002 commandBuffer, int(faceMask), int(compareMask));
2003
2004 vk::Cast(commandBuffer)->setStencilCompareMask(faceMask, compareMask);
2005}
2006
2007VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask)
2008{
2009 TRACE("(VkCommandBuffer commandBuffer = %p, VkStencilFaceFlags faceMask = %d, uint32_t writeMask = %d)",
2010 commandBuffer, int(faceMask), int(writeMask));
2011
2012 vk::Cast(commandBuffer)->setStencilWriteMask(faceMask, writeMask);
2013}
2014
2015VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference)
2016{
2017 TRACE("(VkCommandBuffer commandBuffer = %p, VkStencilFaceFlags faceMask = %d, uint32_t reference = %d)",
2018 commandBuffer, int(faceMask), int(reference));
2019
2020 vk::Cast(commandBuffer)->setStencilReference(faceMask, reference);
2021}
2022
2023VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
2024{
2025 TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineBindPoint pipelineBindPoint = %d, VkPipelineLayout layout = %p, uint32_t firstSet = %d, uint32_t descriptorSetCount = %d, const VkDescriptorSet* pDescriptorSets = %p, uint32_t dynamicOffsetCount = %d, const uint32_t* pDynamicOffsets = %p)",
2026 commandBuffer, int(pipelineBindPoint), static_cast<void*>(layout), int(firstSet), int(descriptorSetCount), pDescriptorSets, int(dynamicOffsetCount), pDynamicOffsets);
2027
2028 vk::Cast(commandBuffer)->bindDescriptorSets(pipelineBindPoint, vk::Cast(layout), firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
2029}
2030
2031VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
2032{
2033 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, VkIndexType indexType = %d)",
2034 commandBuffer, static_cast<void*>(buffer), int(offset), int(indexType));
2035
2036 vk::Cast(commandBuffer)->bindIndexBuffer(vk::Cast(buffer), offset, indexType);
2037}
2038
2039VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
2040{
2041 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t firstBinding = %d, uint32_t bindingCount = %d, const VkBuffer* pBuffers = %p, const VkDeviceSize* pOffsets = %p)",
2042 commandBuffer, int(firstBinding), int(bindingCount), pBuffers, pOffsets);
2043
2044 vk::Cast(commandBuffer)->bindVertexBuffers(firstBinding, bindingCount, pBuffers, pOffsets);
2045}
2046
2047VKAPI_ATTR void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
2048{
2049 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t vertexCount = %d, uint32_t instanceCount = %d, uint32_t firstVertex = %d, uint32_t firstInstance = %d)",
2050 commandBuffer, int(vertexCount), int(instanceCount), int(firstVertex), int(firstInstance));
2051
2052 vk::Cast(commandBuffer)->draw(vertexCount, instanceCount, firstVertex, firstInstance);
2053}
2054
2055VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
2056{
2057 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t indexCount = %d, uint32_t instanceCount = %d, uint32_t firstIndex = %d, int32_t vertexOffset = %d, uint32_t firstInstance = %d)",
2058 commandBuffer, int(indexCount), int(instanceCount), int(firstIndex), int(vertexOffset), int(firstInstance));
2059
2060 vk::Cast(commandBuffer)->drawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
2061}
2062
2063VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
2064{
2065 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
2066 commandBuffer, static_cast<void*>(buffer), int(offset), int(drawCount), int(stride));
2067
2068 vk::Cast(commandBuffer)->drawIndirect(vk::Cast(buffer), offset, drawCount, stride);
2069}
2070
2071VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
2072{
2073 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
2074 commandBuffer, static_cast<void*>(buffer), int(offset), int(drawCount), int(stride));
2075
2076 vk::Cast(commandBuffer)->drawIndexedIndirect(vk::Cast(buffer), offset, drawCount, stride);
2077}
2078
2079VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
2080{
2081 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t groupCountX = %d, uint32_t groupCountY = %d, uint32_t groupCountZ = %d)",
2082 commandBuffer, int(groupCountX), int(groupCountY), int(groupCountZ));
2083
2084 vk::Cast(commandBuffer)->dispatch(groupCountX, groupCountY, groupCountZ);
2085}
2086
2087VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset)
2088{
2089 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer buffer = %p, VkDeviceSize offset = %d)",
2090 commandBuffer, static_cast<void*>(buffer), int(offset));
2091
2092 vk::Cast(commandBuffer)->dispatchIndirect(vk::Cast(buffer), offset);
2093}
2094
2095VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
2096{
2097 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer srcBuffer = %p, VkBuffer dstBuffer = %p, uint32_t regionCount = %d, const VkBufferCopy* pRegions = %p)",
2098 commandBuffer, static_cast<void*>(srcBuffer), static_cast<void*>(dstBuffer), int(regionCount), pRegions);
2099
2100 vk::Cast(commandBuffer)->copyBuffer(vk::Cast(srcBuffer), vk::Cast(dstBuffer), regionCount, pRegions);
2101}
2102
2103VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
2104{
2105 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageCopy* pRegions = %p)",
2106 commandBuffer, static_cast<void*>(srcImage), srcImageLayout, static_cast<void*>(dstImage), dstImageLayout, int(regionCount), pRegions);
2107
2108 vk::Cast(commandBuffer)->copyImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
2109}
2110
2111VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
2112{
2113 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageBlit* pRegions = %p, VkFilter filter = %d)",
2114 commandBuffer, static_cast<void*>(srcImage), srcImageLayout, static_cast<void*>(dstImage), dstImageLayout, int(regionCount), pRegions, filter);
2115
2116 vk::Cast(commandBuffer)->blitImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions, filter);
2117}
2118
2119VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
2120{
2121 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer srcBuffer = %p, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = %p)",
2122 commandBuffer, static_cast<void*>(srcBuffer), static_cast<void*>(dstImage), dstImageLayout, int(regionCount), pRegions);
2123
2124 vk::Cast(commandBuffer)->copyBufferToImage(vk::Cast(srcBuffer), vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
2125}
2126
2127VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
2128{
2129 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkBuffer dstBuffer = %p, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = %p)",
2130 commandBuffer, static_cast<void*>(srcImage), int(srcImageLayout), static_cast<void*>(dstBuffer), int(regionCount), pRegions);
2131
2132 vk::Cast(commandBuffer)->copyImageToBuffer(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstBuffer), regionCount, pRegions);
2133}
2134
2135VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
2136{
2137 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize dataSize = %d, const void* pData = %p)",
2138 commandBuffer, static_cast<void*>(dstBuffer), int(dstOffset), int(dataSize), pData);
2139
2140 vk::Cast(commandBuffer)->updateBuffer(vk::Cast(dstBuffer), dstOffset, dataSize, pData);
2141}
2142
2143VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
2144{
2145 TRACE("(VkCommandBuffer commandBuffer = %p, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize size = %d, uint32_t data = %d)",
2146 commandBuffer, static_cast<void*>(dstBuffer), int(dstOffset), int(size), data);
2147
2148 vk::Cast(commandBuffer)->fillBuffer(vk::Cast(dstBuffer), dstOffset, size, data);
2149}
2150
2151VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
2152{
2153 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage image = %p, VkImageLayout imageLayout = %d, const VkClearColorValue* pColor = %p, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = %p)",
2154 commandBuffer, static_cast<void*>(image), int(imageLayout), pColor, int(rangeCount), pRanges);
2155
2156 vk::Cast(commandBuffer)->clearColorImage(vk::Cast(image), imageLayout, pColor, rangeCount, pRanges);
2157}
2158
2159VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
2160{
2161 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage image = %p, VkImageLayout imageLayout = %d, const VkClearDepthStencilValue* pDepthStencil = %p, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = %p)",
2162 commandBuffer, static_cast<void*>(image), int(imageLayout), pDepthStencil, int(rangeCount), pRanges);
2163
2164 vk::Cast(commandBuffer)->clearDepthStencilImage(vk::Cast(image), imageLayout, pDepthStencil, rangeCount, pRanges);
2165}
2166
2167VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects)
2168{
2169 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t attachmentCount = %d, const VkClearAttachment* pAttachments = %p, uint32_t rectCount = %d, const VkClearRect* pRects = %p)",
2170 commandBuffer, int(attachmentCount), pAttachments, int(rectCount), pRects);
2171
2172 vk::Cast(commandBuffer)->clearAttachments(attachmentCount, pAttachments, rectCount, pRects);
2173}
2174
2175VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
2176{
2177 TRACE("(VkCommandBuffer commandBuffer = %p, VkImage srcImage = %p, VkImageLayout srcImageLayout = %d, VkImage dstImage = %p, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageResolve* pRegions = %p)",
2178 commandBuffer, static_cast<void*>(srcImage), int(srcImageLayout), static_cast<void*>(dstImage), int(dstImageLayout), regionCount, pRegions);
2179
2180 vk::Cast(commandBuffer)->resolveImage(vk::Cast(srcImage), srcImageLayout, vk::Cast(dstImage), dstImageLayout, regionCount, pRegions);
2181}
2182
2183VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
2184{
2185 TRACE("(VkCommandBuffer commandBuffer = %p, VkEvent event = %p, VkPipelineStageFlags stageMask = %d)",
2186 commandBuffer, static_cast<void*>(event), int(stageMask));
2187
2188 vk::Cast(commandBuffer)->setEvent(vk::Cast(event), stageMask);
2189}
2190
2191VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
2192{
2193 TRACE("(VkCommandBuffer commandBuffer = %p, VkEvent event = %p, VkPipelineStageFlags stageMask = %d)",
2194 commandBuffer, static_cast<void*>(event), int(stageMask));
2195
2196 vk::Cast(commandBuffer)->resetEvent(vk::Cast(event), stageMask);
2197}
2198
2199VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
2200{
2201 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t eventCount = %d, const VkEvent* pEvents = %p, VkPipelineStageFlags srcStageMask = 0x%x, VkPipelineStageFlags dstStageMask = 0x%x, uint32_t memoryBarrierCount = %d, const VkMemoryBarrier* pMemoryBarriers = %p, uint32_t bufferMemoryBarrierCount = %d, const VkBufferMemoryBarrier* pBufferMemoryBarriers = %p, uint32_t imageMemoryBarrierCount = %d, const VkImageMemoryBarrier* pImageMemoryBarriers = %p)",
2202 commandBuffer, int(eventCount), pEvents, int(srcStageMask), int(dstStageMask), int(memoryBarrierCount), pMemoryBarriers, int(bufferMemoryBarrierCount), pBufferMemoryBarriers, int(imageMemoryBarrierCount), pImageMemoryBarriers);
2203
2204 vk::Cast(commandBuffer)->waitEvents(eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
2205}
2206
2207VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
2208{
2209 TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineStageFlags srcStageMask = 0x%x, VkPipelineStageFlags dstStageMask = 0x%x, VkDependencyFlags dependencyFlags = %d, uint32_t memoryBarrierCount = %d, onst VkMemoryBarrier* pMemoryBarriers = %p,"
2210 " uint32_t bufferMemoryBarrierCount = %d, const VkBufferMemoryBarrier* pBufferMemoryBarriers = %p, uint32_t imageMemoryBarrierCount = %d, const VkImageMemoryBarrier* pImageMemoryBarriers = %p)",
2211 commandBuffer, int(srcStageMask), int(dstStageMask), dependencyFlags, int(memoryBarrierCount), pMemoryBarriers, int(bufferMemoryBarrierCount), pBufferMemoryBarriers, int(imageMemoryBarrierCount), pImageMemoryBarriers);
2212
2213 vk::Cast(commandBuffer)->pipelineBarrier(srcStageMask, dstStageMask, dependencyFlags,
2214 memoryBarrierCount, pMemoryBarriers,
2215 bufferMemoryBarrierCount, pBufferMemoryBarriers,
2216 imageMemoryBarrierCount, pImageMemoryBarriers);
2217}
2218
2219VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
2220{
2221 TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t query = %d, VkQueryControlFlags flags = %d)",
2222 commandBuffer, static_cast<void*>(queryPool), query, int(flags));
2223
2224 vk::Cast(commandBuffer)->beginQuery(vk::Cast(queryPool), query, flags);
2225}
2226
2227VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
2228{
2229 TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t query = %d)",
2230 commandBuffer, static_cast<void*>(queryPool), int(query));
2231
2232 vk::Cast(commandBuffer)->endQuery(vk::Cast(queryPool), query);
2233}
2234
2235VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
2236{
2237 TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t firstQuery = %d, uint32_t queryCount = %d)",
2238 commandBuffer, static_cast<void*>(queryPool), int(firstQuery), int(queryCount));
2239
2240 vk::Cast(commandBuffer)->resetQueryPool(vk::Cast(queryPool), firstQuery, queryCount);
2241}
2242
2243VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
2244{
2245 TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineStageFlagBits pipelineStage = %d, VkQueryPool queryPool = %p, uint32_t query = %d)",
2246 commandBuffer, int(pipelineStage), static_cast<void*>(queryPool), int(query));
2247
2248 vk::Cast(commandBuffer)->writeTimestamp(pipelineStage, vk::Cast(queryPool), query);
2249}
2250
2251VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
2252{
2253 TRACE("(VkCommandBuffer commandBuffer = %p, VkQueryPool queryPool = %p, uint32_t firstQuery = %d, uint32_t queryCount = %d, VkBuffer dstBuffer = %p, VkDeviceSize dstOffset = %d, VkDeviceSize stride = %d, VkQueryResultFlags flags = %d)",
2254 commandBuffer, static_cast<void*>(queryPool), int(firstQuery), int(queryCount), static_cast<void*>(dstBuffer), int(dstOffset), int(stride), int(flags));
2255
2256 vk::Cast(commandBuffer)->copyQueryPoolResults(vk::Cast(queryPool), firstQuery, queryCount, vk::Cast(dstBuffer), dstOffset, stride, flags);
2257}
2258
2259VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues)
2260{
2261 TRACE("(VkCommandBuffer commandBuffer = %p, VkPipelineLayout layout = %p, VkShaderStageFlags stageFlags = %d, uint32_t offset = %d, uint32_t size = %d, const void* pValues = %p)",
2262 commandBuffer, static_cast<void*>(layout), stageFlags, offset, size, pValues);
2263
2264 vk::Cast(commandBuffer)->pushConstants(vk::Cast(layout), stageFlags, offset, size, pValues);
2265}
2266
2267VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
2268{
2269 TRACE("(VkCommandBuffer commandBuffer = %p, const VkRenderPassBeginInfo* pRenderPassBegin = %p, VkSubpassContents contents = %d)",
2270 commandBuffer, pRenderPassBegin, contents);
2271
2272 const VkBaseInStructure* renderPassBeginInfo = reinterpret_cast<const VkBaseInStructure*>(pRenderPassBegin->pNext);
2273 while(renderPassBeginInfo)
2274 {
2275 switch(renderPassBeginInfo->sType)
2276 {
2277 case VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO:
2278 // This extension controls which render area is used on which physical device,
2279 // in order to distribute rendering between multiple physical devices.
2280 // SwiftShader only has a single physical device, so this extension does nothing in this case.
2281 break;
2282 default:
2283 UNIMPLEMENTED("renderPassBeginInfo->sType");
2284 break;
2285 }
2286
2287 renderPassBeginInfo = renderPassBeginInfo->pNext;
2288 }
2289
2290 vk::Cast(commandBuffer)->beginRenderPass(vk::Cast(pRenderPassBegin->renderPass), vk::Cast(pRenderPassBegin->framebuffer),
2291 pRenderPassBegin->renderArea, pRenderPassBegin->clearValueCount,
2292 pRenderPassBegin->pClearValues, contents);
2293}
2294
2295VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
2296{
2297 TRACE("(VkCommandBuffer commandBuffer = %p, VkSubpassContents contents = %d)",
2298 commandBuffer, contents);
2299
2300 vk::Cast(commandBuffer)->nextSubpass(contents);
2301}
2302
2303VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
2304{
2305 TRACE("(VkCommandBuffer commandBuffer = %p)", commandBuffer);
2306
2307 vk::Cast(commandBuffer)->endRenderPass();
2308}
2309
2310VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
2311{
2312 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = %p)",
2313 commandBuffer, commandBufferCount, pCommandBuffers);
2314
2315 vk::Cast(commandBuffer)->executeCommands(commandBufferCount, pCommandBuffers);
2316}
2317
2318VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t* pApiVersion)
2319{
2320 TRACE("(uint32_t* pApiVersion = %p)", pApiVersion);
2321 *pApiVersion = vk::API_VERSION;
2322 return VK_SUCCESS;
2323}
2324
2325VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos)
2326{
2327 TRACE("(VkDevice device = %p, uint32_t bindInfoCount = %d, const VkBindBufferMemoryInfo* pBindInfos = %p)",
2328 device, bindInfoCount, pBindInfos);
2329
2330 for(uint32_t i = 0; i < bindInfoCount; i++)
2331 {
2332 if(pBindInfos[i].pNext)
2333 {
2334 UNIMPLEMENTED("pBindInfos[%d].pNext", i);
2335 }
2336
2337 if (!vk::Cast(pBindInfos[i].buffer)->canBindToMemory(vk::Cast(pBindInfos[i].memory)))
2338 {
2339 UNSUPPORTED("vkBindBufferMemory2 with invalid external memory");
2340 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
2341 }
2342 }
2343
2344 for (uint32_t i = 0; i < bindInfoCount; i++)
2345 {
2346 vk::Cast(pBindInfos[i].buffer)->bind(vk::Cast(pBindInfos[i].memory), pBindInfos[i].memoryOffset);
2347 }
2348
2349 return VK_SUCCESS;
2350}
2351
2352VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos)
2353{
2354 TRACE("(VkDevice device = %p, uint32_t bindInfoCount = %d, const VkBindImageMemoryInfo* pBindInfos = %p)",
2355 device, bindInfoCount, pBindInfos);
2356
2357 for(uint32_t i = 0; i < bindInfoCount; i++)
2358 {
2359 if (!vk::Cast(pBindInfos[i].image)->canBindToMemory(vk::Cast(pBindInfos[i].memory)))
2360 {
2361 UNSUPPORTED("vkBindImageMemory2 with invalid external memory");
2362 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2363 }
2364 }
2365
2366 for(uint32_t i = 0; i < bindInfoCount; i++)
2367 {
2368 vk::DeviceMemory *memory = vk::Cast(pBindInfos[i].memory);
2369 VkDeviceSize offset = pBindInfos[i].memoryOffset;
2370
2371 auto extInfo = reinterpret_cast<VkBaseInStructure const *>(pBindInfos[i].pNext);
2372 while (extInfo)
2373 {
2374 switch (extInfo->sType)
2375 {
2376 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO:
2377 /* Do nothing */
2378 break;
2379
2380#ifndef __ANDROID__
2381 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
2382 {
2383 auto swapchainInfo = reinterpret_cast<VkBindImageMemorySwapchainInfoKHR const *>(extInfo);
2384 memory = vk::Cast(swapchainInfo->swapchain)->getImage(swapchainInfo->imageIndex).getImageMemory();
2385 offset = 0;
2386 }
2387 break;
2388#endif
2389
2390 default:
2391 break;
2392 }
2393 extInfo = extInfo->pNext;
2394 }
2395
2396 vk::Cast(pBindInfos[i].image)->bind(memory, offset);
2397 }
2398
2399 return VK_SUCCESS;
2400}
2401
2402VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
2403{
2404 TRACE("(VkDevice device = %p, uint32_t heapIndex = %d, uint32_t localDeviceIndex = %d, uint32_t remoteDeviceIndex = %d, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures = %p)",
2405 device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
2406
2407 ASSERT(localDeviceIndex != remoteDeviceIndex); // "localDeviceIndex must not equal remoteDeviceIndex"
2408 UNREACHABLE("remoteDeviceIndex: %d", int(remoteDeviceIndex)); // Only one physical device is supported, and since the device indexes can't be equal, this should never be called.
2409}
2410
2411VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
2412{
2413 TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t deviceMask = %d", commandBuffer, deviceMask);
2414
2415 vk::Cast(commandBuffer)->setDeviceMask(deviceMask);
2416}
2417
2418VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
2419{
2420 TRACE("(VkCommandBuffer commandBuffer = %p, baseGroupX = %u, baseGroupY = %u, baseGroupZ = %u, groupCountX = %u, groupCountY = %u, groupCountZ = %u)",
2421 commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
2422
2423 vk::Cast(commandBuffer)->dispatchBase(baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
2424}
2425
2426VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
2427{
2428 TRACE("VkInstance instance = %p, uint32_t* pPhysicalDeviceGroupCount = %p, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties = %p",
2429 instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
2430
2431 return vk::Cast(instance)->getPhysicalDeviceGroups(pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
2432}
2433
2434VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements)
2435{
2436 TRACE("(VkDevice device = %p, const VkImageMemoryRequirementsInfo2* pInfo = %p, VkMemoryRequirements2* pMemoryRequirements = %p)",
2437 device, pInfo, pMemoryRequirements);
2438
2439 if(pInfo->pNext)
2440 {
2441 UNIMPLEMENTED("pInfo->pNext");
2442 }
2443
2444 VkBaseOutStructure* extensionRequirements = reinterpret_cast<VkBaseOutStructure*>(pMemoryRequirements->pNext);
2445 while(extensionRequirements)
2446 {
2447 switch(extensionRequirements->sType)
2448 {
2449 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:
2450 {
2451 auto& requirements = *reinterpret_cast<VkMemoryDedicatedRequirements*>(extensionRequirements);
2452 requirements.prefersDedicatedAllocation = VK_FALSE;
2453 requirements.requiresDedicatedAllocation = VK_FALSE;
2454 }
2455 break;
2456 default:
2457 UNIMPLEMENTED("extensionRequirements->sType");
2458 break;
2459 }
2460
2461 extensionRequirements = extensionRequirements->pNext;
2462 }
2463
2464 vkGetImageMemoryRequirements(device, pInfo->image, &(pMemoryRequirements->memoryRequirements));
2465}
2466
2467VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements)
2468{
2469 TRACE("(VkDevice device = %p, const VkBufferMemoryRequirementsInfo2* pInfo = %p, VkMemoryRequirements2* pMemoryRequirements = %p)",
2470 device, pInfo, pMemoryRequirements);
2471
2472 if(pInfo->pNext)
2473 {
2474 UNIMPLEMENTED("pInfo->pNext");
2475 }
2476
2477 VkBaseOutStructure* extensionRequirements = reinterpret_cast<VkBaseOutStructure*>(pMemoryRequirements->pNext);
2478 while(extensionRequirements)
2479 {
2480 switch(extensionRequirements->sType)
2481 {
2482 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:
2483 {
2484 auto& requirements = *reinterpret_cast<VkMemoryDedicatedRequirements*>(extensionRequirements);
2485 requirements.prefersDedicatedAllocation = VK_FALSE;
2486 requirements.requiresDedicatedAllocation = VK_FALSE;
2487 }
2488 break;
2489 default:
2490 UNIMPLEMENTED("extensionRequirements->sType");
2491 break;
2492 }
2493
2494 extensionRequirements = extensionRequirements->pNext;
2495 }
2496
2497 vkGetBufferMemoryRequirements(device, pInfo->buffer, &(pMemoryRequirements->memoryRequirements));
2498}
2499
2500VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
2501{
2502 TRACE("(VkDevice device = %p, const VkImageSparseMemoryRequirementsInfo2* pInfo = %p, uint32_t* pSparseMemoryRequirementCount = %p, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements = %p)",
2503 device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
2504
2505 if(pInfo->pNext || pSparseMemoryRequirements->pNext)
2506 {
2507 UNIMPLEMENTED("pInfo->pNext || pSparseMemoryRequirements->pNext");
2508 }
2509
2510 // The 'sparseBinding' feature is not supported, so images can not be created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag.
2511 // "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to."
2512 *pSparseMemoryRequirementCount = 0;
2513}
2514
2515VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures)
2516{
2517 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceFeatures2* pFeatures = %p)", physicalDevice, pFeatures);
2518
2519 VkBaseOutStructure* extensionFeatures = reinterpret_cast<VkBaseOutStructure*>(pFeatures->pNext);
2520 while(extensionFeatures)
2521 {
2522 switch((long)(extensionFeatures->sType))
2523 {
2524 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
2525 {
2526 auto& features = *reinterpret_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(extensionFeatures);
2527 vk::Cast(physicalDevice)->getFeatures(&features);
2528 }
2529 break;
2530 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
2531 {
2532 auto& features = *reinterpret_cast<VkPhysicalDevice16BitStorageFeatures*>(extensionFeatures);
2533 vk::Cast(physicalDevice)->getFeatures(&features);
2534 }
2535 break;
2536 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES:
2537 {
2538 auto& features = *reinterpret_cast<VkPhysicalDeviceVariablePointerFeatures*>(extensionFeatures);
2539 vk::Cast(physicalDevice)->getFeatures(&features);
2540 }
2541 break;
2542 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR:
2543 {
2544 auto& features = *reinterpret_cast<VkPhysicalDevice8BitStorageFeaturesKHR*>(extensionFeatures);
2545 vk::Cast(physicalDevice)->getFeatures(&features);
2546 }
2547 break;
2548 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
2549 {
2550 auto& features = *reinterpret_cast<VkPhysicalDeviceMultiviewFeatures*>(extensionFeatures);
2551 vk::Cast(physicalDevice)->getFeatures(&features);
2552 }
2553 break;
2554 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
2555 {
2556 auto& features = *reinterpret_cast<VkPhysicalDeviceProtectedMemoryFeatures*>(extensionFeatures);
2557 vk::Cast(physicalDevice)->getFeatures(&features);
2558 }
2559 break;
2560 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES:
2561 {
2562 auto& features = *reinterpret_cast<VkPhysicalDeviceShaderDrawParameterFeatures*>(extensionFeatures);
2563 vk::Cast(physicalDevice)->getFeatures(&features);
2564 }
2565 break;
2566 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
2567 {
2568 auto& features = *reinterpret_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT*>(extensionFeatures);
2569 vk::Cast(physicalDevice)->getFeatures(&features);
2570 }
2571 break;
2572 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
2573 {
2574 auto& features = *reinterpret_cast<VkPhysicalDeviceProvokingVertexFeaturesEXT*>(extensionFeatures);
2575 vk::Cast(physicalDevice)->getFeatures(&features);
2576 }
2577 break;
2578 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT:
2579 ASSERT(!HasExtensionProperty(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, deviceExtensionProperties,
2580 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2581 break;
2582 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT:
2583 ASSERT(!HasExtensionProperty(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, deviceExtensionProperties,
2584 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2585 break;
2586 default:
2587 // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
2588 UNIMPLEMENTED("extensionFeatures->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
2589 break;
2590 }
2591
2592 extensionFeatures = extensionFeatures->pNext;
2593 }
2594
2595 vkGetPhysicalDeviceFeatures(physicalDevice, &(pFeatures->features));
2596}
2597
2598VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties)
2599{
2600 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceProperties2* pProperties = %p)", physicalDevice, pProperties);
2601
2602 VkBaseOutStructure* extensionProperties = reinterpret_cast<VkBaseOutStructure*>(pProperties->pNext);
2603 while(extensionProperties)
2604 {
2605 // Casting to a long since some structures, such as
2606 // VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID and
2607 // VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT
2608 // are not enumerated in the official Vulkan header
2609 switch((long)(extensionProperties->sType))
2610 {
2611 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES:
2612 {
2613 auto& properties = *reinterpret_cast<VkPhysicalDeviceIDProperties*>(extensionProperties);
2614 vk::Cast(physicalDevice)->getProperties(&properties);
2615 }
2616 break;
2617 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:
2618 {
2619 auto& properties = *reinterpret_cast<VkPhysicalDeviceMaintenance3Properties*>(extensionProperties);
2620 vk::Cast(physicalDevice)->getProperties(&properties);
2621 }
2622 break;
2623 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES:
2624 {
2625 auto& properties = *reinterpret_cast<VkPhysicalDeviceMultiviewProperties*>(extensionProperties);
2626 vk::Cast(physicalDevice)->getProperties(&properties);
2627 }
2628 break;
2629 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES:
2630 {
2631 auto& properties = *reinterpret_cast<VkPhysicalDevicePointClippingProperties*>(extensionProperties);
2632 vk::Cast(physicalDevice)->getProperties(&properties);
2633 }
2634 break;
2635 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES:
2636 {
2637 auto& properties = *reinterpret_cast<VkPhysicalDeviceProtectedMemoryProperties*>(extensionProperties);
2638 vk::Cast(physicalDevice)->getProperties(&properties);
2639 }
2640 break;
2641 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES:
2642 {
2643 auto& properties = *reinterpret_cast<VkPhysicalDeviceSubgroupProperties*>(extensionProperties);
2644 vk::Cast(physicalDevice)->getProperties(&properties);
2645 }
2646 break;
2647 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT:
2648 // Explicitly ignored, since VK_EXT_sample_locations is not supported
2649 ASSERT(!HasExtensionProperty(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, deviceExtensionProperties,
2650 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2651 break;
2652 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT:
2653 ASSERT(!HasExtensionProperty(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionProperties,
2654 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2655 break;
2656 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR:
2657 {
2658 auto& properties = *reinterpret_cast<VkPhysicalDeviceDriverPropertiesKHR*>(extensionProperties);
2659 vk::Cast(physicalDevice)->getProperties(&properties);
2660 }
2661 break;
2662#ifdef __ANDROID__
2663 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:
2664 {
2665 auto& properties = *reinterpret_cast<VkPhysicalDevicePresentationPropertiesANDROID*>(extensionProperties);
2666 vk::Cast(physicalDevice)->getProperties(&properties);
2667 }
2668 break;
2669#endif
2670 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT:
2671 {
2672 auto& properties = *reinterpret_cast<VkPhysicalDeviceLineRasterizationPropertiesEXT*>(extensionProperties);
2673 vk::Cast(physicalDevice)->getProperties(&properties);
2674 }
2675 break;
2676 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT:
2677 {
2678 auto& properties = *reinterpret_cast<VkPhysicalDeviceProvokingVertexPropertiesEXT*>(extensionProperties);
2679 vk::Cast(physicalDevice)->getProperties(&properties);
2680 }
2681 break;
2682 default:
2683 // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
2684 UNIMPLEMENTED("extensionProperties->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
2685 break;
2686 }
2687
2688 extensionProperties = extensionProperties->pNext;
2689 }
2690
2691 vkGetPhysicalDeviceProperties(physicalDevice, &(pProperties->properties));
2692}
2693
2694VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties)
2695{
2696 TRACE("(VkPhysicalDevice physicalDevice = %p, VkFormat format = %d, VkFormatProperties2* pFormatProperties = %p)",
2697 physicalDevice, format, pFormatProperties);
2698
2699 if(pFormatProperties->pNext)
2700 {
2701 UNIMPLEMENTED("pFormatProperties->pNext");
2702 }
2703
2704 vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &(pFormatProperties->formatProperties));
2705}
2706
2707VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties)
2708{
2709 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo = %p, VkImageFormatProperties2* pImageFormatProperties = %p)",
2710 physicalDevice, pImageFormatInfo, pImageFormatProperties);
2711
2712 const VkBaseInStructure* extensionFormatInfo = reinterpret_cast<const VkBaseInStructure*>(pImageFormatInfo->pNext);
2713
2714 const VkExternalMemoryHandleTypeFlagBits* handleType = nullptr;
2715 while(extensionFormatInfo)
2716 {
2717 switch(extensionFormatInfo->sType)
2718 {
2719 case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR:
2720 {
2721 // Explicitly ignored, since VK_KHR_image_format_list is not supported
2722 ASSERT(!HasExtensionProperty(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, deviceExtensionProperties,
2723 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2724 }
2725 break;
2726 case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
2727 {
2728 // Explicitly ignored, since VK_EXT_separate_stencil_usage is not supported
2729 ASSERT(!HasExtensionProperty(VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME, deviceExtensionProperties,
2730 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2731 }
2732 break;
2733 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
2734 {
2735 const VkPhysicalDeviceExternalImageFormatInfo* imageFormatInfo = reinterpret_cast<const VkPhysicalDeviceExternalImageFormatInfo*>(extensionFormatInfo);
2736 handleType = &(imageFormatInfo->handleType);
2737 }
2738 break;
2739 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
2740 {
2741 // Explicitly ignored, since VK_EXT_image_drm_format_modifier is not supported
2742 ASSERT(!HasExtensionProperty(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, deviceExtensionProperties,
2743 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2744 }
2745 break;
2746 default:
2747 UNIMPLEMENTED("extensionFormatInfo->sType");
2748 break;
2749 }
2750
2751 extensionFormatInfo = extensionFormatInfo->pNext;
2752 }
2753
2754 VkBaseOutStructure* extensionProperties = reinterpret_cast<VkBaseOutStructure*>(pImageFormatProperties->pNext);
2755
2756 while(extensionProperties)
2757 {
2758 switch(extensionProperties->sType)
2759 {
2760 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
2761 {
2762 auto& properties = *reinterpret_cast<VkExternalImageFormatProperties*>(extensionProperties);
2763 vk::Cast(physicalDevice)->getProperties(handleType, &properties);
2764 }
2765 break;
2766 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
2767 {
2768 auto& properties = *reinterpret_cast<VkSamplerYcbcrConversionImageFormatProperties*>(extensionProperties);
2769 vk::Cast(physicalDevice)->getProperties(&properties);
2770 }
2771 break;
2772 case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD:
2773 {
2774 // Explicitly ignored, since VK_AMD_texture_gather_bias_lod is not supported
2775 ASSERT(!HasExtensionProperty(VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME, deviceExtensionProperties,
2776 sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
2777 }
2778 break;
2779 default:
2780 UNIMPLEMENTED("extensionProperties->sType");
2781 break;
2782 }
2783
2784 extensionProperties = extensionProperties->pNext;
2785 }
2786
2787 return vkGetPhysicalDeviceImageFormatProperties(physicalDevice,
2788 pImageFormatInfo->format,
2789 pImageFormatInfo->type,
2790 pImageFormatInfo->tiling,
2791 pImageFormatInfo->usage,
2792 pImageFormatInfo->flags,
2793 &(pImageFormatProperties->imageFormatProperties));
2794}
2795
2796VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties)
2797{
2798 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t* pQueueFamilyPropertyCount = %p, VkQueueFamilyProperties2* pQueueFamilyProperties = %p)",
2799 physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
2800
2801 if(pQueueFamilyProperties && pQueueFamilyProperties->pNext)
2802 {
2803 UNIMPLEMENTED("pQueueFamilyProperties->pNext");
2804 }
2805
2806 if(!pQueueFamilyProperties)
2807 {
2808 *pQueueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
2809 }
2810 else
2811 {
2812 vk::Cast(physicalDevice)->getQueueFamilyProperties(*pQueueFamilyPropertyCount, pQueueFamilyProperties);
2813 }
2814}
2815
2816VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties)
2817{
2818 TRACE("(VkPhysicalDevice physicalDevice = %p, VkPhysicalDeviceMemoryProperties2* pMemoryProperties = %p)", physicalDevice, pMemoryProperties);
2819
2820 if(pMemoryProperties->pNext)
2821 {
2822 UNIMPLEMENTED("pMemoryProperties->pNext");
2823 }
2824
2825 vkGetPhysicalDeviceMemoryProperties(physicalDevice, &(pMemoryProperties->memoryProperties));
2826}
2827
2828VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties)
2829{
2830 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo = %p, uint32_t* pPropertyCount = %p, VkSparseImageFormatProperties2* pProperties = %p)",
2831 physicalDevice, pFormatInfo, pPropertyCount, pProperties);
2832
2833 if(pProperties && pProperties->pNext)
2834 {
2835 UNIMPLEMENTED("pProperties->pNext");
2836 }
2837
2838 // We do not support sparse images.
2839 *pPropertyCount = 0;
2840}
2841
2842VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
2843{
2844 TRACE("(VkDevice device = %p, VkCommandPool commandPool = %p, VkCommandPoolTrimFlags flags = %d)",
2845 device, static_cast<void*>(commandPool), flags);
2846
2847 vk::Cast(commandPool)->trim(flags);
2848}
2849
2850VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue)
2851{
2852 TRACE("(VkDevice device = %p, const VkDeviceQueueInfo2* pQueueInfo = %p, VkQueue* pQueue = %p)",
2853 device, pQueueInfo, pQueue);
2854
2855 if(pQueueInfo->pNext)
2856 {
2857 UNIMPLEMENTED("pQueueInfo->pNext");
2858 }
2859
2860 // The only flag that can be set here is VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
2861 // According to the Vulkan spec, 4.3.1. Queue Family Properties:
2862 // "VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT specifies that the device queue is a
2863 // protected-capable queue. If the protected memory feature is not enabled,
2864 // the VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT bit of flags must not be set."
2865 if(pQueueInfo->flags)
2866 {
2867 *pQueue = VK_NULL_HANDLE;
2868 }
2869 else
2870 {
2871 vkGetDeviceQueue(device, pQueueInfo->queueFamilyIndex, pQueueInfo->queueIndex, pQueue);
2872 }
2873}
2874
2875VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion)
2876{
2877 TRACE("(VkDevice device = %p, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSamplerYcbcrConversion* pYcbcrConversion = %p)",
2878 device, pCreateInfo, pAllocator, pYcbcrConversion);
2879
2880 if(pCreateInfo->pNext)
2881 {
2882 UNIMPLEMENTED("pCreateInfo->pNext");
2883 }
2884
2885 return vk::SamplerYcbcrConversion::Create(pAllocator, pCreateInfo, pYcbcrConversion);
2886}
2887
2888VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator)
2889{
2890 TRACE("(VkDevice device = %p, VkSamplerYcbcrConversion ycbcrConversion = %p, const VkAllocationCallbacks* pAllocator = %p)",
2891 device, static_cast<void*>(ycbcrConversion), pAllocator);
2892
2893 vk::destroy(ycbcrConversion, pAllocator);
2894}
2895
2896VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
2897{
2898 TRACE("(VkDevice device = %p, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate = %p)",
2899 device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
2900
2901 if(pCreateInfo->pNext || pCreateInfo->flags || (pCreateInfo->templateType != VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET))
2902 {
2903 UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags || (pCreateInfo->templateType != VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET)");
2904 }
2905
2906 return vk::DescriptorUpdateTemplate::Create(pAllocator, pCreateInfo, pDescriptorUpdateTemplate);
2907}
2908
2909VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator)
2910{
2911 TRACE("(VkDevice device = %p, VkDescriptorUpdateTemplate descriptorUpdateTemplate = %p, const VkAllocationCallbacks* pAllocator = %p)",
2912 device, static_cast<void*>(descriptorUpdateTemplate), pAllocator);
2913
2914 vk::destroy(descriptorUpdateTemplate, pAllocator);
2915}
2916
2917VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData)
2918{
2919 TRACE("(VkDevice device = %p, VkDescriptorSet descriptorSet = %p, VkDescriptorUpdateTemplate descriptorUpdateTemplate = %p, const void* pData = %p)",
2920 device, static_cast<void*>(descriptorSet), static_cast<void*>(descriptorUpdateTemplate), pData);
2921
2922 vk::Cast(descriptorUpdateTemplate)->updateDescriptorSet(vk::Cast(device), descriptorSet, pData);
2923}
2924
2925VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties)
2926{
2927 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo = %p, VkExternalBufferProperties* pExternalBufferProperties = %p)",
2928 physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
2929
2930 vk::Cast(physicalDevice)->getProperties(pExternalBufferInfo, pExternalBufferProperties);
2931}
2932
2933VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties)
2934{
2935 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo = %p, VkExternalFenceProperties* pExternalFenceProperties = %p)",
2936 physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
2937
2938 vk::Cast(physicalDevice)->getProperties(pExternalFenceInfo, pExternalFenceProperties);
2939}
2940
2941VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties)
2942{
2943 TRACE("(VkPhysicalDevice physicalDevice = %p, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo = %p, VkExternalSemaphoreProperties* pExternalSemaphoreProperties = %p)",
2944 physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
2945
2946 vk::Cast(physicalDevice)->getProperties(pExternalSemaphoreInfo, pExternalSemaphoreProperties);
2947}
2948
2949VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)
2950{
2951 TRACE("(VkDevice device = %p, const VkDescriptorSetLayoutCreateInfo* pCreateInfo = %p, VkDescriptorSetLayoutSupport* pSupport = %p)",
2952 device, pCreateInfo, pSupport);
2953
2954 vk::Cast(device)->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
2955}
2956
2957#ifdef VK_USE_PLATFORM_XCB_KHR
2958VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
2959{
2960 TRACE("(VkInstance instance = %p, VkXcbSurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
2961 instance, pCreateInfo, pAllocator, pSurface);
2962
2963 return vk::XcbSurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
2964}
2965
2966VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id)
2967{
2968 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, xcb_connection_t* connection = %p, xcb_visualid_t visual_id = %d)",
2969 physicalDevice, int(queueFamilyIndex), connection, int(visual_id));
2970
2971 return VK_TRUE;
2972}
2973#endif
2974
2975#ifdef VK_USE_PLATFORM_XLIB_KHR
2976VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
2977{
2978 TRACE("(VkInstance instance = %p, VkXlibSurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
2979 instance, pCreateInfo, pAllocator, pSurface);
2980
2981 return vk::XlibSurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
2982}
2983
2984VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID)
2985{
2986 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, Display* dpy = %p, VisualID visualID = %lu)",
2987 physicalDevice, int(queueFamilyIndex), dpy, visualID);
2988
2989 return VK_TRUE;
2990}
2991#endif
2992
2993#ifdef VK_USE_PLATFORM_MACOS_MVK
2994VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
2995{
2996 TRACE("(VkInstance instance = %p, VkMacOSSurfaceCreateInfoMVK* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
2997 instance, pCreateInfo, pAllocator, pSurface);
2998
2999 return vk::MacOSSurfaceMVK::Create(pAllocator, pCreateInfo, pSurface);
3000}
3001#endif
3002
3003#ifdef VK_USE_PLATFORM_METAL_EXT
3004VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
3005{
3006 TRACE("(VkInstance instance = %p, VkMetalSurfaceCreateInfoEXT* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
3007 instance, pCreateInfo, pAllocator, pSurface);
3008
3009 return vk::MetalSurfaceEXT::Create(pAllocator, pCreateInfo, pSurface);
3010}
3011#endif
3012
3013#ifdef VK_USE_PLATFORM_WIN32_KHR
3014VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
3015{
3016 TRACE("(VkInstance instance = %p, VkWin32SurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
3017 instance, pCreateInfo, pAllocator, pSurface);
3018
3019 return vk::Win32SurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
3020}
3021
3022VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex)
3023{
3024 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d)",
3025 physicalDevice, queueFamilyIndex);
3026 return VK_TRUE;
3027}
3028#endif
3029
3030#ifndef __ANDROID__
3031VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
3032{
3033 TRACE("(VkInstance instance = %p, VkSurfaceKHR surface = %p, const VkAllocationCallbacks* pAllocator = %p)",
3034 instance, static_cast<void*>(surface), pAllocator);
3035
3036 vk::destroy(surface, pAllocator);
3037}
3038
3039VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported)
3040{
3041 TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, VkSurface surface = %p, VKBool32* pSupported = %p)",
3042 physicalDevice, int(queueFamilyIndex), static_cast<void*>(surface), pSupported);
3043
3044 *pSupported = VK_TRUE;
3045 return VK_SUCCESS;
3046}
3047
3048VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
3049{
3050 TRACE("(VkPhysicalDevice physicalDevice = %p, VkSurfaceKHR surface = %p, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities = %p)",
3051 physicalDevice, static_cast<void*>(surface), pSurfaceCapabilities);
3052
3053 vk::Cast(surface)->getSurfaceCapabilities(pSurfaceCapabilities);
3054 return VK_SUCCESS;
3055}
3056
3057VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats)
3058{
3059 TRACE("(VkPhysicalDevice physicalDevice = %p, VkSurfaceKHR surface = %p. uint32_t* pSurfaceFormatCount = %p, VkSurfaceFormatKHR* pSurfaceFormats = %p)",
3060 physicalDevice, static_cast<void*>(surface), pSurfaceFormatCount, pSurfaceFormats);
3061
3062 if(!pSurfaceFormats)
3063 {
3064 *pSurfaceFormatCount = vk::Cast(surface)->getSurfaceFormatsCount();
3065 return VK_SUCCESS;
3066 }
3067
3068 return vk::Cast(surface)->getSurfaceFormats(pSurfaceFormatCount, pSurfaceFormats);
3069}
3070
3071VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes)
3072{
3073 TRACE("(VkPhysicalDevice physicalDevice = %p, VkSurfaceKHR surface = %p uint32_t* pPresentModeCount = %p, VkPresentModeKHR* pPresentModes = %p)",
3074 physicalDevice, static_cast<void*>(surface), pPresentModeCount, pPresentModes);
3075
3076 if(!pPresentModes)
3077 {
3078 *pPresentModeCount = vk::Cast(surface)->getPresentModeCount();
3079 return VK_SUCCESS;
3080 }
3081
3082 return vk::Cast(surface)->getPresentModes(pPresentModeCount, pPresentModes);
3083}
3084
3085VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
3086{
3087 TRACE("(VkDevice device = %p, const VkSwapchainCreateInfoKHR* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSwapchainKHR* pSwapchain = %p)",
3088 device, pCreateInfo, pAllocator, pSwapchain);
3089
3090 if(pCreateInfo->oldSwapchain)
3091 {
3092 vk::Cast(pCreateInfo->oldSwapchain)->retire();
3093 }
3094
3095 if(vk::Cast(pCreateInfo->surface)->hasAssociatedSwapchain())
3096 {
3097 return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
3098 }
3099
3100 VkResult status = vk::SwapchainKHR::Create(pAllocator, pCreateInfo, pSwapchain);
3101
3102 if(status != VK_SUCCESS)
3103 {
3104 return status;
3105 }
3106
3107 auto swapchain = vk::Cast(*pSwapchain);
3108 status = swapchain->createImages(device, pCreateInfo);
3109
3110 if(status != VK_SUCCESS)
3111 {
3112 vk::destroy(*pSwapchain, pAllocator);
3113 return status;
3114 }
3115
3116 vk::Cast(pCreateInfo->surface)->associateSwapchain(swapchain);
3117
3118 return VK_SUCCESS;
3119}
3120
3121VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator)
3122{
3123 TRACE("(VkDevice device = %p, VkSwapchainKHR swapchain = %p, const VkAllocationCallbacks* pAllocator = %p)",
3124 device, static_cast<void*>(swapchain), pAllocator);
3125
3126 vk::destroy(swapchain, pAllocator);
3127}
3128
3129VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages)
3130{
3131 TRACE("(VkDevice device = %p, VkSwapchainKHR swapchain = %p, uint32_t* pSwapchainImageCount = %p, VkImage* pSwapchainImages = %p)",
3132 device, static_cast<void*>(swapchain), pSwapchainImageCount, pSwapchainImages);
3133
3134 if(!pSwapchainImages)
3135 {
3136 *pSwapchainImageCount = vk::Cast(swapchain)->getImageCount();
3137 return VK_SUCCESS;
3138 }
3139
3140 return vk::Cast(swapchain)->getImages(pSwapchainImageCount, pSwapchainImages);
3141}
3142
3143VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex)
3144{
3145 TRACE("(VkDevice device = %p, VkSwapchainKHR swapchain = %p, uint64_t timeout = %d, VkSemaphore semaphore = %p, VkFence fence = %p, uint32_t* pImageIndex = %p)",
3146 device, static_cast<void*>(swapchain), int(timeout), static_cast<void*>(semaphore), static_cast<void*>(fence), pImageIndex);
3147
3148 return vk::Cast(swapchain)->getNextImage(timeout, vk::Cast(semaphore), vk::Cast(fence), pImageIndex);
3149}
3150
3151VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo)
3152{
3153 TRACE("(VkQueue queue = %p, const VkPresentInfoKHR* pPresentInfo = %p)",
3154 queue, pPresentInfo);
3155
3156 return vk::Cast(queue)->present(pPresentInfo);
3157}
3158
3159VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex)
3160{
3161 TRACE("(VkDevice device = %p, const VkAcquireNextImageInfoKHR *pAcquireInfo = %p, uint32_t *pImageIndex = %p",
3162 device, pAcquireInfo, pImageIndex);
3163
3164 return vk::Cast(pAcquireInfo->swapchain)->getNextImage(pAcquireInfo->timeout, vk::Cast(pAcquireInfo->semaphore), vk::Cast(pAcquireInfo->fence), pImageIndex);
3165}
3166
3167VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities)
3168{
3169 TRACE("(VkDevice device = %p, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities = %p)",
3170 device, pDeviceGroupPresentCapabilities);
3171
3172 for (int i = 0; i < VK_MAX_DEVICE_GROUP_SIZE; i++)
3173 {
3174 // The only real physical device in the presentation group is device 0,
3175 // and it can present to itself.
3176 pDeviceGroupPresentCapabilities->presentMask[i] = (i == 0) ? 1 : 0;
3177 }
3178
3179 pDeviceGroupPresentCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
3180
3181 return VK_SUCCESS;
3182}
3183
3184VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes)
3185{
3186 TRACE("(VkDevice device = %p, VkSurfaceKHR surface = %p, VkDeviceGroupPresentModeFlagsKHR *pModes = %p)",
3187 device, static_cast<void*>(surface), pModes);
3188
3189 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
3190 return VK_SUCCESS;
3191}
3192
3193VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
3194{
3195 TRACE("(VkPhysicalDevice physicalDevice = %p, VkSurfaceKHR surface = %p, uint32_t* pRectCount = %p, VkRect2D* pRects = %p)",
3196 physicalDevice, static_cast<void*>(surface), pRectCount, pRects);
3197
3198 return vk::Cast(surface)->getPresentRectangles(pRectCount, pRects);
3199}
3200
3201
3202#endif // ! __ANDROID__
3203
3204#ifdef __ANDROID__
3205
3206VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage)
3207{
3208 TRACE("(VkDevice device = %p, VkFormat format = %d, VkImageUsageFlags imageUsage = %d, VkSwapchainImageUsageFlagsANDROID swapchainUsage = %d, uint64_t* grallocConsumerUsage = %p, uin64_t* grallocProducerUsage = %p)",
3209 device, format, imageUsage, swapchainUsage, grallocConsumerUsage, grallocProducerUsage);
3210
3211 *grallocConsumerUsage = 0;
3212 *grallocProducerUsage = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
3213
3214 return VK_SUCCESS;
3215}
3216
3217VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage)
3218{
3219 TRACE("(VkDevice device = %p, VkFormat format = %d, VkImageUsageFlags imageUsage = %d, int* grallocUsage = %p)",
3220 device, format, imageUsage, grallocUsage);
3221
3222 *grallocUsage = GRALLOC_USAGE_SW_WRITE_OFTEN;
3223
3224 return VK_SUCCESS;
3225}
3226
3227VKAPI_ATTR VkResult VKAPI_CALL vkAcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence)
3228{
3229 TRACE("(VkDevice device = %p, VkImage image = %p, int nativeFenceFd = %d, VkSemaphore semaphore = %p, VkFence fence = %p)",
3230 device, static_cast<void*>(image), nativeFenceFd, static_cast<void*>(semaphore), static_cast<void*>(fence));
3231
3232 if(nativeFenceFd >= 0)
3233 {
3234 sync_wait(nativeFenceFd, -1);
3235 close(nativeFenceFd);
3236 }
3237
3238 if(fence != VK_NULL_HANDLE)
3239 {
3240 vk::Cast(fence)->complete();
3241 }
3242
3243 if(semaphore != VK_NULL_HANDLE)
3244 {
3245 vk::Cast(semaphore)->signal();
3246 }
3247
3248 return VK_SUCCESS;
3249}
3250
3251VKAPI_ATTR VkResult VKAPI_CALL vkQueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd)
3252{
3253 TRACE("(VkQueue queue = %p, uint32_t waitSemaphoreCount = %d, const VkSemaphore* pWaitSemaphores = %p, VkImage image = %p, int* pNativeFenceFd = %p)",
3254 queue, waitSemaphoreCount, pWaitSemaphores, static_cast<void*>(image), pNativeFenceFd);
3255
3256 // This is a hack to deal with screen tearing for now.
3257 // Need to correctly implement threading using VkSemaphore
3258 // to get rid of it. b/132458423
3259 vkQueueWaitIdle(queue);
3260
3261 *pNativeFenceFd = -1;
3262
3263 return vk::Cast(image)->prepareForExternalUseANDROID();
3264}
3265#endif // __ANDROID__
3266
3267}
3268