blob: 2c9eca0dfcf4c7ae4a65f8582eba47793a5e7184 [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Tobin Ehlisd34a4c52015-12-08 10:50:10 -07005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Tobin Ehlisd34a4c52015-12-08 10:50:10 -07009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070017 *
18 * Author: Tobin Ehlis <tobine@google.com>
19 */
20
Jamie Madilldf5d5732016-04-04 11:54:43 -040021#include "vk_loader_platform.h"
22#include "vulkan/vulkan.h"
23
Dustin Graves176f9df2016-07-14 17:28:11 -060024#include <cinttypes>
25#include <memory>
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070029
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070030#include <unordered_map>
Tobin Ehlis10ba1de2016-04-13 12:59:43 -060031#include <vector>
32#include <mutex>
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070033
34#include "vulkan/vk_layer.h"
35#include "vk_layer_config.h"
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070036#include "vk_layer_table.h"
37#include "vk_layer_data.h"
38#include "vk_layer_logging.h"
39#include "vk_layer_extension_utils.h"
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -070040#include "vk_safe_struct.h"
Jon Ashburndc9111c2016-03-22 12:57:13 -060041#include "vk_layer_utils.h"
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070042
Chia-I Wucdb70962016-05-13 14:07:36 +080043namespace unique_objects {
44
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -060045// All increments must be guarded by global_lock
46static uint64_t global_unique_id = 1;
47
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070048struct layer_data {
Chia-I Wu16570472016-05-17 07:57:15 +080049 VkInstance instance;
50
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070051 bool wsi_enabled;
Tobin Ehlis10ba1de2016-04-13 12:59:43 -060052 std::unordered_map<uint64_t, uint64_t> unique_id_mapping; // Map uniqueID to actual object handle
53 VkPhysicalDevice gpu;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070054
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -060055 layer_data() : wsi_enabled(false), gpu(VK_NULL_HANDLE){};
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070056};
57
Mark Lobodzinskife1f0662016-06-24 09:57:32 -060058struct instance_extension_enables {
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070059 bool wsi_enabled;
Tobin Ehlisa39c26a2016-01-05 16:34:59 -070060 bool xlib_enabled;
61 bool xcb_enabled;
62 bool wayland_enabled;
63 bool mir_enabled;
64 bool android_enabled;
65 bool win32_enabled;
Jon Ashburn5e026df2016-06-15 08:19:07 -060066 bool display_enabled;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070067};
68
Mark Lobodzinskife1f0662016-06-24 09:57:32 -060069static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
Jon Ashburn5484e0c2016-03-08 17:48:44 -070070static std::unordered_map<void *, layer_data *> layer_data_map;
71static device_table_map unique_objects_device_table_map;
72static instance_table_map unique_objects_instance_table_map;
Tobin Ehlis10ba1de2016-04-13 12:59:43 -060073static std::mutex global_lock; // Protect map accesses and unique_id increments
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070074
Dustin Graves176f9df2016-07-14 17:28:11 -060075struct GenericHeader {
76 VkStructureType sType;
77 void *pNext;
78};
79
80template <typename T> bool ContainsExtStruct(const T *target, VkStructureType ext_type) {
81 assert(target != nullptr);
82
83 const GenericHeader *ext_struct = reinterpret_cast<const GenericHeader *>(target->pNext);
84
85 while (ext_struct != nullptr) {
86 if (ext_struct->sType == ext_type) {
87 return true;
88 }
89
90 ext_struct = reinterpret_cast<const GenericHeader *>(ext_struct->pNext);
91 }
92
93 return false;
94}
95
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070096// Handle CreateInstance
Mark Youngaa1aa3a2016-07-05 16:41:50 -060097static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
Tobin Ehlisd34a4c52015-12-08 10:50:10 -070098 uint32_t i;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070099 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700100
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700101 instanceExtMap[pDisp] = {};
Mark Lobodzinskife1f0662016-06-24 09:57:32 -0600102
Jon Ashburnf19916e2016-01-11 13:12:43 -0700103 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700104 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700105 instanceExtMap[pDisp].wsi_enabled = true;
Jon Ashburn5e026df2016-06-15 08:19:07 -0600106 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0)
107 instanceExtMap[pDisp].display_enabled = true;
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700108#ifdef VK_USE_PLATFORM_XLIB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700109 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700110 instanceExtMap[pDisp].xlib_enabled = true;
111#endif
112#ifdef VK_USE_PLATFORM_XCB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700113 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700114 instanceExtMap[pDisp].xcb_enabled = true;
115#endif
116#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700117 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700118 instanceExtMap[pDisp].wayland_enabled = true;
119#endif
120#ifdef VK_USE_PLATFORM_MIR_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700121 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700122 instanceExtMap[pDisp].mir_enabled = true;
123#endif
124#ifdef VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700125 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700126 instanceExtMap[pDisp].android_enabled = true;
127#endif
128#ifdef VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700129 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0)
Tobin Ehlisa39c26a2016-01-05 16:34:59 -0700130 instanceExtMap[pDisp].win32_enabled = true;
131#endif
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700132 }
133}
134
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700135VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
136 VkInstance *pInstance) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700137 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700138
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700139 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700140 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700141 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700142 if (fpCreateInstance == NULL) {
143 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700144 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700145
146 // Advance the link info for the next element on the chain
147 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
148
149 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
150 if (result != VK_SUCCESS) {
151 return result;
152 }
153
Chia-I Wu16570472016-05-17 07:57:15 +0800154 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
155 my_data->instance = *pInstance;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700156 initInstanceTable(*pInstance, fpGetInstanceProcAddr, unique_objects_instance_table_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700157
Mark Youngaa1aa3a2016-07-05 16:41:50 -0600158 checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700159
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700160 return result;
161}
162
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600163void explicit_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Dustin Graves7b098da2016-04-29 11:55:43 -0600164 dispatch_key key = get_dispatch_key(instance);
Jon Ashburn5e026df2016-06-15 08:19:07 -0600165 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
166 instanceExtMap.erase(pDisp);
Cody Northrop48968b42016-07-12 11:43:32 -0600167 pDisp->DestroyInstance(instance, pAllocator);
168 layer_data_map.erase(key);
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600169}
170
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700171// Handle CreateDevice
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700172static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700173 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
174 VkLayerDispatchTable *pDisp = get_dispatch_table(unique_objects_device_table_map, device);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700175 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700176 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
177 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
178 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
179 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
180 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700181 my_device_data->wsi_enabled = false;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700182 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700183 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700184 my_device_data->wsi_enabled = true;
185 }
186}
187
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700188VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
189 VkDevice *pDevice) {
Chia-I Wu16570472016-05-17 07:57:15 +0800190 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700191 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700192
193 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700194 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
195 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Chia-I Wu16570472016-05-17 07:57:15 +0800196 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700197 if (fpCreateDevice == NULL) {
198 return VK_ERROR_INITIALIZATION_FAILED;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700199 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700200
201 // Advance the link info for the next element on the chain
202 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
203
204 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
205 if (result != VK_SUCCESS) {
206 return result;
207 }
208
209 // Setup layer's device dispatch table
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700210 initDeviceTable(*pDevice, fpGetDeviceProcAddr, unique_objects_device_table_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700211
212 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600213 // Set gpu for this device in order to get at any objects mapped at instance level
214 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
215 my_device_data->gpu = gpu;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700216
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700217 return result;
218}
219
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600220void explicit_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Dustin Graves7b098da2016-04-29 11:55:43 -0600221 dispatch_key key = get_dispatch_key(device);
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600222 get_dispatch_table(unique_objects_device_table_map, device)->DestroyDevice(device, pAllocator);
Dustin Graves7b098da2016-04-29 11:55:43 -0600223 layer_data_map.erase(key);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700224}
225
Dustin Graves176f9df2016-07-14 17:28:11 -0600226VkResult explicit_AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
227 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
228 const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
229 std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
230 std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
231 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
232
233 if ((pAllocateInfo != nullptr) &&
234 ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
235 // Assuming there is only one extension struct of this type in the list for now
236 safe_dedicated_allocate_info =
237 std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
238 safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo);
239
240 safe_allocate_info->initialize(pAllocateInfo);
241 input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
242
243 const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
244 GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
245 while (orig_pnext != nullptr) {
246 if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
247 safe_dedicated_allocate_info->initialize(
248 reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
249
250 std::unique_lock<std::mutex> lock(global_lock);
251
252 if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
253 uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
254 safe_dedicated_allocate_info->buffer =
255 reinterpret_cast<VkBuffer &>(my_map_data->unique_id_mapping[local_buffer]);
256 }
257
258 if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
259 uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
260 safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(my_map_data->unique_id_mapping[local_image]);
261 }
262
263 lock.unlock();
264
265 input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
266 input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
267 } else {
268 // TODO: generic handling of pNext copies
269 }
270
271 orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
272 }
273 }
274
275 VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
276 ->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
277
278 if (VK_SUCCESS == result) {
279 std::lock_guard<std::mutex> lock(global_lock);
280 uint64_t unique_id = global_unique_id++;
281 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
282 *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
283 }
284
285 return result;
286}
287
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700288VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
289 const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
290 VkPipeline *pPipelines) {
291 // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'stage': {'module': 'VkShaderModule'},
292 // 'layout': 'VkPipelineLayout', 'basePipelineHandle': 'VkPipeline'}}
293 // LOCAL DECLS:{'pCreateInfos': 'VkComputePipelineCreateInfo*'}
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600294 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700295 safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700296 if (pCreateInfos) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600297 std::lock_guard<std::mutex> lock(global_lock);
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700298 local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700299 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700300 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
301 if (pCreateInfos[idx0].basePipelineHandle) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700302 local_pCreateInfos[idx0].basePipelineHandle =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600303 (VkPipeline)my_device_data
304 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700305 }
306 if (pCreateInfos[idx0].layout) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600307 local_pCreateInfos[idx0].layout =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600308 (VkPipelineLayout)
309 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700310 }
311 if (pCreateInfos[idx0].stage.module) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700312 local_pCreateInfos[idx0].stage.module =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600313 (VkShaderModule)
314 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].stage.module)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700315 }
316 }
317 }
318 if (pipelineCache) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600319 std::lock_guard<std::mutex> lock(global_lock);
Dustin Gravesa7622d82016-04-14 17:29:20 -0600320 pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700321 }
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600322
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700323 VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
324 ->CreateComputePipelines(device, pipelineCache, createInfoCount,
325 (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
Eric Engestrom53b513f2016-02-21 19:58:09 +0000326 delete[] local_pCreateInfos;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700327 if (VK_SUCCESS == result) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600328 uint64_t unique_id = 0;
329 std::lock_guard<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700330 for (uint32_t i = 0; i < createInfoCount; ++i) {
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -0600331 unique_id = global_unique_id++;
Dustin Gravesa7622d82016-04-14 17:29:20 -0600332 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
333 pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700334 }
335 }
336 return result;
337}
338
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700339VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
340 const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
341 VkPipeline *pPipelines) {
342 // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'layout': 'VkPipelineLayout',
343 // 'pStages[stageCount]': {'module': 'VkShaderModule'}, 'renderPass': 'VkRenderPass', 'basePipelineHandle': 'VkPipeline'}}
344 // LOCAL DECLS:{'pCreateInfos': 'VkGraphicsPipelineCreateInfo*'}
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600345 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700346 safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = NULL;
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700347 if (pCreateInfos) {
348 local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600349 std::lock_guard<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700350 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700351 local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
352 if (pCreateInfos[idx0].basePipelineHandle) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700353 local_pCreateInfos[idx0].basePipelineHandle =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600354 (VkPipeline)my_device_data
355 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700356 }
357 if (pCreateInfos[idx0].layout) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600358 local_pCreateInfos[idx0].layout =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600359 (VkPipelineLayout)
360 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700361 }
362 if (pCreateInfos[idx0].pStages) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700363 for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700364 if (pCreateInfos[idx0].pStages[idx1].module) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700365 local_pCreateInfos[idx0].pStages[idx1].module =
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600366 (VkShaderModule)my_device_data
Dustin Gravesa7622d82016-04-14 17:29:20 -0600367 ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].pStages[idx1].module)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700368 }
369 }
370 }
371 if (pCreateInfos[idx0].renderPass) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600372 local_pCreateInfos[idx0].renderPass =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600373 (VkRenderPass)
374 my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].renderPass)];
Tobin Ehlis8bb7c2f2016-02-10 15:38:45 -0700375 }
376 }
377 }
378 if (pipelineCache) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600379 std::lock_guard<std::mutex> lock(global_lock);
Dustin Gravesa7622d82016-04-14 17:29:20 -0600380 pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700381 }
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600382
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700383 VkResult result =
384 get_dispatch_table(unique_objects_device_table_map, device)
385 ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount,
386 (const VkGraphicsPipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
Eric Engestrom53b513f2016-02-21 19:58:09 +0000387 delete[] local_pCreateInfos;
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700388 if (VK_SUCCESS == result) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600389 uint64_t unique_id = 0;
390 std::lock_guard<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700391 for (uint32_t i = 0; i < createInfoCount; ++i) {
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -0600392 unique_id = global_unique_id++;
Dustin Gravesa7622d82016-04-14 17:29:20 -0600393 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
394 pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700395 }
396 }
397 return result;
398}
399
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600400VkResult explicit_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
401 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
402 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
403
404 safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
405 if (pCreateInfo) {
406 std::lock_guard<std::mutex> lock(global_lock);
407 local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
408 local_pCreateInfo->oldSwapchain =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600409 (VkSwapchainKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->oldSwapchain)];
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600410 // Need to pull surface mapping from the instance-level map
411 layer_data *instance_data = get_my_data_ptr(get_dispatch_key(my_map_data->gpu), layer_data_map);
412 local_pCreateInfo->surface =
Dustin Gravesa7622d82016-04-14 17:29:20 -0600413 (VkSurfaceKHR)instance_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->surface)];
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600414 }
415
416 VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
417 ->CreateSwapchainKHR(device, (const VkSwapchainCreateInfoKHR *)local_pCreateInfo, pAllocator, pSwapchain);
418 if (local_pCreateInfo)
419 delete local_pCreateInfo;
420 if (VK_SUCCESS == result) {
421 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -0600422 uint64_t unique_id =global_unique_id++;
Dustin Gravesa7622d82016-04-14 17:29:20 -0600423 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pSwapchain);
424 *pSwapchain = reinterpret_cast<VkSwapchainKHR &>(unique_id);
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600425 }
426 return result;
427}
428
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700429VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
430 VkImage *pSwapchainImages) {
431 // UNWRAP USES:
432 // 0 : swapchain,VkSwapchainKHR, pSwapchainImages,VkImage
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600433 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700434 if (VK_NULL_HANDLE != swapchain) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600435 std::lock_guard<std::mutex> lock(global_lock);
Dustin Gravesa7622d82016-04-14 17:29:20 -0600436 swapchain = (VkSwapchainKHR)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(swapchain)];
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700437 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700438 VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
439 ->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700440 // TODO : Need to add corresponding code to delete these images
441 if (VK_SUCCESS == result) {
442 if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
Tobin Ehlis10ba1de2016-04-13 12:59:43 -0600443 uint64_t unique_id = 0;
444 std::lock_guard<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700445 for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
Mark Lobodzinskifdf8f472016-04-28 16:36:58 -0600446 unique_id = global_unique_id++;
Dustin Gravesa7622d82016-04-14 17:29:20 -0600447 my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pSwapchainImages[i]);
448 pSwapchainImages[i] = reinterpret_cast<VkImage &>(unique_id);
Tobin Ehlisd34a4c52015-12-08 10:50:10 -0700449 }
450 }
451 }
452 return result;
453}
Chia-I Wucdb70962016-05-13 14:07:36 +0800454
Jon Ashburnbd846452016-06-30 10:21:55 -0600455 #ifndef __ANDROID__
Jon Ashburn73a34352016-06-29 16:12:51 -0600456VkResult explicit_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties)
457{
458 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
459 safe_VkDisplayPropertiesKHR* local_pProperties = NULL;
460 {
461 std::lock_guard<std::mutex> lock(global_lock);
462 if (pProperties) {
463 local_pProperties = new safe_VkDisplayPropertiesKHR[*pPropertyCount];
464 for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
465 local_pProperties[idx0].initialize(&pProperties[idx0]);
466 if (pProperties[idx0].display) {
467 local_pProperties[idx0].display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pProperties[idx0].display)];
468 }
469 }
470 }
471 }
472
473 VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, ( VkDisplayPropertiesKHR*)local_pProperties);
474 if (result == VK_SUCCESS && pProperties)
475 {
476 for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
477 std::lock_guard<std::mutex> lock(global_lock);
478
479 uint64_t unique_id = global_unique_id++;
480 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].display);
481 pProperties[idx0].display = reinterpret_cast<VkDisplayKHR&>(unique_id);
482 pProperties[idx0].displayName = local_pProperties[idx0].displayName;
483 pProperties[idx0].physicalDimensions = local_pProperties[idx0].physicalDimensions;
484 pProperties[idx0].physicalResolution = local_pProperties[idx0].physicalResolution;
485 pProperties[idx0].supportedTransforms = local_pProperties[idx0].supportedTransforms;
486 pProperties[idx0].planeReorderPossible = local_pProperties[idx0].planeReorderPossible;
487 pProperties[idx0].persistentContent = local_pProperties[idx0].persistentContent;
488 }
489 }
490 if (local_pProperties)
491 delete[] local_pProperties;
492 return result;
493}
494
Jon Ashburn5e026df2016-06-15 08:19:07 -0600495VkResult explicit_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
496{
497 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
498 VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
499 if (VK_SUCCESS == result) {
500 if ((*pDisplayCount > 0) && pDisplays) {
501 std::lock_guard<std::mutex> lock(global_lock);
Jon Ashburn5e026df2016-06-15 08:19:07 -0600502 for (uint32_t i = 0; i < *pDisplayCount; i++) {
Jon Ashburnbd846452016-06-30 10:21:55 -0600503 auto it = my_map_data->unique_id_mapping.find(reinterpret_cast<const uint64_t &> (pDisplays[i]));
Jon Ashburn73a34352016-06-29 16:12:51 -0600504 assert (it != my_map_data->unique_id_mapping.end());
Jon Ashburnbd846452016-06-30 10:21:55 -0600505 pDisplays[i] = reinterpret_cast<VkDisplayKHR&> (it->second);
Jon Ashburn5e026df2016-06-15 08:19:07 -0600506 }
507 }
508 }
509 return result;
510}
Jon Ashburn32e042d2016-06-28 14:46:12 -0600511
512
513VkResult explicit_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties)
514{
515 layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
516 safe_VkDisplayModePropertiesKHR* local_pProperties = NULL;
517 {
518 std::lock_guard<std::mutex> lock(global_lock);
519 display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(display)];
520 if (pProperties) {
521 local_pProperties = new safe_VkDisplayModePropertiesKHR[*pPropertyCount];
522 for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
523 local_pProperties[idx0].initialize(&pProperties[idx0]);
524 }
525 }
526 }
527
528 VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, ( VkDisplayModePropertiesKHR*)local_pProperties);
529 if (result == VK_SUCCESS && pProperties)
530 {
531 for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
532 std::lock_guard<std::mutex> lock(global_lock);
533
534 uint64_t unique_id = global_unique_id++;
535 my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].displayMode);
536 pProperties[idx0].displayMode = reinterpret_cast<VkDisplayModeKHR&>(unique_id);
537 pProperties[idx0].parameters.visibleRegion.width = local_pProperties[idx0].parameters.visibleRegion.width;
538 pProperties[idx0].parameters.visibleRegion.height = local_pProperties[idx0].parameters.visibleRegion.height;
539 pProperties[idx0].parameters.refreshRate = local_pProperties[idx0].parameters.refreshRate;
540 }
541 }
542 if (local_pProperties)
543 delete[] local_pProperties;
544 return result;
545}
Jon Ashburnbd846452016-06-30 10:21:55 -0600546#endif
Chia-I Wucdb70962016-05-13 14:07:36 +0800547} // namespace unique_objects