blob: 4749e207048ca77e8edf0787c69c44022831ea23 [file] [log] [blame]
Mark Lobodzinski317574e2016-08-29 14:21:14 -06001/*
2 * Copyright (c) 2015-2016 The Khronos Group Inc.
3 * Copyright (c) 2015-2016 Valve Corporation
4 * Copyright (c) 2015-2016 LunarG, Inc.
5 *
6 * 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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * 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.
17 *
18 * Author: Mark Lobodzinski <mark@lunarg.com>
19 */
20
21#define _GNU_SOURCE
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include "vk_loader_platform.h"
26#include "loader.h"
27#include "extensions.h"
28#include <vulkan/vk_icd.h>
29
Mark Young35159af2016-09-07 08:50:32 -060030// Definitions for EXT_debug_marker extension
Mark Lobodzinski317574e2016-08-29 14:21:14 -060031
Mark Young35159af2016-09-07 08:50:32 -060032VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT(
33 VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
34 struct loader_dev_dispatch_table *disp = loader_get_dev_dispatch(device);
35 if (0 == disp->enabled_known_extensions.ext_debug_marker ||
36 NULL == disp->core_dispatch.DebugMarkerSetObjectTagEXT) {
37 return VK_ERROR_EXTENSION_NOT_PRESENT;
38 } else {
39 return disp->core_dispatch.DebugMarkerSetObjectTagEXT(device, pTagInfo);
40 }
41}
42
43VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT(
44 VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
45 struct loader_dev_dispatch_table *disp = loader_get_dev_dispatch(device);
46 if (0 == disp->enabled_known_extensions.ext_debug_marker ||
47 NULL == disp->core_dispatch.DebugMarkerSetObjectNameEXT) {
48 return VK_ERROR_EXTENSION_NOT_PRESENT;
49 } else {
50 return disp->core_dispatch.DebugMarkerSetObjectNameEXT(device,
51 pNameInfo);
52 }
53}
54
55VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT(
56 VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
57 struct loader_dev_dispatch_table *disp =
58 loader_get_dev_dispatch(commandBuffer);
59 if (1 == disp->enabled_known_extensions.ext_debug_marker &&
60 NULL != disp->core_dispatch.CmdDebugMarkerBeginEXT) {
61 disp->core_dispatch.CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
62 }
63}
64
65VKAPI_ATTR void VKAPI_CALL
66vkCmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) {
67 struct loader_dev_dispatch_table *disp =
68 loader_get_dev_dispatch(commandBuffer);
69 if (1 == disp->enabled_known_extensions.ext_debug_marker &&
70 NULL != disp->core_dispatch.CmdDebugMarkerEndEXT) {
71 disp->core_dispatch.CmdDebugMarkerEndEXT(commandBuffer);
72 }
73}
74
75VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT(
76 VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
77 struct loader_dev_dispatch_table *disp =
78 loader_get_dev_dispatch(commandBuffer);
79 if (1 == disp->enabled_known_extensions.ext_debug_marker &&
80 NULL != disp->core_dispatch.CmdDebugMarkerInsertEXT) {
81 disp->core_dispatch.CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
82 }
83}
84
85// Definitions for the VK_NV_external_memory_capabilities extension
Mark Lobodzinski317574e2016-08-29 14:21:14 -060086
87LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
88vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
89 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
90 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
91 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
92 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
93
94 const VkLayerInstanceDispatchTable *disp;
Mark Young35159af2016-09-07 08:50:32 -060095 struct loader_physical_device_tramp *phys_dev =
96 (struct loader_physical_device_tramp *)physicalDevice;
97 struct loader_instance *inst = phys_dev->this_instance;
Mark Lobodzinski317574e2016-08-29 14:21:14 -060098 VkPhysicalDevice unwrapped_phys_dev =
99 loader_unwrap_physical_device(physicalDevice);
100 disp = loader_get_instance_dispatch(physicalDevice);
101
Mark Young35159af2016-09-07 08:50:32 -0600102 if (0 == inst->enabled_known_extensions.nv_external_memory_capabilities ||
103 NULL == disp->GetPhysicalDeviceExternalImageFormatPropertiesNV) {
104 loader_log(
105 inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
106 "vkGetPhysicalDeviceExternalImageFormatPropertiesNV called without"
107 " NV_external_memory_capabilities extension being enabled");
108 return VK_ERROR_EXTENSION_NOT_PRESENT;
109 } else {
110 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
111 unwrapped_phys_dev, format, type, tiling, usage, flags,
112 externalHandleType, pExternalImageFormatProperties);
113 }
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600114}
115
116VKAPI_ATTR VkResult VKAPI_CALL
117terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
118 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
119 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
120 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
121 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600122 struct loader_physical_device *phys_dev =
123 (struct loader_physical_device *)physicalDevice;
124 struct loader_icd *icd = phys_dev->this_icd;
125
James Jones389dc0c2016-08-18 23:41:19 +0100126 if (!icd->GetPhysicalDeviceExternalImageFormatPropertiesNV) {
127 if (externalHandleType) {
128 return VK_ERROR_FORMAT_NOT_SUPPORTED;
129 }
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600130
James Jones389dc0c2016-08-18 23:41:19 +0100131 if (!icd->GetPhysicalDeviceImageFormatProperties) {
132 return VK_ERROR_INITIALIZATION_FAILED;
133 }
134
135 pExternalImageFormatProperties->externalMemoryFeatures = 0;
136 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
137 pExternalImageFormatProperties->compatibleHandleTypes = 0;
138
139 return icd->GetPhysicalDeviceImageFormatProperties(
140 phys_dev->phys_dev, format, type, tiling, usage, flags,
141 &pExternalImageFormatProperties->imageFormatProperties);
142 }
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600143
144 return icd->GetPhysicalDeviceExternalImageFormatPropertiesNV(
145 phys_dev->phys_dev, format, type, tiling, usage, flags,
146 externalHandleType, pExternalImageFormatProperties);
147}
148
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600149// Definitions for the VK_AMD_draw_indirect_count extension
150
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600151VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD(
152 VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
153 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
154 uint32_t stride) {
Mark Young35159af2016-09-07 08:50:32 -0600155 struct loader_dev_dispatch_table *disp =
156 loader_get_dev_dispatch(commandBuffer);
157 if (1 == disp->enabled_known_extensions.amd_draw_indirect_count &&
158 NULL != disp->core_dispatch.CmdDrawIndirectCountAMD) {
159 disp->core_dispatch.CmdDrawIndirectCountAMD(
160 commandBuffer, buffer, offset, countBuffer, countBufferOffset,
161 maxDrawCount, stride);
162 }
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600163}
164
165VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(
166 VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
167 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
168 uint32_t stride) {
Mark Young35159af2016-09-07 08:50:32 -0600169 struct loader_dev_dispatch_table *disp =
170 loader_get_dev_dispatch(commandBuffer);
171 if (1 == disp->enabled_known_extensions.amd_draw_indirect_count &&
172 NULL != disp->core_dispatch.CmdDrawIndexedIndirectCountAMD) {
173 disp->core_dispatch.CmdDrawIndexedIndirectCountAMD(
174 commandBuffer, buffer, offset, countBuffer, countBufferOffset,
175 maxDrawCount, stride);
176 }
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600177}
178
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600179#ifdef VK_USE_PLATFORM_WIN32_KHR
180
181// Definitions for the VK_NV_external_memory_win32 extension
182
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600183VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
184 VkDevice device, VkDeviceMemory memory,
185 VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle) {
Mark Young35159af2016-09-07 08:50:32 -0600186 struct loader_dev_dispatch_table *disp = loader_get_dev_dispatch(device);
187 if (0 == disp->enabled_known_extensions.nv_external_memory_win32 ||
188 NULL == disp->core_dispatch.GetMemoryWin32HandleNV) {
189 return VK_ERROR_EXTENSION_NOT_PRESENT;
190 } else {
191 return disp->core_dispatch.GetMemoryWin32HandleNV(device, memory,
192 handleType, pHandle);
193 }
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600194}
195
196#endif // VK_USE_PLATFORM_WIN32_KHR
197
198// GPA helpers for non-KHR extensions
199
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600200bool extension_instance_gpa(struct loader_instance *ptr_instance,
201 const char *name, void **addr) {
202 *addr = NULL;
203
Mark Young35159af2016-09-07 08:50:32 -0600204 // Functions for the EXT_debug_marker extension
205
206 if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
207 *addr = (void *)vkDebugMarkerSetObjectTagEXT;
208 return true;
209 }
210 if (!strcmp("vkDebugMarkerSetObjectNameEXT", name)) {
211 *addr = (void *)vkDebugMarkerSetObjectNameEXT;
212 return true;
213 }
214 if (!strcmp("vkCmdDebugMarkerBeginEXT", name)) {
215 *addr = (void *)vkCmdDebugMarkerBeginEXT;
216 return true;
217 }
218 if (!strcmp("vkCmdDebugMarkerEndEXT", name)) {
219 *addr = (void *)vkCmdDebugMarkerEndEXT;
220 return true;
221 }
222 if (!strcmp("vkCmdDebugMarkerInsertEXT", name)) {
223 *addr = (void *)vkCmdDebugMarkerInsertEXT;
224 return true;
225 }
226
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600227 // Functions for the VK_NV_external_memory_capabilities extension
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600228
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600229 if (!strcmp("vkGetPhysicalDeviceExternalImageFormatPropertiesNV", name)) {
Mark Young35159af2016-09-07 08:50:32 -0600230 *addr = (ptr_instance->enabled_known_extensions
231 .nv_external_memory_capabilities == 1)
232 ? (void *)vkGetPhysicalDeviceExternalImageFormatPropertiesNV
233 : NULL;
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600234 return true;
235 }
236
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600237 // Functions for the VK_AMD_draw_indirect_count extension
238
239 if (!strcmp("vkCmdDrawIndirectCountAMD", name)) {
240 *addr = (void *)vkCmdDrawIndirectCountAMD;
241 return true;
242 }
243
244 if (!strcmp("vkCmdDrawIndexedIndirectCountAMD", name)) {
245 *addr = (void *)vkCmdDrawIndexedIndirectCountAMD;
246 return true;
247 }
248
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600249#ifdef VK_USE_PLATFORM_WIN32_KHR
250
251 // Functions for the VK_NV_external_memory_win32 extension
252
253 if (!strcmp("vkGetMemoryWin32HandleNV", name)) {
254 *addr = (void *)vkGetMemoryWin32HandleNV;
255 return true;
256 }
257
258#endif // VK_USE_PLATFORM_WIN32_KHR
259
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600260 return false;
261}
262
263void extensions_create_instance(struct loader_instance *ptr_instance,
264 const VkInstanceCreateInfo *pCreateInfo) {
Mark Young35159af2016-09-07 08:50:32 -0600265 ptr_instance->enabled_known_extensions.nv_external_memory_capabilities = 0;
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600266
267 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
268 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
269 VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME) == 0) {
Mark Young35159af2016-09-07 08:50:32 -0600270 ptr_instance->enabled_known_extensions
271 .nv_external_memory_capabilities = 1;
272 return;
273 }
274 }
275}
276
277void extensions_create_device(struct loader_device *dev,
278 const VkDeviceCreateInfo *pCreateInfo) {
279 dev->loader_dispatch.enabled_known_extensions.ext_debug_marker = 0;
280 dev->loader_dispatch.enabled_known_extensions.amd_draw_indirect_count = 0;
281 dev->loader_dispatch.enabled_known_extensions.nv_external_memory_win32 = 0;
282
283 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
284 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
285 VK_EXT_DEBUG_MARKER_EXTENSION_NAME) == 0) {
286 dev->loader_dispatch.enabled_known_extensions.ext_debug_marker = 1;
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600287 return;
288 }
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600289
290 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
291 VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_EXTENSION_NAME) == 0) {
Mark Young35159af2016-09-07 08:50:32 -0600292 dev->loader_dispatch.enabled_known_extensions
293 .amd_draw_indirect_count = 1;
Mark Lobodzinski0853ad52016-08-29 14:54:34 -0600294 return;
295 }
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600296
297#ifdef VK_USE_PLATFORM_WIN32_KHR
298 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
299 VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) == 0) {
Mark Young35159af2016-09-07 08:50:32 -0600300 dev->loader_dispatch.enabled_known_extensions
301 .nv_external_memory_win32 = 1;
Mark Lobodzinski5f208522016-08-29 15:36:23 -0600302 return;
303 }
304#endif // VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinski317574e2016-08-29 14:21:14 -0600305 }
306}