From cdaa4fd95aa802abed46837ff3b297fba1844ea0 Mon Sep 17 00:00:00 2001 From: Mike Stroyan Date: Tue, 5 May 2015 16:33:08 -0600 Subject: layers: update object tracker memory ref validation Allocate enough space for queueInfo. Record queueNodeIndex to allow setGpuQueueInfoState between addQueueInfo and validateQueueFlags. Report case when queue flags remain unknown to application and layer. Move expanded common code into validateQueueFlags. Initialize g_pQueueInfo to NULL. Handle case when it is NULL. Handle when malloc or realloc fails. --- vk-layer-generate.py | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 5fa03d18..cdd9be54 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -904,13 +904,13 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append('typedef struct _OT_QUEUE_INFO {') header_txt.append(' OT_MEM_INFO *pMemRefList;') header_txt.append(' struct _OT_QUEUE_INFO *pNextQI;') - header_txt.append(' VkPhysicalDeviceQueueProperties *pQueueProps;') + header_txt.append(' uint32_t queueNodeIndex;') header_txt.append(' VkQueue queue;') header_txt.append(' uint32_t refCount;') header_txt.append('} OT_QUEUE_INFO;') header_txt.append('') header_txt.append('// Global list of QueueInfo structures, one per queue') - header_txt.append('static OT_QUEUE_INFO *g_pQueueInfo;') + header_txt.append('static OT_QUEUE_INFO *g_pQueueInfo = NULL;') header_txt.append('') header_txt.append('// Convert an object type enum to an object type array index') header_txt.append('static uint32_t objTypeToIndex(uint32_t objType)') @@ -948,11 +948,11 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append('static void addQueueInfo(uint32_t queueNodeIndex, VkQueue queue)') header_txt.append('{') header_txt.append(' OT_QUEUE_INFO *pQueueInfo = malloc(sizeof(OT_QUEUE_INFO));') - header_txt.append(' memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));') - header_txt.append(' pQueueInfo->queue = queue;') - header_txt.append(' pQueueInfo->pQueueProps = &queueInfo[queueNodeIndex];') header_txt.append('') header_txt.append(' if (pQueueInfo != NULL) {') + header_txt.append(' memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));') + header_txt.append(' pQueueInfo->queue = queue;') + header_txt.append(' pQueueInfo->queueNodeIndex = queueNodeIndex;') header_txt.append(' pQueueInfo->pNextQI = g_pQueueInfo;') header_txt.append(' g_pQueueInfo = pQueueInfo;') header_txt.append(' }') @@ -1158,23 +1158,28 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append('') header_txt.append('static void setGpuQueueInfoState(size_t* pDataSize, void *pData) {') header_txt.append(' queueCount = ((uint32_t)*pDataSize / sizeof(VkPhysicalDeviceQueueProperties));') - header_txt.append(' queueInfo = (VkPhysicalDeviceQueueProperties*)malloc(sizeof(pDataSize));') - header_txt.append(' memcpy(queueInfo, pData, *pDataSize);') + header_txt.append(' queueInfo = (VkPhysicalDeviceQueueProperties*)realloc((void*)queueInfo, *pDataSize);') + header_txt.append(' if (queueInfo != NULL) {') + header_txt.append(' memcpy(queueInfo, pData, *pDataSize);') + header_txt.append(' }') header_txt.append('}') header_txt.append('') header_txt.append('// Check object status for selected flag state') - header_txt.append('static bool32_t validateQueueFlags(VkQueue queue) {') - header_txt.append(' bool32_t result = VK_TRUE;') + header_txt.append('static void validateQueueFlags(VkQueue queue, const char *function) {') header_txt.append(' OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;') - header_txt.append(' while (pQueueInfo->queue != queue) {') + header_txt.append(' while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {') header_txt.append(' pQueueInfo = pQueueInfo->pNextQI;') header_txt.append(' }') header_txt.append(' if (pQueueInfo != NULL) {') - header_txt.append(' if ((pQueueInfo->pQueueProps->queueFlags & VK_QUEUE_MEMMGR_BIT) == 0) {') - header_txt.append(' result = VK_FALSE;') + header_txt.append(' char str[1024];\n') + header_txt.append(' if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_MEMMGR_BIT) == 0) {') + header_txt.append(' sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not set", function);') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);') + header_txt.append(' } else {') + header_txt.append(' sprintf(str, "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not known", function);') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);') header_txt.append(' }') header_txt.append(' }') - header_txt.append(' return result;') header_txt.append('}') header_txt.append('') header_txt.append('// Check object status for selected flag state') @@ -1241,22 +1246,18 @@ class ObjectTrackerSubcommand(Subcommand): using_line += ' // validate_memory_mapping_status(pMemRefs, memRefCount);\n' using_line += ' // validate_mem_ref_count(memRefCount);\n' using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' + elif 'QueueBindObjectMemoryRange' in proto.name: + using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) + using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindObject' in proto.name: using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) - using_line += ' if (validateQueueFlags(queue) == VK_FALSE) {\n' - using_line += ' char str[1024];\n' - using_line += ' sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not set");\n' % (proto.name) - using_line += ' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);\n' - using_line += ' }\n' using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindImage' in proto.name: using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' - using_line += ' if (validateQueueFlags(queue) == VK_FALSE) {\n' - using_line += ' char str[1024];\n' - using_line += ' sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not set");\n' % (proto.name) - using_line += ' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);\n' - using_line += ' }\n' + using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'GetObjectInfo' in proto.name: using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) -- cgit v1.2.3 From 8665489787ce42479cdc49b0e31b883415aa526e Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Tue, 5 May 2015 16:20:46 -0600 Subject: loader: logging on Windows to both debug output and stderr --- loader/loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/loader.c b/loader/loader.c index f5e4472c..17778d5b 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -235,10 +235,10 @@ static void loader_log(VK_DBG_MSG_TYPE msg_type, int32_t msg_code, #if defined(WIN32) OutputDebugString(msg); -#else +#endif fputs(msg, stderr); fputc('\n', stderr); -#endif + } static bool has_extension(struct extension_property *exts, uint32_t count, -- cgit v1.2.3 From 358c4592b6205705a3aa0c0a44312050d397e6f1 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Tue, 5 May 2015 16:11:15 -0600 Subject: layers: Fix bug of GetGlobalExtensionInfo not being added to layer_intercept --- vk-layer-generate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/vk-layer-generate.py b/vk-layer-generate.py index cdd9be54..8e5967ef 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -308,6 +308,7 @@ class Subcommand(object): intercept = self._gen_layer_dbg_callback_unregister() elif 'GetGlobalExtensionInfo' == proto.name: funcs.append(self._gen_layer_get_global_extension_info(self.layer_name)) + intercepted.append(proto) if intercept is not None: funcs.append(intercept) intercepted.append(proto) -- cgit v1.2.3 From 8abcd57aee10259ad7066200383c0769bdb7e3f4 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Wed, 6 May 2015 09:02:10 -0600 Subject: loader: No longer generate code, instead directly check in source code --- loader/CMakeLists.txt | 21 +- loader/gpa_helper.h | 337 +++++++++++++++ loader/table_ops.h | 431 +++++++++++++++++++ loader/trampoline.c | 1149 +++++++++++++++++++++++++++++++++++++++++++++++++ loader/vulkan.def | 158 +++++++ 5 files changed, 2077 insertions(+), 19 deletions(-) create mode 100644 loader/gpa_helper.h create mode 100644 loader/table_ops.h create mode 100644 loader/trampoline.c create mode 100644 loader/vulkan.def diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 274bc4dc..9c1c2314 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -1,20 +1,3 @@ -add_custom_command(OUTPUT dispatch.c - COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py loader-entrypoints > dispatch.c - DEPENDS ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py - ${PROJECT_SOURCE_DIR}/include/vkIcd.h) - -add_custom_command(OUTPUT table_ops.h - COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py dispatch-table-ops loader > table_ops.h - DEPENDS ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py) - -add_custom_command(OUTPUT vulkan.def - COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py win-def-file vulkan all > vulkan.def - DEPENDS ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py) - -add_custom_command(OUTPUT gpa_helper.h - COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py loader-get-proc-addr loader > gpa_helper.h - DEPENDS ${PROJECT_SOURCE_DIR}/loader/vk-loader-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py) - include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} @@ -27,7 +10,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") if (WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -D_CRT_SECURE_NO_WARNINGS -DXCB_NVIDIA") - add_library(vulkan SHARED loader.c loader.h dirent_on_windows.c dispatch.c table_ops.h gpa_helper.h vulkan.def) + add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c table_ops.h gpa_helper.h vulkan.def) set_target_properties(vulkan PROPERTIES LINK_FLAGS "/DEF:${PROJECT_SOURCE_DIR}/loader/vulkan.def") add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c dispatch.c table_ops.h gpa_helper.h) set_target_properties(VKstatic PROPERTIES OUTPUT_NAME VKstatic) @@ -36,7 +19,7 @@ endif() if (NOT WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -Wpointer-arith") - add_library(vulkan SHARED loader.c dispatch.c table_ops.h gpa_helper.h) + add_library(vulkan SHARED loader.c trampoline.c loader.h loader_platform.h table_ops.h gpa_helper.h) set_target_properties(vulkan PROPERTIES SOVERSION 0) target_link_libraries(vulkan -ldl -lpthread) endif() diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h new file mode 100644 index 00000000..b2a6f311 --- /dev/null +++ b/loader/gpa_helper.h @@ -0,0 +1,337 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +static inline void* globalGetProcAddr(const char *name) +{ + if (!name || name[0] != 'v' || name[1] != 'k') + return NULL; + + name += 2; + if (!strcmp(name, "CreateInstance")) + return (void*) vkCreateInstance; + if (!strcmp(name, "DestroyInstance")) + return (void*) vkDestroyInstance; + if (!strcmp(name, "EnumeratePhysicalDevices")) + return (void*) vkEnumeratePhysicalDevices; + if (!strcmp(name, "GetPhysicalDeviceInfo")) + return (void*) vkGetPhysicalDeviceInfo; + if (!strcmp(name, "GetProcAddr")) + return (void*) vkGetProcAddr; + if (!strcmp(name, "CreateDevice")) + return (void*) vkCreateDevice; + if (!strcmp(name, "DestroyDevice")) + return (void*) vkDestroyDevice; + if (!strcmp(name, "GetGlobalExtensionInfo")) + return (void*) vkGetGlobalExtensionInfo; + if (!strcmp(name, "GetPhysicalDeviceExtensionInfo")) + return (void*) vkGetPhysicalDeviceExtensionInfo; + if (!strcmp(name, "EnumerateLayers")) + return (void*) vkEnumerateLayers; + if (!strcmp(name, "GetDeviceQueue")) + return (void*) vkGetDeviceQueue; + if (!strcmp(name, "QueueSubmit")) + return (void*) vkQueueSubmit; + if (!strcmp(name, "QueueWaitIdle")) + return (void*) vkQueueWaitIdle; + if (!strcmp(name, "DeviceWaitIdle")) + return (void*) vkDeviceWaitIdle; + if (!strcmp(name, "AllocMemory")) + return (void*) vkAllocMemory; + if (!strcmp(name, "FreeMemory")) + return (void*) vkFreeMemory; + if (!strcmp(name, "SetMemoryPriority")) + return (void*) vkSetMemoryPriority; + if (!strcmp(name, "MapMemory")) + return (void*) vkMapMemory; + if (!strcmp(name, "UnmapMemory")) + return (void*) vkUnmapMemory; + if (!strcmp(name, "FlushMappedMemoryRanges")) + return (void*) vkFlushMappedMemoryRanges; + if (!strcmp(name, "InvalidateMappedMemoryRanges")) + return (void*) vkInvalidateMappedMemoryRanges; + if (!strcmp(name, "PinSystemMemory")) + return (void*) vkPinSystemMemory; + if (!strcmp(name, "GetMultiDeviceCompatibility")) + return (void*) vkGetMultiDeviceCompatibility; + if (!strcmp(name, "OpenSharedMemory")) + return (void*) vkOpenSharedMemory; + if (!strcmp(name, "OpenSharedSemaphore")) + return (void*) vkOpenSharedSemaphore; + if (!strcmp(name, "OpenPeerMemory")) + return (void*) vkOpenPeerMemory; + if (!strcmp(name, "OpenPeerImage")) + return (void*) vkOpenPeerImage; + if (!strcmp(name, "DestroyObject")) + return (void*) vkDestroyObject; + if (!strcmp(name, "GetObjectInfo")) + return (void*) vkGetObjectInfo; + if (!strcmp(name, "QueueBindObjectMemory")) + return (void*) vkQueueBindObjectMemory; + if (!strcmp(name, "QueueBindObjectMemoryRange")) + return (void*) vkQueueBindObjectMemoryRange; + if (!strcmp(name, "QueueBindImageMemoryRange")) + return (void*) vkQueueBindImageMemoryRange; + if (!strcmp(name, "CreateFence")) + return (void*) vkCreateFence; + if (!strcmp(name, "ResetFences")) + return (void*) vkResetFences; + if (!strcmp(name, "GetFenceStatus")) + return (void*) vkGetFenceStatus; + if (!strcmp(name, "WaitForFences")) + return (void*) vkWaitForFences; + if (!strcmp(name, "CreateSemaphore")) + return (void*) vkCreateSemaphore; + if (!strcmp(name, "QueueSignalSemaphore")) + return (void*) vkQueueSignalSemaphore; + if (!strcmp(name, "QueueWaitSemaphore")) + return (void*) vkQueueWaitSemaphore; + if (!strcmp(name, "CreateEvent")) + return (void*) vkCreateEvent; + if (!strcmp(name, "GetEventStatus")) + return (void*) vkGetEventStatus; + if (!strcmp(name, "SetEvent")) + return (void*) vkSetEvent; + if (!strcmp(name, "ResetEvent")) + return (void*) vkResetEvent; + if (!strcmp(name, "CreateQueryPool")) + return (void*) vkCreateQueryPool; + if (!strcmp(name, "GetQueryPoolResults")) + return (void*) vkGetQueryPoolResults; + if (!strcmp(name, "GetFormatInfo")) + return (void*) vkGetFormatInfo; + if (!strcmp(name, "CreateBuffer")) + return (void*) vkCreateBuffer; + if (!strcmp(name, "CreateBufferView")) + return (void*) vkCreateBufferView; + if (!strcmp(name, "CreateImage")) + return (void*) vkCreateImage; + if (!strcmp(name, "GetImageSubresourceInfo")) + return (void*) vkGetImageSubresourceInfo; + if (!strcmp(name, "CreateImageView")) + return (void*) vkCreateImageView; + if (!strcmp(name, "CreateColorAttachmentView")) + return (void*) vkCreateColorAttachmentView; + if (!strcmp(name, "CreateDepthStencilView")) + return (void*) vkCreateDepthStencilView; + if (!strcmp(name, "CreateShader")) + return (void*) vkCreateShader; + if (!strcmp(name, "CreateGraphicsPipeline")) + return (void*) vkCreateGraphicsPipeline; + if (!strcmp(name, "CreateGraphicsPipelineDerivative")) + return (void*) vkCreateGraphicsPipelineDerivative; + if (!strcmp(name, "CreateComputePipeline")) + return (void*) vkCreateComputePipeline; + if (!strcmp(name, "StorePipeline")) + return (void*) vkStorePipeline; + if (!strcmp(name, "LoadPipeline")) + return (void*) vkLoadPipeline; + if (!strcmp(name, "LoadPipelineDerivative")) + return (void*) vkLoadPipelineDerivative; + if (!strcmp(name, "CreatePipelineLayout")) + return (void*) vkCreatePipelineLayout; + if (!strcmp(name, "CreateSampler")) + return (void*) vkCreateSampler; + if (!strcmp(name, "CreateDescriptorSetLayout")) + return (void*) vkCreateDescriptorSetLayout; + if (!strcmp(name, "BeginDescriptorPoolUpdate")) + return (void*) vkBeginDescriptorPoolUpdate; + if (!strcmp(name, "EndDescriptorPoolUpdate")) + return (void*) vkEndDescriptorPoolUpdate; + if (!strcmp(name, "CreateDescriptorPool")) + return (void*) vkCreateDescriptorPool; + if (!strcmp(name, "ResetDescriptorPool")) + return (void*) vkResetDescriptorPool; + if (!strcmp(name, "AllocDescriptorSets")) + return (void*) vkAllocDescriptorSets; + if (!strcmp(name, "ClearDescriptorSets")) + return (void*) vkClearDescriptorSets; + if (!strcmp(name, "UpdateDescriptors")) + return (void*) vkUpdateDescriptors; + if (!strcmp(name, "CreateDynamicViewportState")) + return (void*) vkCreateDynamicViewportState; + if (!strcmp(name, "CreateDynamicRasterState")) + return (void*) vkCreateDynamicRasterState; + if (!strcmp(name, "CreateDynamicColorBlendState")) + return (void*) vkCreateDynamicColorBlendState; + if (!strcmp(name, "CreateDynamicDepthStencilState")) + return (void*) vkCreateDynamicDepthStencilState; + if (!strcmp(name, "CreateCommandBuffer")) + return (void*) vkCreateCommandBuffer; + if (!strcmp(name, "BeginCommandBuffer")) + return (void*) vkBeginCommandBuffer; + if (!strcmp(name, "EndCommandBuffer")) + return (void*) vkEndCommandBuffer; + if (!strcmp(name, "ResetCommandBuffer")) + return (void*) vkResetCommandBuffer; + if (!strcmp(name, "CmdBindPipeline")) + return (void*) vkCmdBindPipeline; + if (!strcmp(name, "CmdBindDynamicStateObject")) + return (void*) vkCmdBindDynamicStateObject; + if (!strcmp(name, "CmdBindDescriptorSets")) + return (void*) vkCmdBindDescriptorSets; + if (!strcmp(name, "CmdBindVertexBuffers")) + return (void*) vkCmdBindVertexBuffers; + if (!strcmp(name, "CmdBindIndexBuffer")) + return (void*) vkCmdBindIndexBuffer; + if (!strcmp(name, "CmdDraw")) + return (void*) vkCmdDraw; + if (!strcmp(name, "CmdDrawIndexed")) + return (void*) vkCmdDrawIndexed; + if (!strcmp(name, "CmdDrawIndirect")) + return (void*) vkCmdDrawIndirect; + if (!strcmp(name, "CmdDrawIndexedIndirect")) + return (void*) vkCmdDrawIndexedIndirect; + if (!strcmp(name, "CmdDispatch")) + return (void*) vkCmdDispatch; + if (!strcmp(name, "CmdDispatchIndirect")) + return (void*) vkCmdDispatchIndirect; + if (!strcmp(name, "CmdCopyBuffer")) + return (void*) vkCmdCopyBuffer; + if (!strcmp(name, "CmdCopyImage")) + return (void*) vkCmdCopyImage; + if (!strcmp(name, "CmdBlitImage")) + return (void*) vkCmdBlitImage; + if (!strcmp(name, "CmdCopyBufferToImage")) + return (void*) vkCmdCopyBufferToImage; + if (!strcmp(name, "CmdCopyImageToBuffer")) + return (void*) vkCmdCopyImageToBuffer; + if (!strcmp(name, "CmdCloneImageData")) + return (void*) vkCmdCloneImageData; + if (!strcmp(name, "CmdUpdateBuffer")) + return (void*) vkCmdUpdateBuffer; + if (!strcmp(name, "CmdFillBuffer")) + return (void*) vkCmdFillBuffer; + if (!strcmp(name, "CmdClearColorImage")) + return (void*) vkCmdClearColorImage; + if (!strcmp(name, "CmdClearDepthStencil")) + return (void*) vkCmdClearDepthStencil; + if (!strcmp(name, "CmdResolveImage")) + return (void*) vkCmdResolveImage; + if (!strcmp(name, "CmdSetEvent")) + return (void*) vkCmdSetEvent; + if (!strcmp(name, "CmdResetEvent")) + return (void*) vkCmdResetEvent; + if (!strcmp(name, "CmdWaitEvents")) + return (void*) vkCmdWaitEvents; + if (!strcmp(name, "CmdPipelineBarrier")) + return (void*) vkCmdPipelineBarrier; + if (!strcmp(name, "CmdBeginQuery")) + return (void*) vkCmdBeginQuery; + if (!strcmp(name, "CmdEndQuery")) + return (void*) vkCmdEndQuery; + if (!strcmp(name, "CmdResetQueryPool")) + return (void*) vkCmdResetQueryPool; + if (!strcmp(name, "CmdWriteTimestamp")) + return (void*) vkCmdWriteTimestamp; + if (!strcmp(name, "CmdCopyQueryPoolResults")) + return (void*) vkCmdCopyQueryPoolResults; + if (!strcmp(name, "CmdInitAtomicCounters")) + return (void*) vkCmdInitAtomicCounters; + if (!strcmp(name, "CmdLoadAtomicCounters")) + return (void*) vkCmdLoadAtomicCounters; + if (!strcmp(name, "CmdSaveAtomicCounters")) + return (void*) vkCmdSaveAtomicCounters; + if (!strcmp(name, "CreateFramebuffer")) + return (void*) vkCreateFramebuffer; + if (!strcmp(name, "CreateRenderPass")) + return (void*) vkCreateRenderPass; + if (!strcmp(name, "CmdBeginRenderPass")) + return (void*) vkCmdBeginRenderPass; + if (!strcmp(name, "CmdEndRenderPass")) + return (void*) vkCmdEndRenderPass; + if (!strcmp(name, "DbgSetValidationLevel")) + return (void*) vkDbgSetValidationLevel; + if (!strcmp(name, "DbgRegisterMsgCallback")) + return (void*) vkDbgRegisterMsgCallback; + if (!strcmp(name, "DbgUnregisterMsgCallback")) + return (void*) vkDbgUnregisterMsgCallback; + if (!strcmp(name, "DbgSetMessageFilter")) + return (void*) vkDbgSetMessageFilter; + if (!strcmp(name, "DbgSetObjectTag")) + return (void*) vkDbgSetObjectTag; + if (!strcmp(name, "DbgSetGlobalOption")) + return (void*) vkDbgSetGlobalOption; + if (!strcmp(name, "DbgSetDeviceOption")) + return (void*) vkDbgSetDeviceOption; + if (!strcmp(name, "CmdDbgMarkerBegin")) + return (void*) vkCmdDbgMarkerBegin; + if (!strcmp(name, "CmdDbgMarkerEnd")) + return (void*) vkCmdDbgMarkerEnd; + if (!strcmp(name, "GetDisplayInfoWSI")) + return (void*) vkGetDisplayInfoWSI; + if (!strcmp(name, "CreateSwapChainWSI")) + return (void*) vkCreateSwapChainWSI; + if (!strcmp(name, "DestroySwapChainWSI")) + return (void*) vkDestroySwapChainWSI; + if (!strcmp(name, "GetSwapChainInfoWSI")) + return (void*) vkGetSwapChainInfoWSI; + if (!strcmp(name, "QueuePresentWSI")) + return (void*) vkQueuePresentWSI; + + return NULL; +} + +/* These functions require special handling by the loader. +* They are not just generic trampoline code entrypoints. +* Thus GPA must return loader entrypoint for these instead of first function +* in the chain. */ +static inline void *loader_non_passthrough_gpa(const char *name) +{ + if (!name || name[0] != 'v' || name[1] != 'k') + return NULL; + + name += 2; + if (!strcmp(name, "CreateInstance")) + return (void*) vkCreateInstance; + if (!strcmp(name, "DestroyInstance")) + return (void*) vkDestroyInstance; + if (!strcmp(name, "EnumeratePhysicalDevices")) + return (void*) vkEnumeratePhysicalDevices; + if (!strcmp(name, "GetPhysicalDeviceInfo")) + return (void*) vkGetPhysicalDeviceInfo; + if (!strcmp(name, "GetProcAddr")) + return (void*) vkGetProcAddr; + if (!strcmp(name, "CreateDevice")) + return (void*) vkCreateDevice; + if (!strcmp(name, "GetGlobalExtensionInfo")) + return (void*) vkGetGlobalExtensionInfo; + if (!strcmp(name, "EnumerateLayers")) + return (void*) vkEnumerateLayers; + if (!strcmp(name, "GetDeviceQueue")) + return (void*) vkGetDeviceQueue; + if (!strcmp(name, "CreateCommandBuffer")) + return (void*) vkCreateCommandBuffer; + if (!strcmp(name, "DbgRegisterMsgCallback")) + return (void*) vkDbgRegisterMsgCallback; + if (!strcmp(name, "DbgUnregisterMsgCallback")) + return (void*) vkDbgUnregisterMsgCallback; + if (!strcmp(name, "DbgSetGlobalOption")) + return (void*) vkDbgSetGlobalOption; + if (!strcmp(name, "CreateSwapChainWSI")) + return (void*) vkCreateSwapChainWSI; + + return NULL; +} diff --git a/loader/table_ops.h b/loader/table_ops.h new file mode 100644 index 00000000..3a3535d2 --- /dev/null +++ b/loader/table_ops.h @@ -0,0 +1,431 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "loader_platform.h" + +static inline void loader_initialize_dispatch_table(VkLayerDispatchTable *table, + PFN_vkGetProcAddr gpa, + VkPhysicalDevice gpu) +{ + table->CreateInstance = (PFN_vkCreateInstance) gpa(gpu, "vkCreateInstance"); + table->DestroyInstance = (PFN_vkDestroyInstance) gpa(gpu, "vkDestroyInstance"); + table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(gpu, "vkEnumeratePhysicalDevices"); + table->GetPhysicalDeviceInfo = (PFN_vkGetPhysicalDeviceInfo) gpa(gpu, "vkGetPhysicalDeviceInfo"); + table->GetProcAddr = (PFN_vkGetProcAddr) gpa(gpu, "vkGetProcAddr"); + table->CreateDevice = (PFN_vkCreateDevice) gpa(gpu, "vkCreateDevice"); + table->DestroyDevice = (PFN_vkDestroyDevice) gpa(gpu, "vkDestroyDevice"); + table->GetGlobalExtensionInfo = vkGetGlobalExtensionInfo; /* non-dispatchable */ + table->GetPhysicalDeviceExtensionInfo = (PFN_vkGetPhysicalDeviceExtensionInfo) gpa(gpu, "vkGetPhysicalDeviceExtensionInfo"); + table->EnumerateLayers = (PFN_vkEnumerateLayers) gpa(gpu, "vkEnumerateLayers"); + table->GetDeviceQueue = (PFN_vkGetDeviceQueue) gpa(gpu, "vkGetDeviceQueue"); + table->QueueSubmit = (PFN_vkQueueSubmit) gpa(gpu, "vkQueueSubmit"); + table->QueueWaitIdle = (PFN_vkQueueWaitIdle) gpa(gpu, "vkQueueWaitIdle"); + table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle) gpa(gpu, "vkDeviceWaitIdle"); + table->AllocMemory = (PFN_vkAllocMemory) gpa(gpu, "vkAllocMemory"); + table->FreeMemory = (PFN_vkFreeMemory) gpa(gpu, "vkFreeMemory"); + table->SetMemoryPriority = (PFN_vkSetMemoryPriority) gpa(gpu, "vkSetMemoryPriority"); + table->MapMemory = (PFN_vkMapMemory) gpa(gpu, "vkMapMemory"); + table->UnmapMemory = (PFN_vkUnmapMemory) gpa(gpu, "vkUnmapMemory"); + table->FlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) gpa(gpu, "vkFlushMappedMemoryRanges"); + table->InvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) gpa(gpu, "vkInvalidateMappedMemoryRanges"); + table->PinSystemMemory = (PFN_vkPinSystemMemory) gpa(gpu, "vkPinSystemMemory"); + table->GetMultiDeviceCompatibility = (PFN_vkGetMultiDeviceCompatibility) gpa(gpu, "vkGetMultiDeviceCompatibility"); + table->OpenSharedMemory = (PFN_vkOpenSharedMemory) gpa(gpu, "vkOpenSharedMemory"); + table->OpenSharedSemaphore = (PFN_vkOpenSharedSemaphore) gpa(gpu, "vkOpenSharedSemaphore"); + table->OpenPeerMemory = (PFN_vkOpenPeerMemory) gpa(gpu, "vkOpenPeerMemory"); + table->OpenPeerImage = (PFN_vkOpenPeerImage) gpa(gpu, "vkOpenPeerImage"); + table->DestroyObject = (PFN_vkDestroyObject) gpa(gpu, "vkDestroyObject"); + table->GetObjectInfo = (PFN_vkGetObjectInfo) gpa(gpu, "vkGetObjectInfo"); + table->QueueBindObjectMemory = (PFN_vkQueueBindObjectMemory) gpa(gpu, "vkQueueBindObjectMemory"); + table->QueueBindObjectMemoryRange = (PFN_vkQueueBindObjectMemoryRange) gpa(gpu, "vkQueueBindObjectMemoryRange"); + table->QueueBindImageMemoryRange = (PFN_vkQueueBindImageMemoryRange) gpa(gpu, "vkQueueBindImageMemoryRange"); + table->CreateFence = (PFN_vkCreateFence) gpa(gpu, "vkCreateFence"); + table->ResetFences = (PFN_vkResetFences) gpa(gpu, "vkResetFences"); + table->GetFenceStatus = (PFN_vkGetFenceStatus) gpa(gpu, "vkGetFenceStatus"); + table->WaitForFences = (PFN_vkWaitForFences) gpa(gpu, "vkWaitForFences"); + table->CreateSemaphore = (PFN_vkCreateSemaphore) gpa(gpu, "vkCreateSemaphore"); + table->QueueSignalSemaphore = (PFN_vkQueueSignalSemaphore) gpa(gpu, "vkQueueSignalSemaphore"); + table->QueueWaitSemaphore = (PFN_vkQueueWaitSemaphore) gpa(gpu, "vkQueueWaitSemaphore"); + table->CreateEvent = (PFN_vkCreateEvent) gpa(gpu, "vkCreateEvent"); + table->GetEventStatus = (PFN_vkGetEventStatus) gpa(gpu, "vkGetEventStatus"); + table->SetEvent = (PFN_vkSetEvent) gpa(gpu, "vkSetEvent"); + table->ResetEvent = (PFN_vkResetEvent) gpa(gpu, "vkResetEvent"); + table->CreateQueryPool = (PFN_vkCreateQueryPool) gpa(gpu, "vkCreateQueryPool"); + table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults) gpa(gpu, "vkGetQueryPoolResults"); + table->GetFormatInfo = (PFN_vkGetFormatInfo) gpa(gpu, "vkGetFormatInfo"); + table->CreateBuffer = (PFN_vkCreateBuffer) gpa(gpu, "vkCreateBuffer"); + table->CreateBufferView = (PFN_vkCreateBufferView) gpa(gpu, "vkCreateBufferView"); + table->CreateImage = (PFN_vkCreateImage) gpa(gpu, "vkCreateImage"); + table->GetImageSubresourceInfo = (PFN_vkGetImageSubresourceInfo) gpa(gpu, "vkGetImageSubresourceInfo"); + table->CreateImageView = (PFN_vkCreateImageView) gpa(gpu, "vkCreateImageView"); + table->CreateColorAttachmentView = (PFN_vkCreateColorAttachmentView) gpa(gpu, "vkCreateColorAttachmentView"); + table->CreateDepthStencilView = (PFN_vkCreateDepthStencilView) gpa(gpu, "vkCreateDepthStencilView"); + table->CreateShader = (PFN_vkCreateShader) gpa(gpu, "vkCreateShader"); + table->CreateGraphicsPipeline = (PFN_vkCreateGraphicsPipeline) gpa(gpu, "vkCreateGraphicsPipeline"); + table->CreateGraphicsPipelineDerivative = (PFN_vkCreateGraphicsPipelineDerivative) gpa(gpu, "vkCreateGraphicsPipelineDerivative"); + table->CreateComputePipeline = (PFN_vkCreateComputePipeline) gpa(gpu, "vkCreateComputePipeline"); + table->StorePipeline = (PFN_vkStorePipeline) gpa(gpu, "vkStorePipeline"); + table->LoadPipeline = (PFN_vkLoadPipeline) gpa(gpu, "vkLoadPipeline"); + table->LoadPipelineDerivative = (PFN_vkLoadPipelineDerivative) gpa(gpu, "vkLoadPipelineDerivative"); + table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout) gpa(gpu, "vkCreatePipelineLayout"); + table->CreateSampler = (PFN_vkCreateSampler) gpa(gpu, "vkCreateSampler"); + table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) gpa(gpu, "vkCreateDescriptorSetLayout"); + table->BeginDescriptorPoolUpdate = (PFN_vkBeginDescriptorPoolUpdate) gpa(gpu, "vkBeginDescriptorPoolUpdate"); + table->EndDescriptorPoolUpdate = (PFN_vkEndDescriptorPoolUpdate) gpa(gpu, "vkEndDescriptorPoolUpdate"); + table->CreateDescriptorPool = (PFN_vkCreateDescriptorPool) gpa(gpu, "vkCreateDescriptorPool"); + table->ResetDescriptorPool = (PFN_vkResetDescriptorPool) gpa(gpu, "vkResetDescriptorPool"); + table->AllocDescriptorSets = (PFN_vkAllocDescriptorSets) gpa(gpu, "vkAllocDescriptorSets"); + table->ClearDescriptorSets = (PFN_vkClearDescriptorSets) gpa(gpu, "vkClearDescriptorSets"); + table->UpdateDescriptors = (PFN_vkUpdateDescriptors) gpa(gpu, "vkUpdateDescriptors"); + table->CreateDynamicViewportState = (PFN_vkCreateDynamicViewportState) gpa(gpu, "vkCreateDynamicViewportState"); + table->CreateDynamicRasterState = (PFN_vkCreateDynamicRasterState) gpa(gpu, "vkCreateDynamicRasterState"); + table->CreateDynamicColorBlendState = (PFN_vkCreateDynamicColorBlendState) gpa(gpu, "vkCreateDynamicColorBlendState"); + table->CreateDynamicDepthStencilState = (PFN_vkCreateDynamicDepthStencilState) gpa(gpu, "vkCreateDynamicDepthStencilState"); + table->CreateCommandBuffer = (PFN_vkCreateCommandBuffer) gpa(gpu, "vkCreateCommandBuffer"); + table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer) gpa(gpu, "vkBeginCommandBuffer"); + table->EndCommandBuffer = (PFN_vkEndCommandBuffer) gpa(gpu, "vkEndCommandBuffer"); + table->ResetCommandBuffer = (PFN_vkResetCommandBuffer) gpa(gpu, "vkResetCommandBuffer"); + table->CmdBindPipeline = (PFN_vkCmdBindPipeline) gpa(gpu, "vkCmdBindPipeline"); + table->CmdBindDynamicStateObject = (PFN_vkCmdBindDynamicStateObject) gpa(gpu, "vkCmdBindDynamicStateObject"); + table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) gpa(gpu, "vkCmdBindDescriptorSets"); + table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) gpa(gpu, "vkCmdBindVertexBuffers"); + table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) gpa(gpu, "vkCmdBindIndexBuffer"); + table->CmdDraw = (PFN_vkCmdDraw) gpa(gpu, "vkCmdDraw"); + table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed) gpa(gpu, "vkCmdDrawIndexed"); + table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect) gpa(gpu, "vkCmdDrawIndirect"); + table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) gpa(gpu, "vkCmdDrawIndexedIndirect"); + table->CmdDispatch = (PFN_vkCmdDispatch) gpa(gpu, "vkCmdDispatch"); + table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) gpa(gpu, "vkCmdDispatchIndirect"); + table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer) gpa(gpu, "vkCmdCopyBuffer"); + table->CmdCopyImage = (PFN_vkCmdCopyImage) gpa(gpu, "vkCmdCopyImage"); + table->CmdBlitImage = (PFN_vkCmdBlitImage) gpa(gpu, "vkCmdBlitImage"); + table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) gpa(gpu, "vkCmdCopyBufferToImage"); + table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) gpa(gpu, "vkCmdCopyImageToBuffer"); + table->CmdCloneImageData = (PFN_vkCmdCloneImageData) gpa(gpu, "vkCmdCloneImageData"); + table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) gpa(gpu, "vkCmdUpdateBuffer"); + table->CmdFillBuffer = (PFN_vkCmdFillBuffer) gpa(gpu, "vkCmdFillBuffer"); + table->CmdClearColorImage = (PFN_vkCmdClearColorImage) gpa(gpu, "vkCmdClearColorImage"); + table->CmdClearDepthStencil = (PFN_vkCmdClearDepthStencil) gpa(gpu, "vkCmdClearDepthStencil"); + table->CmdResolveImage = (PFN_vkCmdResolveImage) gpa(gpu, "vkCmdResolveImage"); + table->CmdSetEvent = (PFN_vkCmdSetEvent) gpa(gpu, "vkCmdSetEvent"); + table->CmdResetEvent = (PFN_vkCmdResetEvent) gpa(gpu, "vkCmdResetEvent"); + table->CmdWaitEvents = (PFN_vkCmdWaitEvents) gpa(gpu, "vkCmdWaitEvents"); + table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) gpa(gpu, "vkCmdPipelineBarrier"); + table->CmdBeginQuery = (PFN_vkCmdBeginQuery) gpa(gpu, "vkCmdBeginQuery"); + table->CmdEndQuery = (PFN_vkCmdEndQuery) gpa(gpu, "vkCmdEndQuery"); + table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool) gpa(gpu, "vkCmdResetQueryPool"); + table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) gpa(gpu, "vkCmdWriteTimestamp"); + table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) gpa(gpu, "vkCmdCopyQueryPoolResults"); + table->CmdInitAtomicCounters = (PFN_vkCmdInitAtomicCounters) gpa(gpu, "vkCmdInitAtomicCounters"); + table->CmdLoadAtomicCounters = (PFN_vkCmdLoadAtomicCounters) gpa(gpu, "vkCmdLoadAtomicCounters"); + table->CmdSaveAtomicCounters = (PFN_vkCmdSaveAtomicCounters) gpa(gpu, "vkCmdSaveAtomicCounters"); + table->CreateFramebuffer = (PFN_vkCreateFramebuffer) gpa(gpu, "vkCreateFramebuffer"); + table->CreateRenderPass = (PFN_vkCreateRenderPass) gpa(gpu, "vkCreateRenderPass"); + table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) gpa(gpu, "vkCmdBeginRenderPass"); + table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass) gpa(gpu, "vkCmdEndRenderPass"); + table->DbgSetValidationLevel = (PFN_vkDbgSetValidationLevel) gpa(gpu, "vkDbgSetValidationLevel"); + table->DbgRegisterMsgCallback = (PFN_vkDbgRegisterMsgCallback) gpa(gpu, "vkDbgRegisterMsgCallback"); + table->DbgUnregisterMsgCallback = (PFN_vkDbgUnregisterMsgCallback) gpa(gpu, "vkDbgUnregisterMsgCallback"); + table->DbgSetMessageFilter = (PFN_vkDbgSetMessageFilter) gpa(gpu, "vkDbgSetMessageFilter"); + table->DbgSetObjectTag = (PFN_vkDbgSetObjectTag) gpa(gpu, "vkDbgSetObjectTag"); + table->DbgSetGlobalOption = (PFN_vkDbgSetGlobalOption) gpa(gpu, "vkDbgSetGlobalOption"); + table->DbgSetDeviceOption = (PFN_vkDbgSetDeviceOption) gpa(gpu, "vkDbgSetDeviceOption"); + table->CmdDbgMarkerBegin = (PFN_vkCmdDbgMarkerBegin) gpa(gpu, "vkCmdDbgMarkerBegin"); + table->CmdDbgMarkerEnd = (PFN_vkCmdDbgMarkerEnd) gpa(gpu, "vkCmdDbgMarkerEnd"); + table->GetDisplayInfoWSI = (PFN_vkGetDisplayInfoWSI) gpa(gpu, "vkGetDisplayInfoWSI"); + table->CreateSwapChainWSI = (PFN_vkCreateSwapChainWSI) gpa(gpu, "vkCreateSwapChainWSI"); + table->DestroySwapChainWSI = (PFN_vkDestroySwapChainWSI) gpa(gpu, "vkDestroySwapChainWSI"); + table->GetSwapChainInfoWSI = (PFN_vkGetSwapChainInfoWSI) gpa(gpu, "vkGetSwapChainInfoWSI"); + table->QueuePresentWSI = (PFN_vkQueuePresentWSI) gpa(gpu, "vkQueuePresentWSI"); +} + +static inline void *loader_lookup_dispatch_table(const VkLayerDispatchTable *table, + const char *name) +{ + if (!name || name[0] != 'v' || name[1] != 'k') + return NULL; + + name += 2; + if (!strcmp(name, "DestroyInstance")) + return (void *) table->DestroyInstance; + if (!strcmp(name, "EnumeratePhysicalDevices")) + return (void *) table->EnumeratePhysicalDevices; + if (!strcmp(name, "GetPhysicalDeviceInfo")) + return (void *) table->GetPhysicalDeviceInfo; + if (!strcmp(name, "GetProcAddr")) + return (void *) table->GetProcAddr; + if (!strcmp(name, "CreateDevice")) + return (void *) table->CreateDevice; + if (!strcmp(name, "DestroyDevice")) + return (void *) table->DestroyDevice; + if (!strcmp(name, "GetPhysicalDeviceExtensionInfo")) + return (void *) table->GetPhysicalDeviceExtensionInfo; + if (!strcmp(name, "EnumerateLayers")) + return (void *) table->EnumerateLayers; + if (!strcmp(name, "GetDeviceQueue")) + return (void *) table->GetDeviceQueue; + if (!strcmp(name, "QueueSubmit")) + return (void *) table->QueueSubmit; + if (!strcmp(name, "QueueWaitIdle")) + return (void *) table->QueueWaitIdle; + if (!strcmp(name, "DeviceWaitIdle")) + return (void *) table->DeviceWaitIdle; + if (!strcmp(name, "AllocMemory")) + return (void *) table->AllocMemory; + if (!strcmp(name, "FreeMemory")) + return (void *) table->FreeMemory; + if (!strcmp(name, "SetMemoryPriority")) + return (void *) table->SetMemoryPriority; + if (!strcmp(name, "MapMemory")) + return (void *) table->MapMemory; + if (!strcmp(name, "UnmapMemory")) + return (void *) table->UnmapMemory; + if (!strcmp(name, "FlushMappedMemoryRanges")) + return (void *) table->FlushMappedMemoryRanges; + if (!strcmp(name, "InvalidateMappedMemoryRanges")) + return (void *) table->InvalidateMappedMemoryRanges; + if (!strcmp(name, "PinSystemMemory")) + return (void *) table->PinSystemMemory; + if (!strcmp(name, "GetMultiDeviceCompatibility")) + return (void *) table->GetMultiDeviceCompatibility; + if (!strcmp(name, "OpenSharedMemory")) + return (void *) table->OpenSharedMemory; + if (!strcmp(name, "OpenSharedSemaphore")) + return (void *) table->OpenSharedSemaphore; + if (!strcmp(name, "OpenPeerMemory")) + return (void *) table->OpenPeerMemory; + if (!strcmp(name, "OpenPeerImage")) + return (void *) table->OpenPeerImage; + if (!strcmp(name, "DestroyObject")) + return (void *) table->DestroyObject; + if (!strcmp(name, "GetObjectInfo")) + return (void *) table->GetObjectInfo; + if (!strcmp(name, "QueueBindObjectMemory")) + return (void *) table->QueueBindObjectMemory; + if (!strcmp(name, "QueueBindObjectMemoryRange")) + return (void *) table->QueueBindObjectMemoryRange; + if (!strcmp(name, "QueueBindImageMemoryRange")) + return (void *) table->QueueBindImageMemoryRange; + if (!strcmp(name, "CreateFence")) + return (void *) table->CreateFence; + if (!strcmp(name, "ResetFences")) + return (void *) table->ResetFences; + if (!strcmp(name, "GetFenceStatus")) + return (void *) table->GetFenceStatus; + if (!strcmp(name, "WaitForFences")) + return (void *) table->WaitForFences; + if (!strcmp(name, "CreateSemaphore")) + return (void *) table->CreateSemaphore; + if (!strcmp(name, "QueueSignalSemaphore")) + return (void *) table->QueueSignalSemaphore; + if (!strcmp(name, "QueueWaitSemaphore")) + return (void *) table->QueueWaitSemaphore; + if (!strcmp(name, "CreateEvent")) + return (void *) table->CreateEvent; + if (!strcmp(name, "GetEventStatus")) + return (void *) table->GetEventStatus; + if (!strcmp(name, "SetEvent")) + return (void *) table->SetEvent; + if (!strcmp(name, "ResetEvent")) + return (void *) table->ResetEvent; + if (!strcmp(name, "CreateQueryPool")) + return (void *) table->CreateQueryPool; + if (!strcmp(name, "GetQueryPoolResults")) + return (void *) table->GetQueryPoolResults; + if (!strcmp(name, "GetFormatInfo")) + return (void *) table->GetFormatInfo; + if (!strcmp(name, "CreateBuffer")) + return (void *) table->CreateBuffer; + if (!strcmp(name, "CreateBufferView")) + return (void *) table->CreateBufferView; + if (!strcmp(name, "CreateImage")) + return (void *) table->CreateImage; + if (!strcmp(name, "GetImageSubresourceInfo")) + return (void *) table->GetImageSubresourceInfo; + if (!strcmp(name, "CreateImageView")) + return (void *) table->CreateImageView; + if (!strcmp(name, "CreateColorAttachmentView")) + return (void *) table->CreateColorAttachmentView; + if (!strcmp(name, "CreateDepthStencilView")) + return (void *) table->CreateDepthStencilView; + if (!strcmp(name, "CreateShader")) + return (void *) table->CreateShader; + if (!strcmp(name, "CreateGraphicsPipeline")) + return (void *) table->CreateGraphicsPipeline; + if (!strcmp(name, "CreateGraphicsPipelineDerivative")) + return (void *) table->CreateGraphicsPipelineDerivative; + if (!strcmp(name, "CreateComputePipeline")) + return (void *) table->CreateComputePipeline; + if (!strcmp(name, "StorePipeline")) + return (void *) table->StorePipeline; + if (!strcmp(name, "LoadPipeline")) + return (void *) table->LoadPipeline; + if (!strcmp(name, "LoadPipelineDerivative")) + return (void *) table->LoadPipelineDerivative; + if (!strcmp(name, "CreatePipelineLayout")) + return (void *) table->CreatePipelineLayout; + if (!strcmp(name, "CreateSampler")) + return (void *) table->CreateSampler; + if (!strcmp(name, "CreateDescriptorSetLayout")) + return (void *) table->CreateDescriptorSetLayout; + if (!strcmp(name, "BeginDescriptorPoolUpdate")) + return (void *) table->BeginDescriptorPoolUpdate; + if (!strcmp(name, "EndDescriptorPoolUpdate")) + return (void *) table->EndDescriptorPoolUpdate; + if (!strcmp(name, "CreateDescriptorPool")) + return (void *) table->CreateDescriptorPool; + if (!strcmp(name, "ResetDescriptorPool")) + return (void *) table->ResetDescriptorPool; + if (!strcmp(name, "AllocDescriptorSets")) + return (void *) table->AllocDescriptorSets; + if (!strcmp(name, "ClearDescriptorSets")) + return (void *) table->ClearDescriptorSets; + if (!strcmp(name, "UpdateDescriptors")) + return (void *) table->UpdateDescriptors; + if (!strcmp(name, "CreateDynamicViewportState")) + return (void *) table->CreateDynamicViewportState; + if (!strcmp(name, "CreateDynamicRasterState")) + return (void *) table->CreateDynamicRasterState; + if (!strcmp(name, "CreateDynamicColorBlendState")) + return (void *) table->CreateDynamicColorBlendState; + if (!strcmp(name, "CreateDynamicDepthStencilState")) + return (void *) table->CreateDynamicDepthStencilState; + if (!strcmp(name, "CreateCommandBuffer")) + return (void *) table->CreateCommandBuffer; + if (!strcmp(name, "BeginCommandBuffer")) + return (void *) table->BeginCommandBuffer; + if (!strcmp(name, "EndCommandBuffer")) + return (void *) table->EndCommandBuffer; + if (!strcmp(name, "ResetCommandBuffer")) + return (void *) table->ResetCommandBuffer; + if (!strcmp(name, "CmdBindPipeline")) + return (void *) table->CmdBindPipeline; + if (!strcmp(name, "CmdBindDynamicStateObject")) + return (void *) table->CmdBindDynamicStateObject; + if (!strcmp(name, "CmdBindDescriptorSets")) + return (void *) table->CmdBindDescriptorSets; + if (!strcmp(name, "CmdBindVertexBuffers")) + return (void *) table->CmdBindVertexBuffers; + if (!strcmp(name, "CmdBindIndexBuffer")) + return (void *) table->CmdBindIndexBuffer; + if (!strcmp(name, "CmdDraw")) + return (void *) table->CmdDraw; + if (!strcmp(name, "CmdDrawIndexed")) + return (void *) table->CmdDrawIndexed; + if (!strcmp(name, "CmdDrawIndirect")) + return (void *) table->CmdDrawIndirect; + if (!strcmp(name, "CmdDrawIndexedIndirect")) + return (void *) table->CmdDrawIndexedIndirect; + if (!strcmp(name, "CmdDispatch")) + return (void *) table->CmdDispatch; + if (!strcmp(name, "CmdDispatchIndirect")) + return (void *) table->CmdDispatchIndirect; + if (!strcmp(name, "CmdCopyBuffer")) + return (void *) table->CmdCopyBuffer; + if (!strcmp(name, "CmdCopyImage")) + return (void *) table->CmdCopyImage; + if (!strcmp(name, "CmdBlitImage")) + return (void *) table->CmdBlitImage; + if (!strcmp(name, "CmdCopyBufferToImage")) + return (void *) table->CmdCopyBufferToImage; + if (!strcmp(name, "CmdCopyImageToBuffer")) + return (void *) table->CmdCopyImageToBuffer; + if (!strcmp(name, "CmdCloneImageData")) + return (void *) table->CmdCloneImageData; + if (!strcmp(name, "CmdUpdateBuffer")) + return (void *) table->CmdUpdateBuffer; + if (!strcmp(name, "CmdFillBuffer")) + return (void *) table->CmdFillBuffer; + if (!strcmp(name, "CmdClearColorImage")) + return (void *) table->CmdClearColorImage; + if (!strcmp(name, "CmdClearDepthStencil")) + return (void *) table->CmdClearDepthStencil; + if (!strcmp(name, "CmdResolveImage")) + return (void *) table->CmdResolveImage; + if (!strcmp(name, "CmdSetEvent")) + return (void *) table->CmdSetEvent; + if (!strcmp(name, "CmdResetEvent")) + return (void *) table->CmdResetEvent; + if (!strcmp(name, "CmdWaitEvents")) + return (void *) table->CmdWaitEvents; + if (!strcmp(name, "CmdPipelineBarrier")) + return (void *) table->CmdPipelineBarrier; + if (!strcmp(name, "CmdBeginQuery")) + return (void *) table->CmdBeginQuery; + if (!strcmp(name, "CmdEndQuery")) + return (void *) table->CmdEndQuery; + if (!strcmp(name, "CmdResetQueryPool")) + return (void *) table->CmdResetQueryPool; + if (!strcmp(name, "CmdWriteTimestamp")) + return (void *) table->CmdWriteTimestamp; + if (!strcmp(name, "CmdCopyQueryPoolResults")) + return (void *) table->CmdCopyQueryPoolResults; + if (!strcmp(name, "CmdInitAtomicCounters")) + return (void *) table->CmdInitAtomicCounters; + if (!strcmp(name, "CmdLoadAtomicCounters")) + return (void *) table->CmdLoadAtomicCounters; + if (!strcmp(name, "CmdSaveAtomicCounters")) + return (void *) table->CmdSaveAtomicCounters; + if (!strcmp(name, "CreateFramebuffer")) + return (void *) table->CreateFramebuffer; + if (!strcmp(name, "CreateRenderPass")) + return (void *) table->CreateRenderPass; + if (!strcmp(name, "CmdBeginRenderPass")) + return (void *) table->CmdBeginRenderPass; + if (!strcmp(name, "CmdEndRenderPass")) + return (void *) table->CmdEndRenderPass; + if (!strcmp(name, "DbgSetValidationLevel")) + return (void *) table->DbgSetValidationLevel; + if (!strcmp(name, "DbgRegisterMsgCallback")) + return (void *) table->DbgRegisterMsgCallback; + if (!strcmp(name, "DbgUnregisterMsgCallback")) + return (void *) table->DbgUnregisterMsgCallback; + if (!strcmp(name, "DbgSetMessageFilter")) + return (void *) table->DbgSetMessageFilter; + if (!strcmp(name, "DbgSetObjectTag")) + return (void *) table->DbgSetObjectTag; + if (!strcmp(name, "DbgSetGlobalOption")) + return (void *) table->DbgSetGlobalOption; + if (!strcmp(name, "DbgSetDeviceOption")) + return (void *) table->DbgSetDeviceOption; + if (!strcmp(name, "CmdDbgMarkerBegin")) + return (void *) table->CmdDbgMarkerBegin; + if (!strcmp(name, "CmdDbgMarkerEnd")) + return (void *) table->CmdDbgMarkerEnd; + if (!strcmp(name, "GetDisplayInfoWSI")) + return (void *) table->GetDisplayInfoWSI; + if (!strcmp(name, "CreateSwapChainWSI")) + return (void *) table->CreateSwapChainWSI; + if (!strcmp(name, "DestroySwapChainWSI")) + return (void *) table->DestroySwapChainWSI; + if (!strcmp(name, "GetSwapChainInfoWSI")) + return (void *) table->GetSwapChainInfoWSI; + if (!strcmp(name, "QueuePresentWSI")) + return (void *) table->QueuePresentWSI; + + return NULL; +} diff --git a/loader/trampoline.c b/loader/trampoline.c new file mode 100644 index 00000000..a435ca1f --- /dev/null +++ b/loader/trampoline.c @@ -0,0 +1,1149 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "loader.h" + +/* Trampoline entrypoints */ +LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo(VkPhysicalDevice gpu, VkPhysicalDeviceInfoType infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + VkResult res; + + disp = loader_get_dispatch(gpu); + + res = disp->GetPhysicalDeviceInfo(gpu, infoType, pDataSize, pData); + if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI && pData && res == VK_SUCCESS) { + VkDisplayPropertiesWSI *info = pData; + size_t count = *pDataSize / sizeof(*info), i; + for (i = 0; i < count; i++) { + loader_set_dispatch(info[i].display, disp); + } + } + + return res; +} + +LOADER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice) +{ + const VkLayerDispatchTable *disp; + VkResult res; + + disp = loader_get_dispatch(gpu); + + res = disp->CreateDevice(gpu, pCreateInfo, pDevice); + if (res == VK_SUCCESS) { + loader_init_dispatch(*pDevice, disp); + } + + return res; +} + +LOADER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DestroyDevice(device); +} + +LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo(VkPhysicalDevice gpu, VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(gpu); + + return disp->GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue) +{ + const VkLayerDispatchTable *disp; + VkResult res; + + disp = loader_get_dispatch(device); + + res = disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue); + if (res == VK_SUCCESS) { + loader_set_dispatch(*pQueue, disp); + } + + return res; +} + +LOADER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence); +} + +LOADER_EXPORT VkResult VKAPI vkQueueWaitIdle(VkQueue queue) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueWaitIdle(queue); +} + +LOADER_EXPORT VkResult VKAPI vkDeviceWaitIdle(VkDevice device) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DeviceWaitIdle(device); +} + +LOADER_EXPORT VkResult VKAPI vkAllocMemory(VkDevice device, const VkMemoryAllocInfo* pAllocInfo, VkDeviceMemory* pMem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->AllocMemory(device, pAllocInfo, pMem); +} + +LOADER_EXPORT VkResult VKAPI vkFreeMemory(VkDevice device, VkDeviceMemory mem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->FreeMemory(device, mem); +} + +LOADER_EXPORT VkResult VKAPI vkSetMemoryPriority(VkDevice device, VkDeviceMemory mem, VkMemoryPriority priority) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->SetMemoryPriority(device, mem, priority); +} + +LOADER_EXPORT VkResult VKAPI vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, void** ppData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->MapMemory(device, mem, offset, size, flags, ppData); +} + +LOADER_EXPORT VkResult VKAPI vkUnmapMemory(VkDevice device, VkDeviceMemory mem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->UnmapMemory(device, mem); +} + +LOADER_EXPORT VkResult VKAPI vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges); +} + +LOADER_EXPORT VkResult VKAPI vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges); +} + +LOADER_EXPORT VkResult VKAPI vkPinSystemMemory(VkDevice device, const void* pSysMem, size_t memSize, VkDeviceMemory* pMem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->PinSystemMemory(device, pSysMem, memSize, pMem); +} + +LOADER_EXPORT VkResult VKAPI vkGetMultiDeviceCompatibility(VkPhysicalDevice gpu0, VkPhysicalDevice gpu1, VkPhysicalDeviceCompatibilityInfo* pInfo) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(gpu0); + + return disp->GetMultiDeviceCompatibility(gpu0, gpu1, pInfo); +} + +LOADER_EXPORT VkResult VKAPI vkOpenSharedMemory(VkDevice device, const VkMemoryOpenInfo* pOpenInfo, VkDeviceMemory* pMem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->OpenSharedMemory(device, pOpenInfo, pMem); +} + +LOADER_EXPORT VkResult VKAPI vkOpenSharedSemaphore(VkDevice device, const VkSemaphoreOpenInfo* pOpenInfo, VkSemaphore* pSemaphore) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->OpenSharedSemaphore(device, pOpenInfo, pSemaphore); +} + +LOADER_EXPORT VkResult VKAPI vkOpenPeerMemory(VkDevice device, const VkPeerMemoryOpenInfo* pOpenInfo, VkDeviceMemory* pMem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->OpenPeerMemory(device, pOpenInfo, pMem); +} + +LOADER_EXPORT VkResult VKAPI vkOpenPeerImage(VkDevice device, const VkPeerImageOpenInfo* pOpenInfo, VkImage* pImage, VkDeviceMemory* pMem) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->OpenPeerImage(device, pOpenInfo, pImage, pMem); +} + +LOADER_EXPORT VkResult VKAPI vkDestroyObject(VkDevice device, VkObjectType objType, VkObject object) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DestroyObject(device, objType, object); +} + +LOADER_EXPORT VkResult VKAPI vkGetObjectInfo(VkDevice device, VkObjectType objType, VkObject object, VkObjectInfoType infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetObjectInfo(device, objType, object, infoType, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset); +} + +LOADER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset); +} + +LOADER_EXPORT VkResult VKAPI vkQueueBindImageMemoryRange(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueBindImageMemoryRange(queue, image, allocationIdx, pBindInfo, mem, memOffset); +} + +LOADER_EXPORT VkResult VKAPI vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateFence(device, pCreateInfo, pFence); +} + +LOADER_EXPORT VkResult VKAPI vkResetFences(VkDevice device, uint32_t fenceCount, VkFence* pFences) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->ResetFences(device, fenceCount, pFences); +} + +LOADER_EXPORT VkResult VKAPI vkGetFenceStatus(VkDevice device, VkFence fence) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetFenceStatus(device, fence); +} + +LOADER_EXPORT VkResult VKAPI vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, bool32_t waitAll, uint64_t timeout) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout); +} + +LOADER_EXPORT VkResult VKAPI vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateSemaphore(device, pCreateInfo, pSemaphore); +} + +LOADER_EXPORT VkResult VKAPI vkQueueSignalSemaphore(VkQueue queue, VkSemaphore semaphore) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueSignalSemaphore(queue, semaphore); +} + +LOADER_EXPORT VkResult VKAPI vkQueueWaitSemaphore(VkQueue queue, VkSemaphore semaphore) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueueWaitSemaphore(queue, semaphore); +} + +LOADER_EXPORT VkResult VKAPI vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateEvent(device, pCreateInfo, pEvent); +} + +LOADER_EXPORT VkResult VKAPI vkGetEventStatus(VkDevice device, VkEvent event) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetEventStatus(device, event); +} + +LOADER_EXPORT VkResult VKAPI vkSetEvent(VkDevice device, VkEvent event) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->SetEvent(device, event); +} + +LOADER_EXPORT VkResult VKAPI vkResetEvent(VkDevice device, VkEvent event) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->ResetEvent(device, event); +} + +LOADER_EXPORT VkResult VKAPI vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateQueryPool(device, pCreateInfo, pQueryPool); +} + +LOADER_EXPORT VkResult VKAPI vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData, VkQueryResultFlags flags) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetQueryPoolResults(device, queryPool, startQuery, queryCount, pDataSize, pData, flags); +} + +LOADER_EXPORT VkResult VKAPI vkGetFormatInfo(VkDevice device, VkFormat format, VkFormatInfoType infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetFormatInfo(device, format, infoType, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, VkBuffer* pBuffer) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateBuffer(device, pCreateInfo, pBuffer); +} + +LOADER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateBufferView(device, pCreateInfo, pView); +} + +LOADER_EXPORT VkResult VKAPI vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateImage(device, pCreateInfo, pImage); +} + +LOADER_EXPORT VkResult VKAPI vkGetImageSubresourceInfo(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceInfoType infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->GetImageSubresourceInfo(device, image, pSubresource, infoType, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateImageView(device, pCreateInfo, pView); +} + +LOADER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(VkDevice device, const VkColorAttachmentViewCreateInfo* pCreateInfo, VkColorAttachmentView* pView) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateColorAttachmentView(device, pCreateInfo, pView); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDepthStencilView(VkDevice device, const VkDepthStencilViewCreateInfo* pCreateInfo, VkDepthStencilView* pView) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDepthStencilView(device, pCreateInfo, pView); +} + +LOADER_EXPORT VkResult VKAPI vkCreateShader(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateShader(device, pCreateInfo, pShader); +} + +LOADER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateGraphicsPipeline(device, pCreateInfo, pPipeline); +} + +LOADER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline basePipeline, VkPipeline* pPipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline); +} + +LOADER_EXPORT VkResult VKAPI vkCreateComputePipeline(VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateComputePipeline(device, pCreateInfo, pPipeline); +} + +LOADER_EXPORT VkResult VKAPI vkStorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->StorePipeline(device, pipeline, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkLoadPipeline(VkDevice device, size_t dataSize, const void* pData, VkPipeline* pPipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->LoadPipeline(device, dataSize, pData, pPipeline); +} + +LOADER_EXPORT VkResult VKAPI vkLoadPipelineDerivative(VkDevice device, size_t dataSize, const void* pData, VkPipeline basePipeline, VkPipeline* pPipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->LoadPipelineDerivative(device, dataSize, pData, basePipeline, pPipeline); +} + +LOADER_EXPORT VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout); +} + +LOADER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateSampler(device, pCreateInfo, pSampler); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout); +} + +LOADER_EXPORT VkResult VKAPI vkBeginDescriptorPoolUpdate(VkDevice device, VkDescriptorUpdateMode updateMode) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->BeginDescriptorPoolUpdate(device, updateMode); +} + +LOADER_EXPORT VkResult VKAPI vkEndDescriptorPoolUpdate(VkDevice device, VkCmdBuffer cmd) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->EndDescriptorPoolUpdate(device, cmd); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool); +} + +LOADER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->ResetDescriptorPool(device, descriptorPool); +} + +LOADER_EXPORT VkResult VKAPI vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount); +} + +LOADER_EXPORT void VKAPI vkClearDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + disp->ClearDescriptorSets(device, descriptorPool, count, pDescriptorSets); +} + +LOADER_EXPORT void VKAPI vkUpdateDescriptors(VkDevice device, VkDescriptorSet descriptorSet, uint32_t updateCount, const void** ppUpdateArray) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + disp->UpdateDescriptors(device, descriptorSet, updateCount, ppUpdateArray); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(VkDevice device, const VkDynamicVpStateCreateInfo* pCreateInfo, VkDynamicVpState* pState) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDynamicViewportState(device, pCreateInfo, pState); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(VkDevice device, const VkDynamicRsStateCreateInfo* pCreateInfo, VkDynamicRsState* pState) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDynamicRasterState(device, pCreateInfo, pState); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicCbStateCreateInfo* pCreateInfo, VkDynamicCbState* pState) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDynamicColorBlendState(device, pCreateInfo, pState); +} + +LOADER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDsStateCreateInfo* pCreateInfo, VkDynamicDsState* pState) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateDynamicDepthStencilState(device, pCreateInfo, pState); +} + +LOADER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer) +{ + const VkLayerDispatchTable *disp; + VkResult res; + + disp = loader_get_dispatch(device); + + res = disp->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer); + if (res == VK_SUCCESS) { + loader_init_dispatch(*pCmdBuffer, disp); + } + + return res; +} + +LOADER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + return disp->BeginCommandBuffer(cmdBuffer, pBeginInfo); +} + +LOADER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + return disp->EndCommandBuffer(cmdBuffer); +} + +LOADER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + return disp->ResetCommandBuffer(cmdBuffer); +} + +LOADER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline); +} + +LOADER_EXPORT void VKAPI vkCmdBindDynamicStateObject(VkCmdBuffer cmdBuffer, VkStateBindPoint stateBindPoint, VkDynamicStateObject state) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state); +} + +LOADER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); +} + +LOADER_EXPORT void VKAPI vkCmdBindVertexBuffers(VkCmdBuffer cmdBuffer, uint32_t startBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets); +} + +LOADER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType); +} + +LOADER_EXPORT void VKAPI vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount); +} + +LOADER_EXPORT void VKAPI vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount); +} + +LOADER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride); +} + +LOADER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride); +} + +LOADER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDispatch(cmdBuffer, x, y, z); +} + +LOADER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDispatchIndirect(cmdBuffer, buffer, offset); +} + +LOADER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdCloneImageData(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); +} + +LOADER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData); +} + +LOADER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data); +} + +LOADER_EXPORT void VKAPI vkCmdClearColorImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColor* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges); +} + +LOADER_EXPORT void VKAPI vkCmdClearDepthStencil(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, float depth, uint32_t stencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges); +} + +LOADER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions); +} + +LOADER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdSetEvent(cmdBuffer, event, pipeEvent); +} + +LOADER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdResetEvent(cmdBuffer, event, pipeEvent); +} + +LOADER_EXPORT void VKAPI vkCmdWaitEvents(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t eventCount, const VkEvent* pEvents, uint32_t memBarrierCount, const void** ppMemBarriers) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdWaitEvents(cmdBuffer, waitEvent, eventCount, pEvents, memBarrierCount, ppMemBarriers); +} + +LOADER_EXPORT void VKAPI vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t pipeEventCount, const VkPipeEvent* pPipeEvents, uint32_t memBarrierCount, const void** ppMemBarriers) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdPipelineBarrier(cmdBuffer, waitEvent, pipeEventCount, pPipeEvents, memBarrierCount, ppMemBarriers); +} + +LOADER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBeginQuery(cmdBuffer, queryPool, slot, flags); +} + +LOADER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdEndQuery(cmdBuffer, queryPool, slot); +} + +LOADER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount); +} + +LOADER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset); +} + +LOADER_EXPORT void VKAPI vkCmdCopyQueryPoolResults(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, VkFlags flags) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdCopyQueryPoolResults(cmdBuffer, queryPool, startQuery, queryCount, destBuffer, destOffset, destStride, flags); +} + +LOADER_EXPORT void VKAPI vkCmdInitAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, const uint32_t* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData); +} + +LOADER_EXPORT void VKAPI vkCmdLoadAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer srcBuffer, VkDeviceSize srcOffset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset); +} + +LOADER_EXPORT void VKAPI vkCmdSaveAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer destBuffer, VkDeviceSize destOffset) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset); +} + +LOADER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateFramebuffer(device, pCreateInfo, pFramebuffer); +} + +LOADER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->CreateRenderPass(device, pCreateInfo, pRenderPass); +} + +LOADER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBegin* pRenderPassBegin) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin); +} + +LOADER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdEndRenderPass(cmdBuffer, renderPass); +} + +LOADER_EXPORT VkResult VKAPI vkDbgSetValidationLevel(VkDevice device, VkValidationLevel validationLevel) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DbgSetValidationLevel(device, validationLevel); +} + +LOADER_EXPORT VkResult VKAPI vkDbgSetMessageFilter(VkDevice device, int32_t msgCode, VK_DBG_MSG_FILTER filter) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DbgSetMessageFilter(device, msgCode, filter); +} + +LOADER_EXPORT VkResult VKAPI vkDbgSetObjectTag(VkDevice device, VkObject object, size_t tagSize, const void* pTag) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DbgSetObjectTag(device, object, tagSize, pTag); +} + +LOADER_EXPORT VkResult VKAPI vkDbgSetDeviceOption(VkDevice device, VK_DBG_DEVICE_OPTION dbgOption, size_t dataSize, const void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(device); + + return disp->DbgSetDeviceOption(device, dbgOption, dataSize, pData); +} + +LOADER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDbgMarkerBegin(cmdBuffer, pMarker); +} + +LOADER_EXPORT void VKAPI vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(cmdBuffer); + + disp->CmdDbgMarkerEnd(cmdBuffer); +} + +LOADER_EXPORT VkResult VKAPI vkGetDisplayInfoWSI(VkDisplayWSI display, VkDisplayInfoTypeWSI infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(display); + + return disp->GetDisplayInfoWSI(display, infoType, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(VkDevice device, const VkSwapChainCreateInfoWSI* pCreateInfo, VkSwapChainWSI* pSwapChain) +{ + const VkLayerDispatchTable *disp; + VkResult res; + + disp = loader_get_dispatch(device); + + res = disp->CreateSwapChainWSI(device, pCreateInfo, pSwapChain); + if (res == VK_SUCCESS) { + loader_init_dispatch(*pSwapChain, disp); + } + + return res; +} + +LOADER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(VkSwapChainWSI swapChain) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(swapChain); + + return disp->DestroySwapChainWSI(swapChain); +} + +LOADER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(VkSwapChainWSI swapChain, VkSwapChainInfoTypeWSI infoType, size_t* pDataSize, void* pData) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(swapChain); + + return disp->GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData); +} + +LOADER_EXPORT VkResult VKAPI vkQueuePresentWSI(VkQueue queue, const VkPresentInfoWSI* pPresentInfo) +{ + const VkLayerDispatchTable *disp; + + disp = loader_get_dispatch(queue); + + return disp->QueuePresentWSI(queue, pPresentInfo); +} diff --git a/loader/vulkan.def b/loader/vulkan.def new file mode 100644 index 00000000..2be6ed6d --- /dev/null +++ b/loader/vulkan.def @@ -0,0 +1,158 @@ +;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Vulkan +; +; Copyright (C) 2015 LunarG, Inc. +; +; Permission is hereby granted, free of charge, to any person obtaining a +; copy of this software and associated documentation files (the "Software"), +; to deal in the Software without restriction, including without limitation +; the rights to use, copy, modify, merge, publish, distribute, sublicense, +; and/or sell copies of the Software, and to permit persons to whom the +; Software is furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included +; in all copies or substantial portions of the Software. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +; DEALINGS IN THE SOFTWARE. +;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; The following is required on Windows, for exporting symbols from the DLL + +LIBRARY vulkan +EXPORTS + vkCreateInstance + vkDestroyInstance + vkEnumeratePhysicalDevices + vkGetPhysicalDeviceInfo + vkGetProcAddr + vkCreateDevice + vkDestroyDevice + vkGetGlobalExtensionInfo + vkGetPhysicalDeviceExtensionInfo + vkEnumerateLayers + vkGetDeviceQueue + vkQueueSubmit + vkQueueWaitIdle + vkDeviceWaitIdle + vkAllocMemory + vkFreeMemory + vkSetMemoryPriority + vkMapMemory + vkUnmapMemory + vkFlushMappedMemoryRanges + vkInvalidateMappedMemoryRanges + vkPinSystemMemory + vkGetMultiDeviceCompatibility + vkOpenSharedMemory + vkOpenSharedSemaphore + vkOpenPeerMemory + vkOpenPeerImage + vkDestroyObject + vkGetObjectInfo + vkQueueBindObjectMemory + vkQueueBindObjectMemoryRange + vkQueueBindImageMemoryRange + vkCreateFence + vkResetFences + vkGetFenceStatus + vkWaitForFences + vkCreateSemaphore + vkQueueSignalSemaphore + vkQueueWaitSemaphore + vkCreateEvent + vkGetEventStatus + vkSetEvent + vkResetEvent + vkCreateQueryPool + vkGetQueryPoolResults + vkGetFormatInfo + vkCreateBuffer + vkCreateBufferView + vkCreateImage + vkGetImageSubresourceInfo + vkCreateImageView + vkCreateColorAttachmentView + vkCreateDepthStencilView + vkCreateShader + vkCreateGraphicsPipeline + vkCreateGraphicsPipelineDerivative + vkCreateComputePipeline + vkStorePipeline + vkLoadPipeline + vkLoadPipelineDerivative + vkCreatePipelineLayout + vkCreateSampler + vkCreateDescriptorSetLayout + vkBeginDescriptorPoolUpdate + vkEndDescriptorPoolUpdate + vkCreateDescriptorPool + vkResetDescriptorPool + vkAllocDescriptorSets + vkClearDescriptorSets + vkUpdateDescriptors + vkCreateDynamicViewportState + vkCreateDynamicRasterState + vkCreateDynamicColorBlendState + vkCreateDynamicDepthStencilState + vkCreateCommandBuffer + vkBeginCommandBuffer + vkEndCommandBuffer + vkResetCommandBuffer + vkCmdBindPipeline + vkCmdBindDynamicStateObject + vkCmdBindDescriptorSets + vkCmdBindVertexBuffers + vkCmdBindIndexBuffer + vkCmdDraw + vkCmdDrawIndexed + vkCmdDrawIndirect + vkCmdDrawIndexedIndirect + vkCmdDispatch + vkCmdDispatchIndirect + vkCmdCopyBuffer + vkCmdCopyImage + vkCmdBlitImage + vkCmdCopyBufferToImage + vkCmdCopyImageToBuffer + vkCmdCloneImageData + vkCmdUpdateBuffer + vkCmdFillBuffer + vkCmdClearColorImage + vkCmdClearDepthStencil + vkCmdResolveImage + vkCmdSetEvent + vkCmdResetEvent + vkCmdWaitEvents + vkCmdPipelineBarrier + vkCmdBeginQuery + vkCmdEndQuery + vkCmdResetQueryPool + vkCmdWriteTimestamp + vkCmdCopyQueryPoolResults + vkCmdInitAtomicCounters + vkCmdLoadAtomicCounters + vkCmdSaveAtomicCounters + vkCreateFramebuffer + vkCreateRenderPass + vkCmdBeginRenderPass + vkCmdEndRenderPass + vkDbgSetValidationLevel + vkDbgRegisterMsgCallback + vkDbgUnregisterMsgCallback + vkDbgSetMessageFilter + vkDbgSetObjectTag + vkDbgSetGlobalOption + vkDbgSetDeviceOption + vkCmdDbgMarkerBegin + vkCmdDbgMarkerEnd + vkGetDisplayInfoWSI + vkCreateSwapChainWSI + vkDestroySwapChainWSI + vkGetSwapChainInfoWSI + vkQueuePresentWSI -- cgit v1.2.3 From c5104f208dd40c53c47a77d84b4c5cd68065af26 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Wed, 6 May 2015 10:15:07 -0600 Subject: misc: Add vkGetInstanceProcAddr() entrypoint Adding this entrypoint as this has been discussed in khronos and is needed for the loader/layer/extension proposal. Caveats: 1) Have not updated layers or any tests/demos yet that will come later; 2) No one including loader is using this call yet; 3) Leaving exisitng vkGetProcAddr() as is for now; later once loader is using vkGetInstanceProcAddr call can switch vkGetProcAddr() to vkGetDeviceProcAddr() --- include/vkLayer.h | 1 + include/vulkan.h | 8 ++++++-- loader/gpa_helper.h | 4 ++++ loader/loader.c | 11 +++++++++++ loader/table_ops.h | 3 +++ vk-generate.py | 9 +++++++++ vk-layer-generate.py | 13 ++++++++----- vulkan.py | 4 ++++ 8 files changed, 46 insertions(+), 7 deletions(-) diff --git a/include/vkLayer.h b/include/vkLayer.h index e95811b8..87a79e5d 100644 --- a/include/vkLayer.h +++ b/include/vkLayer.h @@ -26,6 +26,7 @@ typedef struct VkBaseLayerObject_ typedef struct VkLayerDispatchTable_ { PFN_vkGetProcAddr GetProcAddr; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkCreateInstance CreateInstance; PFN_vkDestroyInstance DestroyInstance; PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; diff --git a/include/vulkan.h b/include/vulkan.h index 00ebbf51..ed222438 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -33,7 +33,7 @@ #include "vk_platform.h" // Vulkan API version supported by this file -#define VK_API_VERSION VK_MAKE_VERSION(0, 93, 0) +#define VK_API_VERSION VK_MAKE_VERSION(0, 93, 1) #ifdef __cplusplus extern "C" @@ -2136,6 +2136,7 @@ typedef VkResult (VKAPI *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCrea typedef VkResult (VKAPI *PFN_vkDestroyInstance)(VkInstance instance); typedef VkResult (VKAPI *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceInfo)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceInfoType infoType, size_t* pDataSize, void* pData); +typedef void * (VKAPI *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char * pName); typedef void * (VKAPI *PFN_vkGetProcAddr)(VkPhysicalDevice physicalDevice, const char * pName); typedef VkResult (VKAPI *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice); typedef VkResult (VKAPI *PFN_vkDestroyDevice)(VkDevice device); @@ -2271,10 +2272,13 @@ VkResult VKAPI vkGetPhysicalDeviceInfo( size_t* pDataSize, void* pData); +void * VKAPI vkGetInstanceProcAddr( + VkInstance instance, + const char* pName); + void * VKAPI vkGetProcAddr( VkPhysicalDevice physicalDevice, const char* pName); - // Device functions VkResult VKAPI vkCreateDevice( diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h index b2a6f311..b9bd688b 100644 --- a/loader/gpa_helper.h +++ b/loader/gpa_helper.h @@ -38,6 +38,8 @@ static inline void* globalGetProcAddr(const char *name) return (void*) vkEnumeratePhysicalDevices; if (!strcmp(name, "GetPhysicalDeviceInfo")) return (void*) vkGetPhysicalDeviceInfo; + if (!strcmp(name, "GetInstanceProcAddr")) + return (void*) vkGetInstanceProcAddr; if (!strcmp(name, "GetProcAddr")) return (void*) vkGetProcAddr; if (!strcmp(name, "CreateDevice")) @@ -312,6 +314,8 @@ static inline void *loader_non_passthrough_gpa(const char *name) return (void*) vkEnumeratePhysicalDevices; if (!strcmp(name, "GetPhysicalDeviceInfo")) return (void*) vkGetPhysicalDeviceInfo; + if (!strcmp(name, "GetInstanceProcAddr")) + return (void*) vkGetInstanceProcAddr; if (!strcmp(name, "GetProcAddr")) return (void*) vkGetProcAddr; if (!strcmp(name, "CreateDevice")) diff --git a/loader/loader.c b/loader/loader.c index 17778d5b..c452ce52 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -1288,6 +1288,17 @@ LOADER_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices( return (count > 0) ? VK_SUCCESS : res; } +LOADER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char * pName) +{ + if (instance != VK_NULL_HANDLE) { + + /* return entrypoint addresses that are global (in the loader)*/ + return globalGetProcAddr(pName); + } + + return NULL; +} + LOADER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char * pName) { if (gpu == VK_NULL_HANDLE) { diff --git a/loader/table_ops.h b/loader/table_ops.h index 3a3535d2..1b59a453 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -35,6 +35,7 @@ static inline void loader_initialize_dispatch_table(VkLayerDispatchTable *table, table->DestroyInstance = (PFN_vkDestroyInstance) gpa(gpu, "vkDestroyInstance"); table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(gpu, "vkEnumeratePhysicalDevices"); table->GetPhysicalDeviceInfo = (PFN_vkGetPhysicalDeviceInfo) gpa(gpu, "vkGetPhysicalDeviceInfo"); + table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(gpu, "vkGetInstanceProcAddr"); table->GetProcAddr = (PFN_vkGetProcAddr) gpa(gpu, "vkGetProcAddr"); table->CreateDevice = (PFN_vkCreateDevice) gpa(gpu, "vkCreateDevice"); table->DestroyDevice = (PFN_vkDestroyDevice) gpa(gpu, "vkDestroyDevice"); @@ -176,6 +177,8 @@ static inline void *loader_lookup_dispatch_table(const VkLayerDispatchTable *tab return (void *) table->EnumeratePhysicalDevices; if (!strcmp(name, "GetPhysicalDeviceInfo")) return (void *) table->GetPhysicalDeviceInfo; + if (!strcmp(name, "GetInstanceProcAddr")) + return (void *) table->GetInstanceProcAddr; if (!strcmp(name, "GetProcAddr")) return (void *) table->GetProcAddr; if (!strcmp(name, "CreateDevice")) diff --git a/vk-generate.py b/vk-generate.py index 024fce89..28d176b0 100755 --- a/vk-generate.py +++ b/vk-generate.py @@ -204,7 +204,10 @@ class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand): for proto in self.protos: if proto.name == "GetProcAddr": gpa_proto = proto + if proto.name == "GetInstanceProcAddr": + gpa_instance_proto = proto + gpa_instance_decl = self._generate_stub_decl(gpa_instance_proto) gpa_decl = self._generate_stub_decl(gpa_proto) gpa_pname = gpa_proto.params[-1].name @@ -216,6 +219,12 @@ class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand): (gpa_proto.ret, self.prefix, proto.name)) body = [] + body.append("%s %s" % (self.qual, gpa_instance_decl)) + body.append("{") + body.append(" return NULL;") + body.append("}") + body.append("") + body.append("%s %s" % (self.qual, gpa_decl)) body.append("{") body.append(generate_get_proc_addr_check(gpa_pname)) diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 8e5967ef..3f2282c1 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -510,7 +510,7 @@ class GenericLayerSubcommand(Subcommand): stmt = '' funcs = [] if proto.ret != "void": - ret_val = "VkResult result = " + ret_val = "%s result = " % proto.ret stmt = " return result;\n" if proto.name == "EnumerateLayers": funcs.append('%s%s\n' @@ -711,7 +711,7 @@ class APIDumpSubcommand(Subcommand): elif 'Create' in proto.name or 'Alloc' in proto.name or 'MapMemory' in proto.name: create_params = -1 if proto.ret != "void": - ret_val = "VkResult result = " + ret_val = "%s result = " % proto.ret stmt = " return result;\n" f_open = 'loader_platform_thread_lock_mutex(&printLock);\n ' log_func = ' if (StreamControl::writeAddress == true) {' @@ -748,9 +748,12 @@ class APIDumpSubcommand(Subcommand): pindex += 1 log_func = log_func.strip(', ') log_func_no_addr = log_func_no_addr.strip(', ') - if proto.ret != "void": + if proto.ret == "VkResult": log_func += ') = " << string_VkResult((VkResult)result) << endl' log_func_no_addr += ') = " << string_VkResult((VkResult)result) << endl' + elif proto.ret == "void*": + log_func += ') = " << result << endl' + log_func_no_addr += ') = " << result << endl' else: log_func += ')\\n"' log_func_no_addr += ')\\n"' @@ -1335,7 +1338,7 @@ class ObjectTrackerSubcommand(Subcommand): ret_val = '' stmt = '' if proto.ret != "void": - ret_val = "VkResult result = " + ret_val = "%s result = " % proto.ret stmt = " return result;\n" if proto.name == "EnumerateLayers": funcs.append('%s%s\n' @@ -1476,7 +1479,7 @@ class ThreadingSubcommand(Subcommand): stmt = '' funcs = [] if proto.ret != "void": - ret_val = "VkResult result = " + ret_val = "%s result = " % proto.ret stmt = " return result;\n" if proto.name == "EnumerateLayers": funcs.append('%s%s\n' diff --git a/vulkan.py b/vulkan.py index cb0b04f9..e795da17 100755 --- a/vulkan.py +++ b/vulkan.py @@ -235,6 +235,10 @@ core = Extension( Param("size_t*", "pDataSize"), Param("void*", "pData")]), + Proto("void*", "GetInstanceProcAddr", + [Param("VkInstance", "instance"), + Param("const char*", "pName")]), + Proto("void*", "GetProcAddr", [Param("VkPhysicalDevice", "gpu"), Param("const char*", "pName")]), -- cgit v1.2.3 From 73621286f61ea560355135175fa5026af529150e Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Fri, 8 May 2015 09:12:28 -0500 Subject: layers: Remove use_count from ObjectTracker Removed ll_increment_use_count from layer Fixed some issues with thread safety Simplified handling of special-case APIs Removed GetExtensionSupport dead code --- layers/object_track.h | 1 - vk-layer-generate.py | 202 ++++++++++++++++---------------------------------- 2 files changed, 65 insertions(+), 138 deletions(-) diff --git a/layers/object_track.h b/layers/object_track.h index 9c45e2a7..65b368e5 100644 --- a/layers/object_track.h +++ b/layers/object_track.h @@ -151,7 +151,6 @@ static const char* string_from_vulkan_object_type(uint32_t type) { typedef struct _OBJTRACK_NODE { VkObject vkObj; VkObjectType objType; - uint64_t numUses; OBJECT_STATUS status; } OBJTRACK_NODE; diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 3f2282c1..0d375c7b 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -267,28 +267,6 @@ class Subcommand(object): ggei_body.append('}') return "\n".join(ggei_body) - def _gen_layer_get_extension_support(self, layer="Generic"): - ges_body = [] - ges_body.append('VK_LAYER_EXPORT VkResult VKAPI xglGetExtensionSupport(VkPhysicalDevice gpu, const char* pExtName)') - ges_body.append('{') - ges_body.append(' VkResult result;') - ges_body.append(' VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;') - ges_body.append('') - ges_body.append(' /* This entrypoint is NOT going to init its own dispatch table since loader calls here early */') - ges_body.append(' if (!strncmp(pExtName, "%s", strlen("%s")))' % (layer, layer)) - ges_body.append(' {') - ges_body.append(' result = VK_SUCCESS;') - ges_body.append(' } else if (nextTable.GetExtensionSupport != NULL)') - ges_body.append(' {') - ges_body.append(' result = nextTable.GetExtensionSupport((VkPhysicalDevice)gpuw->nextObject, pExtName);') - ges_body.append(' } else') - ges_body.append(' {') - ges_body.append(' result = VK_ERROR_INVALID_EXTENSION;') - ges_body.append(' }') - ges_body.append(' return result;') - ges_body.append('}') - return "\n".join(ges_body) - def _generate_dispatch_entrypoints(self, qual=""): if qual: qual += " " @@ -829,24 +807,6 @@ class APIDumpSubcommand(Subcommand): ' return VK_SUCCESS;\n' ' }\n' '}' % (qual, decl, self.layer_name, ret_val, proto.c_call(),f_open, log_func, f_close, stmt, self.layer_name)) - elif 'GetExtensionSupport' == proto.name: - funcs.append('%s%s\n' - '{\n' - ' VkResult result;\n' - ' /* This entrypoint is NOT going to init its own dispatch table since loader calls here early */\n' - ' if (!strncmp(pExtName, "%s", strlen("%s")))\n' - ' {\n' - ' result = VK_SUCCESS;\n' - ' } else if (nextTable.GetExtensionSupport != NULL)\n' - ' {\n' - ' result = nextTable.%s;\n' - ' %s %s %s\n' - ' } else\n' - ' {\n' - ' result = VK_ERROR_INVALID_EXTENSION;\n' - ' }\n' - '%s' - '}' % (qual, decl, self.layer_name, self.layer_name, proto.c_call(), f_open, log_func, f_close, stmt)) else: funcs.append('%s%s\n' '{\n' @@ -1013,7 +973,6 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' pNewObjNode->obj.vkObj = vkObj;') header_txt.append(' pNewObjNode->obj.objType = objType;') header_txt.append(' pNewObjNode->obj.status = OBJSTATUS_NONE;') - header_txt.append(' pNewObjNode->obj.numUses = 0;') header_txt.append(' // insert at front of global list') header_txt.append(' pNewObjNode->pNextGlobal = pGlobalHead;') header_txt.append(' pGlobalHead = pNewObjNode;') @@ -1027,26 +986,6 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' //sprintf(str, "OBJ_STAT : %lu total objs & %lu %s objs.", numTotalObjs, numObjs[objIndex], string_from_vulkan_object_type(objType));') header_txt.append(' if (0) ll_print_lists();') header_txt.append('}') - header_txt.append('static void ll_increment_use_count(VkObject vkObj, VkObjectType objType) {') - header_txt.append(' objNode *pTrav = pObjectHead[objTypeToIndex(objType)];') - header_txt.append(' while (pTrav) {') - header_txt.append(' if (pTrav->obj.vkObj == vkObj) {') - header_txt.append(' pTrav->obj.numUses++;') - header_txt.append(' char str[1024];') - header_txt.append(' sprintf(str, "OBJ[%llu] : USING %s object 0x%" PRId64 " (%lu total uses)", object_track_index++, string_from_vulkan_object_type(objType), vkObj, pTrav->obj.numUses);') - header_txt.append(' layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);') - header_txt.append(' return;') - header_txt.append(' }') - header_txt.append(' pTrav = pTrav->pNextObj;') - header_txt.append(' }') - header_txt.append(' // If we do not find obj, insert it and then increment count') - header_txt.append(' char str[1024];') - header_txt.append(' sprintf(str, "Unable to increment count for obj 0x%" PRId64 ", will add to list as %s type and increment count", vkObj, string_from_vulkan_object_type(objType));') - header_txt.append(' layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);') - header_txt.append('') - header_txt.append(' ll_insert_obj(vkObj, objType);') - header_txt.append(' ll_increment_use_count(vkObj, objType);') - header_txt.append('}') header_txt.append('// We usually do not know Obj type when we destroy it so have to fetch') header_txt.append('// Type from global list w/ ll_destroy_obj()') header_txt.append('// and then do the full removal from both lists w/ ll_remove_obj_type()') @@ -1089,7 +1028,7 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' assert(numTotalObjs > 0);') header_txt.append(' numTotalObjs--;') header_txt.append(' char str[1024];') - header_txt.append(' sprintf(str, "OBJ_STAT Removed %s obj 0x%" PRId64 " that was used %lu times (%lu total objs remain & %lu %s objs).", string_from_vulkan_object_type(pTrav->obj.objType), pTrav->obj.vkObj, pTrav->obj.numUses, numTotalObjs, numObjs[objTypeToIndex(pTrav->obj.objType)], string_from_vulkan_object_type(pTrav->obj.objType));') + header_txt.append(' sprintf(str, "OBJ_STAT Removed %s obj 0x%" PRId64 " (%lu total objs remain & %lu %s objs).", string_from_vulkan_object_type(pTrav->obj.objType), pTrav->obj.vkObj, numTotalObjs, numObjs[objTypeToIndex(pTrav->obj.objType)], string_from_vulkan_object_type(pTrav->obj.objType));') header_txt.append(' layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);') header_txt.append(' free(pTrav);') header_txt.append(' return;') @@ -1233,108 +1172,118 @@ class ObjectTrackerSubcommand(Subcommand): decl = proto.c_func(prefix="vk", attr="VKAPI") param0_name = proto.params[0].name p0_type = proto.params[0].ty.strip('*').replace('const ', '') + using_line = '' create_line = '' destroy_line = '' funcs = [] - # Special cases for API funcs that don't use an object as first arg - if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'GetPhysicalDeviceInfo', 'CreateInstance', 'QueueSubmit', 'QueueWaitIdle', 'QueueBindObjectMemory', 'QueueBindObjectMemoryRange', 'QueueBindImageMemoryRange', 'QueuePresentWSI', 'GetGlobalExtensionInfo', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore']]: - using_line = '' - else: - using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' - using_line += ' ll_increment_use_count(%s, %s);\n' % (param0_name, obj_type_mapping[p0_type]) - # using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' -- Add in after special case sections below. + if 'QueueSubmit' in proto.name: - using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' set_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED);\n' using_line += ' // TODO: Fix for updated memory reference mechanism\n' using_line += ' // validate_memory_mapping_status(pMemRefs, memRefCount);\n' using_line += ' // validate_mem_ref_count(memRefCount);\n' using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindObjectMemoryRange' in proto.name: - using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindObject' in proto.name: - using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindImage' in proto.name: - using_line += ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'GetObjectInfo' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'GetFenceStatus' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' // Warn if submitted_flag is not set\n' using_line += ' validate_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_MSG_ERROR, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'WaitForFences' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' // Warn if waiting on unsubmitted fence\n' using_line += ' for (uint32_t i = 0; i < fenceCount; i++) {\n' using_line += ' validate_status(pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_MSG_ERROR, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");\n' using_line += ' }\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'EndCommandBuffer' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' reset_status(cmdBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER, (OBJSTATUS_VIEWPORT_BOUND |\n' using_line += ' OBJSTATUS_RASTER_BOUND |\n' using_line += ' OBJSTATUS_COLOR_BLEND_BOUND |\n' using_line += ' OBJSTATUS_DEPTH_STENCIL_BOUND));\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'CmdBindDynamicStateObject' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' track_object_status(cmdBuffer, stateBindPoint);\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'CmdDraw' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validate_draw_state_flags(cmdBuffer);\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'MapMemory' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' set_status(mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'UnmapMemory' in proto.name: + using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' reset_status(mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);\n' - if 'AllocDescriptor' in proto.name: # Allocates array of DSs - create_line = ' for (uint32_t i = 0; i < *pCount; i++) {\n' - create_line += ' loader_platform_thread_lock_mutex(&objLock);\n' + using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' + elif 'AllocDescriptor' in proto.name: # Allocates array of DSs + create_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + create_line += ' for (uint32_t i = 0; i < *pCount; i++) {\n' create_line += ' ll_insert_obj(pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);\n' - create_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' create_line += ' }\n' + create_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'Create' in proto.name or 'Alloc' in proto.name: - create_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + create_line = ' loader_platform_thread_lock_mutex(&objLock);\n' create_line += ' ll_insert_obj(*%s, %s);\n' % (proto.params[-1].name, obj_type_mapping[proto.params[-1].ty.strip('*').replace('const ', '')]) create_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - # Add thread unlock statement following objecttracker processing code. - if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'GetPhysicalDeviceInfo', 'CreateInstance', 'QueueSubmit', 'QueueAddMemReferences', 'QueueRemoveMemReferences', 'QueueWaitIdle', 'QueueBindObjectMemory', 'QueueBindObjectMemoryRange', 'QueueBindImageMemoryRange', 'QueuePresentWSI', 'GetGlobalExtensionInfo', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore']]: - using_line += '' - else: - using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - if 'DestroyObject' in proto.name: - destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + + if 'GetDeviceQueue' in proto.name: + destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + destroy_line += ' addQueueInfo(queueNodeIndex, *pQueue);\n' + destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' + elif 'DestroyObject' in proto.name: + destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' destroy_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) destroy_line += ' ll_destroy_obj(%s);\n' % (proto.params[2].name) destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - using_line = '' + elif 'DestroyDevice' in proto.name: + destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + destroy_line += ' ll_destroy_obj(device);\n' + destroy_line += ' // Report any remaining objects in LL\n' + destroy_line += ' objNode *pTrav = pGlobalHead;\n' + destroy_line += ' while (pTrav) {\n' + destroy_line += ' if ((pTrav->obj.objType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) || (pTrav->obj.objType == VK_OBJECT_TYPE_QUEUE)) {\n' + destroy_line += ' // Cannot destroy physical device so ignore\n' + destroy_line += ' pTrav = pTrav->pNextGlobal;\n' + destroy_line += ' } else {\n' + destroy_line += ' char str[1024];\n' + destroy_line += ' sprintf(str, "OBJ ERROR : %s object 0x%" PRId64 " has not been destroyed.", string_from_vulkan_object_type(pTrav->obj.objType), pTrav->obj.vkObj);\n' + destroy_line += ' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK", str);\n' + destroy_line += ' pTrav = pTrav->pNextGlobal;\n' + destroy_line += ' }\n' + destroy_line += ' }\n' + destroy_line += ' // Clean up Queue\'s MemRef Linked Lists\n' + destroy_line += ' destroyQueueMemRefLists();\n' + destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' + elif 'Free' in proto.name: + destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + destroy_line += ' ll_destroy_obj(%s);\n' % (proto.params[1].name) + destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' else: if 'Destroy' in proto.name: - destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' + destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' destroy_line += ' ll_destroy_obj(%s);\n' % (param0_name) destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - using_line = '' - else: - if 'Free' in proto.name: - destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' - destroy_line += ' ll_destroy_obj(%s);\n' % (proto.params[1].name) - destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - using_line = '' - if 'DestroyDevice' in proto.name: - destroy_line += ' // Report any remaining objects in LL\n objNode *pTrav = pGlobalHead;\n while (pTrav) {\n' - destroy_line += ' if ((pTrav->obj.objType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) || (pTrav->obj.objType == VK_OBJECT_TYPE_QUEUE)) {\n' - destroy_line += ' // Cannot destroy physical device so ignore\n' - destroy_line += ' pTrav = pTrav->pNextGlobal;\n' - destroy_line += ' } else {\n' - destroy_line += ' char str[1024];\n' - destroy_line += ' sprintf(str, "OBJ ERROR : %s object 0x%" PRId64 " has not been destroyed (was used %lu times).", string_from_vulkan_object_type(pTrav->obj.objType), pTrav->obj.vkObj, pTrav->obj.numUses);\n' - destroy_line += ' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK", str);\n' - destroy_line += ' pTrav = pTrav->pNextGlobal;\n' - destroy_line += ' }\n' - destroy_line += ' }\n' - destroy_line += ' // Clean up Queue\'s MemRef Linked Lists\n' - destroy_line += ' destroyQueueMemRefLists();\n' - if 'GetDeviceQueue' in proto.name: - destroy_line = ' addQueueInfo(queueNodeIndex, *pQueue);\n' ret_val = '' stmt = '' if proto.ret != "void": @@ -1344,7 +1293,6 @@ class ObjectTrackerSubcommand(Subcommand): funcs.append('%s%s\n' '{\n' ' if (gpu != VK_NULL_HANDLE) {\n' - ' %s' ' pCurObj = (VkBaseLayerObject *) gpu;\n' ' loader_platform_thread_once(&tabOnce, init%s);\n' ' %snextTable.%s;\n' @@ -1358,45 +1306,25 @@ class ObjectTrackerSubcommand(Subcommand): ' strncpy((char *) pOutLayers[0], "%s", maxStringSize);\n' ' return VK_SUCCESS;\n' ' }\n' - '}' % (qual, decl, using_line, self.layer_name, ret_val, proto.c_call(), create_line, destroy_line, stmt, self.layer_name)) - elif 'GetExtensionSupport' == proto.name: - funcs.append('%s%s\n' - '{\n' - ' VkResult result;\n' - ' /* This entrypoint is NOT going to init its own dispatch table since loader calls this early */\n' - ' if (!strncmp(pExtName, "%s", strlen("%s")) ||\n' - ' !strncmp(pExtName, "objTrackGetObjectsCount", strlen("objTrackGetObjectsCount")) ||\n' - ' !strncmp(pExtName, "objTrackGetObjects", strlen("objTrackGetObjects")))\n' - ' !strncmp(pExtName, "objTrackGetObjectsOfTypeCount", strlen("objTrackGetObjectsOfTypeCount")) ||\n' - ' !strncmp(pExtName, "objTrackGetObjectsOfType", strlen("objTrackGetObjectsOfType")))\n' - ' {\n' - ' result = VK_SUCCESS;\n' - ' } else if (nextTable.GetExtensionSupport != NULL)\n' - ' {\n' - ' %s' - ' result = nextTable.%s;\n' - ' } else\n' - ' {\n' - ' result = VK_ERROR_INVALID_EXTENSION;\n' - ' }\n' - '%s' - '}' % (qual, decl, self.layer_name, self.layer_name, using_line, proto.c_call(), stmt)) + '}' % (qual, decl, self.layer_name, ret_val, proto.c_call(), create_line, destroy_line, stmt, self.layer_name)) elif 'GetPhysicalDeviceInfo' in proto.name: - gpu_state = ' if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES) {\n' + + gpu_state = ' if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES) {\n' gpu_state += ' if (pData != NULL) {\n' + gpu_state += ' loader_platform_thread_lock_mutex(&objLock);\n' gpu_state += ' setGpuQueueInfoState(pDataSize, pData);\n' + gpu_state += ' loader_platform_thread_unlock_mutex(&objLock);\n' gpu_state += ' }\n' gpu_state += ' }\n' funcs.append('%s%s\n' '{\n' - '%s' ' pCurObj = (VkBaseLayerObject *) gpu;\n' ' loader_platform_thread_once(&tabOnce, init%s);\n' ' %snextTable.%s;\n' '%s%s' '%s' '%s' - '}' % (qual, decl, using_line, self.layer_name, ret_val, proto.c_call(), create_line, destroy_line, gpu_state, stmt)) + '}' % (qual, decl, self.layer_name, ret_val, proto.c_call(), create_line, destroy_line, gpu_state, stmt)) else: funcs.append('%s%s\n' '{\n' -- cgit v1.2.3 From 7e1c119ff2a9d655103d33136c1237fd4a758340 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Fri, 8 May 2015 09:50:33 -0500 Subject: vulkan.h: V94 -- remove vkCmdCloneImageData. Bug #16550. --- icd/nulldrv/nulldrv.c | 10 ---------- include/vkLayer.h | 1 - include/vulkan.h | 17 ++++------------- layers/draw_state.cpp | 17 ----------------- layers/glave_snapshot.c | 8 -------- layers/mem_tracker.cpp | 27 --------------------------- layers/param_checker.cpp | 14 -------------- loader/gpa_helper.h | 2 -- loader/table_ops.h | 3 --- loader/trampoline.c | 9 --------- loader/vulkan.def | 1 - vulkan.py | 7 ------- 12 files changed, 4 insertions(+), 112 deletions(-) diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c index b7e42dd0..408f2caa 100644 --- a/icd/nulldrv/nulldrv.c +++ b/icd/nulldrv/nulldrv.c @@ -1054,16 +1054,6 @@ ICD_EXPORT void VKAPI vkCmdCopyImageToBuffer( NULLDRV_LOG_FUNC; } -ICD_EXPORT void VKAPI vkCmdCloneImageData( - VkCmdBuffer cmdBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout) -{ - NULLDRV_LOG_FUNC; -} - ICD_EXPORT void VKAPI vkCmdUpdateBuffer( VkCmdBuffer cmdBuffer, VkBuffer destBuffer, diff --git a/include/vkLayer.h b/include/vkLayer.h index 87a79e5d..bd56f03d 100644 --- a/include/vkLayer.h +++ b/include/vkLayer.h @@ -120,7 +120,6 @@ typedef struct VkLayerDispatchTable_ PFN_vkCmdBlitImage CmdBlitImage; PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage; PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer; - PFN_vkCmdCloneImageData CmdCloneImageData; PFN_vkCmdUpdateBuffer CmdUpdateBuffer; PFN_vkCmdFillBuffer CmdFillBuffer; PFN_vkCmdClearColorImage CmdClearColorImage; diff --git a/include/vulkan.h b/include/vulkan.h index ed222438..e85ca9d2 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -1071,11 +1071,10 @@ typedef VkFlags VkImageCreateFlags; typedef enum VkImageCreateFlagBits_ { VK_IMAGE_CREATE_INVARIANT_DATA_BIT = VK_BIT(0), - VK_IMAGE_CREATE_CLONEABLE_BIT = VK_BIT(1), - VK_IMAGE_CREATE_SHAREABLE_BIT = VK_BIT(2), // Image should be shareable - VK_IMAGE_CREATE_SPARSE_BIT = VK_BIT(3), // Image should support sparse backing - VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = VK_BIT(4), // Allows image views to have different format than the base image - VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = VK_BIT(5), // Allows creating image views with cube type from the created image + VK_IMAGE_CREATE_SHAREABLE_BIT = VK_BIT(1), // Image should be shareable + VK_IMAGE_CREATE_SPARSE_BIT = VK_BIT(2), // Image should support sparse backing + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = VK_BIT(3), // Allows image views to have different format than the base image + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = VK_BIT(4), // Allows creating image views with cube type from the created image } VkImageCreateFlagBits; // Depth-stencil view creation flags @@ -2227,7 +2226,6 @@ typedef void (VKAPI *PFN_vkCmdCopyImage)(VkCmdBuffer cmdBuffer, VkImage srcI typedef void (VKAPI *PFN_vkCmdBlitImage)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions); typedef void (VKAPI *PFN_vkCmdCopyBufferToImage)(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); typedef void (VKAPI *PFN_vkCmdCopyImageToBuffer)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); -typedef void (VKAPI *PFN_vkCmdCloneImageData)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout); typedef void (VKAPI *PFN_vkCmdUpdateBuffer)(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData); typedef void (VKAPI *PFN_vkCmdFillBuffer)(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data); typedef void (VKAPI *PFN_vkCmdClearColorImage)(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColor* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); @@ -2835,13 +2833,6 @@ void VKAPI vkCmdCopyImageToBuffer( uint32_t regionCount, const VkBufferImageCopy* pRegions); -void VKAPI vkCmdCloneImageData( - VkCmdBuffer cmdBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout); - void VKAPI vkCmdUpdateBuffer( VkCmdBuffer cmdBuffer, VkBuffer destBuffer, diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index f73e533d..7836198f 100755 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -2299,21 +2299,6 @@ VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); } -VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout) -{ - GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer); - if (pCB) { - updateCBTracking(cmdBuffer); - addCmd(pCB, CMD_CLONEIMAGEDATA); - } - else { - char str[1024]; - sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str); - } - nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); -} - VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData) { GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer); @@ -2848,8 +2833,6 @@ VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* func return (void*) vkCmdCopyBufferToImage; if (!strcmp(funcName, "vkCmdCopyImageToBuffer")) return (void*) vkCmdCopyImageToBuffer; - if (!strcmp(funcName, "vkCmdCloneImageData")) - return (void*) vkCmdCloneImageData; if (!strcmp(funcName, "vkCmdUpdateBuffer")) return (void*) vkCmdUpdateBuffer; if (!strcmp(funcName, "vkCmdFillBuffer")) diff --git a/layers/glave_snapshot.c b/layers/glave_snapshot.c index c924355e..120656d6 100644 --- a/layers/glave_snapshot.c +++ b/layers/glave_snapshot.c @@ -1407,14 +1407,6 @@ VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); } -VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout) -{ - loader_platform_thread_lock_mutex(&objLock); - ll_increment_use_count((void*)cmdBuffer, VK_OBJECT_TYPE_CMD_BUFFER); - loader_platform_thread_unlock_mutex(&objLock); - nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); -} - VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkGpuSize destOffset, VkGpuSize dataSize, const uint32_t* pData) { loader_platform_thread_lock_mutex(&objLock); diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index d8a1df80..98b2df54 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -1909,31 +1909,6 @@ VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer( nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); } -VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData( - VkCmdBuffer cmdBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout) -{ - // TODO : Each image will have mem mapping so track them - loader_platform_thread_lock_mutex(&globalLock); - VkDeviceMemory mem = getMemBindingFromObject(srcImage); - if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) { - char str[1024]; - sprintf(str, "In vkCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str); - } - mem = getMemBindingFromObject(destImage); - if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) { - char str[1024]; - sprintf(str, "In vkCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str); - } - loader_platform_thread_unlock_mutex(&globalLock); - nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); -} - VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer( VkCmdBuffer cmdBuffer, VkBuffer destBuffer, @@ -2352,8 +2327,6 @@ VK_LAYER_EXPORT void* VKAPI vkGetProcAddr( return (void*) vkCmdCopyBufferToImage; if (!strcmp(funcName, "vkCmdCopyImageToBuffer")) return (void*) vkCmdCopyImageToBuffer; - if (!strcmp(funcName, "vkCmdCloneImageData")) - return (void*) vkCmdCloneImageData; if (!strcmp(funcName, "vkCmdUpdateBuffer")) return (void*) vkCmdUpdateBuffer; if (!strcmp(funcName, "vkCmdFillBuffer")) diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index 50f61571..79783cb5 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -1376,20 +1376,6 @@ VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); } -VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout) -{ - char str[1024]; - if (!validate_VkImageLayout(srcImageLayout)) { - sprintf(str, "Parameter srcImageLayout to function CmdCloneImageData has invalid value of %i.", (int)srcImageLayout); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str); - } - if (!validate_VkImageLayout(destImageLayout)) { - sprintf(str, "Parameter destImageLayout to function CmdCloneImageData has invalid value of %i.", (int)destImageLayout); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str); - } - nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); -} - VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData) { diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h index b9bd688b..775b29cf 100644 --- a/loader/gpa_helper.h +++ b/loader/gpa_helper.h @@ -220,8 +220,6 @@ static inline void* globalGetProcAddr(const char *name) return (void*) vkCmdCopyBufferToImage; if (!strcmp(name, "CmdCopyImageToBuffer")) return (void*) vkCmdCopyImageToBuffer; - if (!strcmp(name, "CmdCloneImageData")) - return (void*) vkCmdCloneImageData; if (!strcmp(name, "CmdUpdateBuffer")) return (void*) vkCmdUpdateBuffer; if (!strcmp(name, "CmdFillBuffer")) diff --git a/loader/table_ops.h b/loader/table_ops.h index 1b59a453..da2f7f11 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -126,7 +126,6 @@ static inline void loader_initialize_dispatch_table(VkLayerDispatchTable *table, table->CmdBlitImage = (PFN_vkCmdBlitImage) gpa(gpu, "vkCmdBlitImage"); table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) gpa(gpu, "vkCmdCopyBufferToImage"); table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) gpa(gpu, "vkCmdCopyImageToBuffer"); - table->CmdCloneImageData = (PFN_vkCmdCloneImageData) gpa(gpu, "vkCmdCloneImageData"); table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) gpa(gpu, "vkCmdUpdateBuffer"); table->CmdFillBuffer = (PFN_vkCmdFillBuffer) gpa(gpu, "vkCmdFillBuffer"); table->CmdClearColorImage = (PFN_vkCmdClearColorImage) gpa(gpu, "vkCmdClearColorImage"); @@ -357,8 +356,6 @@ static inline void *loader_lookup_dispatch_table(const VkLayerDispatchTable *tab return (void *) table->CmdCopyBufferToImage; if (!strcmp(name, "CmdCopyImageToBuffer")) return (void *) table->CmdCopyImageToBuffer; - if (!strcmp(name, "CmdCloneImageData")) - return (void *) table->CmdCloneImageData; if (!strcmp(name, "CmdUpdateBuffer")) return (void *) table->CmdUpdateBuffer; if (!strcmp(name, "CmdFillBuffer")) diff --git a/loader/trampoline.c b/loader/trampoline.c index a435ca1f..d393c2be 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -845,15 +845,6 @@ LOADER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage s disp->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); } -LOADER_EXPORT void VKAPI vkCmdCloneImageData(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout) -{ - const VkLayerDispatchTable *disp; - - disp = loader_get_dispatch(cmdBuffer); - - disp->CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout); -} - LOADER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData) { const VkLayerDispatchTable *disp; diff --git a/loader/vulkan.def b/loader/vulkan.def index 2be6ed6d..d3bfe35d 100644 --- a/loader/vulkan.def +++ b/loader/vulkan.def @@ -120,7 +120,6 @@ EXPORTS vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer - vkCmdCloneImageData vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorImage diff --git a/vulkan.py b/vulkan.py index e795da17..9030ea43 100755 --- a/vulkan.py +++ b/vulkan.py @@ -750,13 +750,6 @@ core = Extension( Param("uint32_t", "regionCount"), Param("const VkBufferImageCopy*", "pRegions")]), - Proto("void", "CmdCloneImageData", - [Param("VkCmdBuffer", "cmdBuffer"), - Param("VkImage", "srcImage"), - Param("VkImageLayout", "srcImageLayout"), - Param("VkImage", "destImage"), - Param("VkImageLayout", "destImageLayout")]), - Proto("void", "CmdUpdateBuffer", [Param("VkCmdBuffer", "cmdBuffer"), Param("VkBuffer", "destBuffer"), -- cgit v1.2.3 From 86da3e90a67247824bad8da22dca4e772b614a69 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Fri, 8 May 2015 15:46:40 -0600 Subject: spirv: Update to matching header --- layers/spirv/spirv.h | 1898 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 1220 insertions(+), 678 deletions(-) diff --git a/layers/spirv/spirv.h b/layers/spirv/spirv.h index 7404d6fd..f3d18a3f 100644 --- a/layers/spirv/spirv.h +++ b/layers/spirv/spirv.h @@ -1,762 +1,1304 @@ /* -** Copyright (c) 2014-2015 The Khronos Group Inc. +** Copyright (c) 2015 The Khronos Group Inc. ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: ** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. ** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. */ -// -// Enumeration tokens for SPIR V. -// +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Specification revision 30. +** Enumeration tokens for SPIR-V, in three styles: C, C++, generic. +** - C++ will have the tokens in the "spv" name space, with no prefix. +** - C will have tokens with as "Spv" prefix. +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ -#pragma once #ifndef spirv_H #define spirv_H #ifdef __cplusplus -namespace spv{ -#endif + +namespace spv { const int MagicNumber = 0x07230203; const int Version = 99; typedef unsigned int Id; -const Id NoResult = 0; -const Id NoType = 0; - const unsigned int OpCodeMask = 0xFFFF; const unsigned int WordCountShift = 16; -// Set of capabilities. Generally, something is assumed to be in core, -// if nothing else is said. So, these are used to identify when something -// requires a specific capability to be declared. -enum Capability { - CapMatrix, - CapShader, - CapGeom, - CapTess, - CapAddr, - CapLink, - CapKernel -}; - -// What language is the source code in? Note the OpSource instruction has a separate -// operand for the version number, this is just the language name. The GLSL -// compatibility profile will be indicated by using an OpSourceExtension string. enum SourceLanguage { - LangUnknown, - LangESSL, - LangGLSL, - LangOpenCL, - - LangCount // guard for validation, "default:" statements, etc. + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL = 3, }; -// Used per entry point to communicate the "stage" or other model of -// execution used by that entry point. -// See OpEntryPoint. enum ExecutionModel { - ModelVertex, - ModelTessellationControl, - ModelTessellationEvaluation, - ModelGeometry, - ModelFragment, - ModelGLCompute, - ModelKernel, - - ModelCount // guard for validation, "default:" statements, etc. + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, }; -// Used as an argument to OpMemoryModel enum AddressingModel { - AddressingLogical, - AddressingPhysical32, - AddressingPhysical64, - - AddressingCount // guard for validation, "default:" statements, etc. + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, }; -// Used as an argment to OpMemoryModel enum MemoryModel { - MemorySimple, - MemoryGLSL450, - MemoryOCL12, - MemoryOCL20, - MemoryOCL21, - - MemoryCount // guard for validation, "default:" statements, etc. + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL12 = 2, + MemoryModelOpenCL20 = 3, + MemoryModelOpenCL21 = 4, }; -// Used per entry point to communicate modes related to input, output, and execution. -// See OpExecutionMode. enum ExecutionMode { - ExecutionInvocations, - ExecutionSpacingEqual, - ExecutionSpacingFractionalEven, - ExecutionSpacingFractionalOdd, - ExecutionVertexOrderCw, - ExecutionVertexOrderCcw, - ExecutionPixelCenterInteger, - ExecutionOriginUpperLeft, - ExecutionEarlyFragmentTests, - ExecutionPointMode, - ExecutionXfb, - ExecutionDepthReplacing, - ExecutionDepthAny, - ExecutionDepthGreater, - ExecutionDepthLess, - ExecutionDepthUnchanged, - ExecutionLocalSize, - ExecutionLocalSizeHint, - - ExecutionInputPoints, - ExecutionInputLines, - ExecutionInputLinesAdjacency, - ExecutionInputTriangles, - ExecutionInputTrianglesAdjacency, - ExecutionInputQuads, - ExecutionInputIsolines, - - ExecutionOutputVertices, - ExecutionOutputPoints, - ExecutionOutputLineStrip, - ExecutionOutputTriangleStrip, - - ExecutionVecTypeHint, - ExecutionContractionOff, - ExecutionModeCount // guard for validation, "default:" statements, etc. + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeEarlyFragmentTests = 8, + ExecutionModePointMode = 9, + ExecutionModeXfb = 10, + ExecutionModeDepthReplacing = 11, + ExecutionModeDepthAny = 12, + ExecutionModeDepthGreater = 13, + ExecutionModeDepthLess = 14, + ExecutionModeDepthUnchanged = 15, + ExecutionModeLocalSize = 16, + ExecutionModeLocalSizeHint = 17, + ExecutionModeInputPoints = 18, + ExecutionModeInputLines = 19, + ExecutionModeInputLinesAdjacency = 20, + ExecutionModeInputTriangles = 21, + ExecutionModeInputTrianglesAdjacency = 22, + ExecutionModeInputQuads = 23, + ExecutionModeInputIsolines = 24, + ExecutionModeOutputVertices = 25, + ExecutionModeOutputPoints = 26, + ExecutionModeOutputLineStrip = 27, + ExecutionModeOutputTriangleStrip = 28, + ExecutionModeVecTypeHint = 29, + ExecutionModeContractionOff = 30, }; enum StorageClass { - StorageConstantUniform, - StorageInput, - StorageUniform, - StorageOutput, - StorageWorkgroupLocal, - StorageWorkgroupGlobal, - StoragePrivateGlobal, - StorageFunction, - StorageGeneric, - StoragePrivate, - StorageAtomicCounter, - StorageCount // guard for validation, "default:" statements, etc. -}; - -// Dimensionalities currently used for sampling. -// See TypeSampler in TypeClass. -enum Dimensionality { - Dim1D, - Dim2D, - Dim3D, - DimCube, - DimRect, - DimBuffer, - - DimCount // guard for validation, "default:" statements, etc. -}; - -// Sampler addressing mode. + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroupLocal = 4, + StorageClassWorkgroupGlobal = 5, + StorageClassPrivateGlobal = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPrivate = 9, + StorageClassAtomicCounter = 10, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, +}; + enum SamplerAddressingMode { - SamplerAddressingNone = 0, - SamplerAddressingClampToEdge = 2, - SamplerAddressingClamp = 4, - SamplerAddressingRepeat = 6, - SamplerAddressingRepeatMirrored = 8, - SamplerAddressingModeLast, + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, }; -// Sampler filter mode. enum SamplerFilterMode { - SamplerFilterNearest = 0x10, - SamplerFilterLinear = 0x20, - SamplerFilterModeLast, + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, }; -// FP Fast Math Mode. -enum FPFastMath { - FPFastMathNNan = 0, // assume parameters and result are not NaN. - FPFastMathNInf = 0x02, // assume parameters and result are not +/- Inf. - FPFastMathNSZ = 0x04, // treat the sign of a zero parameter or result as insignificant. - FPFastMathARcp = 0x08, // allow the usage of reciprocal rather than perform a division. - FPFastMathFast = 0x10, // allow Algebraic transformations according to real number associative and distibutive algebra. This flag implies all the others. - FPFastMathLast, +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, }; -// FP Fast Math Mode. enum FPRoundingMode { - FPRoundRTE, // round to nearest even. - FPRoundRTZ, // round towards zero. - FPRoundRTP, // round towards positive infinity. - FPRoundRTN, // round towards negative infinity. - FPRoundLast, + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, }; -// Global identifier linkage types (by default the linkage type of global identifiers is private. This means that they are only accessible to objects inside the module.) enum LinkageType { - LinkageExport, // accessible by objects in other modules as well. - LinkageImport, // a forward declaration to a global identifier that exists in another module. - LinkageLast, + LinkageTypeExport = 0, + LinkageTypeImport = 1, }; -// Access Qualifiers for OpenCL pipes and images enum AccessQualifier { - AccessQualReadOnly, - AccessQualWriteOnly, - AccessQualReadWrite, - AccessQualLast, + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, }; -// Function argument attributes enum FunctionParameterAttribute { - FuncParamAttrZext, // value should be zero extended if needed - FuncParamAttrSext, // value should be sign extended if needed - FuncParamAttrByval, // only valid for pointer parameters (not for ret value), this indicates that the pointer parameter should really be passed by value to the function. - FuncParamAttrSret, // indicates that the pointer parameter specifies the address of a structure that is the return value of the function in the source program. only applicable to the first parameter - FuncParamAttrNoAlias, - FuncParamAttrNoCapture, - FuncParamAttrSVM, - FuncParamAttrNoWrite, - FuncParamAttrNoReadWrite, - FuncParamAttrLast, // guard for validation, "default:" statements, etc. + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeSVM = 6, + FunctionParameterAttributeNoWrite = 7, + FunctionParameterAttributeNoReadWrite = 8, }; - -// Extra forms of "qualification" to add as needed. See OpDecorate. enum Decoration { - // For legacy ES precision qualifiers; newer language - // designs can use the "num-bits" feature in TypeClass. - // The precision qualifiers may be decorated on type s or instruction s. - DecPrecisionLow, - DecPrecisionMedium, - DecPrecisionHigh, - - DecBlock, // basic in/out/uniform block, applied only to types of TypeStruct - DecBufferBlock, // shader storage buffer block - DecRowMajor, - DecColMajor, - DecGLSLShared, - DecGLSLStd140, - DecGLSLStd430, - DecGLSLPacked, - DecSmooth, - DecNoperspective, - DecFlat, - DecPatch, - DecCentroid, - DecSample, - DecInvariant, - DecRestrict, - DecAliased, - DecVolatile, - DecConstant, - DecCoherent, - DecNonwritable, - DecNonreadable, - DecUniform, - DecNoStaticUse, - - DecCPacked, - DecFPSaturatedConv, - - // these all take one additional operand - DecStream, - DecLocation, - DecComponent, - DecIndex, - DecBinding, - DecDescriptorSet, - DecOffset, - DecAlignment, - DecXfbBuffer, - DecStride, - DecBuiltIn, - DecFuncParamAttr, - DecFPRoundingMode, - DecFPFastMathMode, - DecLinkageType, - DecSpecId, - - DecCount // guard for validation, "default:" statements, etc. + DecorationPrecisionLow = 0, + DecorationPrecisionMedium = 1, + DecorationPrecisionHigh = 2, + DecorationBlock = 3, + DecorationBufferBlock = 4, + DecorationRowMajor = 5, + DecorationColMajor = 6, + DecorationGLSLShared = 7, + DecorationGLSLStd140 = 8, + DecorationGLSLStd430 = 9, + DecorationGLSLPacked = 10, + DecorationSmooth = 11, + DecorationNoperspective = 12, + DecorationFlat = 13, + DecorationPatch = 14, + DecorationCentroid = 15, + DecorationSample = 16, + DecorationInvariant = 17, + DecorationRestrict = 18, + DecorationAliased = 19, + DecorationVolatile = 20, + DecorationConstant = 21, + DecorationCoherent = 22, + DecorationNonwritable = 23, + DecorationNonreadable = 24, + DecorationUniform = 25, + DecorationNoStaticUse = 26, + DecorationCPacked = 27, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationAlignment = 36, + DecorationXfbBuffer = 37, + DecorationStride = 38, + DecorationBuiltIn = 39, + DecorationFuncParamAttr = 40, + DecorationFPRoundingMode = 41, + DecorationFPFastMathMode = 42, + DecorationLinkageAttributes = 43, + DecorationSpecId = 44, }; enum BuiltIn { - BuiltInPosition, - BuiltInPointSize, - BuiltInClipVertex, - BuiltInClipDistance, - BuiltInCullDistance, - BuiltInVertexId, - BuiltInInstanceId, - BuiltInPrimitiveId, - BuiltInInvocationId, - BuiltInLayer, - BuiltInViewportIndex, - BuiltInTessLevelOuter, - BuiltInTessLevelInner, - BuiltInTessCoord, - BuiltInPatchVertices, - BuiltInFragCoord, - BuiltInPointCoord, - BuiltInFrontFacing, - BuiltInSampleId, - BuiltInSamplePosition, - BuiltInSampleMask, - BuiltInFragColor, - BuiltInFragDepth, - BuiltInHelperInvocation, - - // OpenGL compute stage, OpenCL work item built-ins - BuiltInNumWorkgroups, // number of work-groups that will execute a kernel - BuiltInWorkgroupSize, // OpenCL number of local work-items - BuiltInWorkgroupId, // OpenCL work group id - BuiltInLocalInvocationId, // OpenCL local work item id (decorates a vector3 i32/i64) - BuiltInGlobalInvocationId, // OpenCL global work item id (decorates a vector3 i32/i64) - BuiltInLocalInvocationIndex, // not in use in OpenCL - BuiltInWorkDim, // OpenCL number of dimensions in use (decorates a scalar i32/i64) - BuiltInGlobalSize, // OpenCL number of global work items, per dimension (decorates a vector3 i32/i64) - BuiltInEnqueuedWorkgroupSize, // OpenCL 2.0 only, get local size - BuiltInGlobalOffset, // OpenCL offset values specified global_work_offset - BuiltInGlobalLinearId, // OpenCL 2.0 only, work items 1-dimensional global ID. - BuiltInWorkgroupLinearId, // OpenCL 2.0 only work items 1-dimensional local ID. - - // OpenCL 2.0 subgroups - BuiltInSubgroupSize, // Returns the number of work-items in the subgroup - BuiltInSubgroupMaxSize, // Returns the maximum size of a subgroup within the dispatch - BuiltInNumSubgroups, // Returns the maximum size of a subgroup within the dispatch - BuiltInNumEnqueuedSubgroups, // Returns the maximum size of a subgroup within the dispatch - BuiltInSubgroupId, // - BuiltInSubgroupLocalInvocationId, // Returns the unique work-item ID within the current subgroup - - BuiltInCount // guard for validation, "default:" statements, etc. -}; - -enum SelectControl { - SelectControlNone, - SelectControlFlatten, - SelectControlDontFlatten, - - SelectControlCount, // guard for validation, "default:" statements, etc. -}; - -enum LoopControl { - LoopControlNone, - LoopControlUnroll, - LoopControlDontUnroll, - - LoopControlCount, + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipVertex = 2, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragColor = 21, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInWorkgroupLinearId = 35, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, }; enum FunctionControlMask { - FunctionControlNone = 0x0, - FunctionControlInline = 0x1, - FunctionControlDontInline = 0x2, - FunctionControlPure = 0x4, - FunctionControlConst = 0x8, + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; - FunctionControlCount = 4, +enum MemorySemanticsShift { + MemorySemanticsRelaxedShift = 0, + MemorySemanticsSequentiallyConsistentShift = 1, + MemorySemanticsAcquireShift = 2, + MemorySemanticsReleaseShift = 3, + MemorySemanticsUniformMemoryShift = 4, + MemorySemanticsSubgroupMemoryShift = 5, + MemorySemanticsWorkgroupLocalMemoryShift = 6, + MemorySemanticsWorkgroupGlobalMemoryShift = 7, + MemorySemanticsAtomicCounterMemoryShift = 8, + MemorySemanticsImageMemoryShift = 9, }; enum MemorySemanticsMask { - MemorySemanticsRelaxed = 0x0001, - MemorySemanticsSequentiallyConsistent = 0x0002, - MemorySemanticsAcquire = 0x0004, - MemorySemanticsRelease = 0x0008, - - MemorySemanticsUniform = 0x0010, - MemorySemanticsSubgroup = 0x0020, - MemorySemanticsWorkgroupLocal = 0x0040, - MemorySemanticsWorkgroupGlobal = 0x0080, - MemorySemanticsAtomicCounter = 0x0100, - MemorySemanticsImage = 0x0200, - MemorySemanticsAllMemory = 0x03FF, + MemorySemanticsMaskNone = 0, + MemorySemanticsRelaxedMask = 0x00000001, + MemorySemanticsSequentiallyConsistentMask = 0x00000002, + MemorySemanticsAcquireMask = 0x00000004, + MemorySemanticsReleaseMask = 0x00000008, + MemorySemanticsUniformMemoryMask = 0x00000010, + MemorySemanticsSubgroupMemoryMask = 0x00000020, + MemorySemanticsWorkgroupLocalMemoryMask = 0x00000040, + MemorySemanticsWorkgroupGlobalMemoryMask = 0x00000080, + MemorySemanticsAtomicCounterMemoryMask = 0x00000100, + MemorySemanticsImageMemoryMask = 0x00000200, +}; - MemorySemanticsCount = 10 +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, }; enum MemoryAccessMask { - MemoryAccessVolatile = 0x0001, - MemoryAccessAligned = 0x0002, - - MemoryAccessCount = 2 + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, }; enum ExecutionScope { - ExecutionScopeCrossDevice, - ExecutionScopeDevice, - ExecutionScopeWorkgroup, - ExecutionScopeSubgroup, - - ExecutionScopeCount // guard for validation, "default:" statements, etc. + ExecutionScopeCrossDevice = 0, + ExecutionScopeDevice = 1, + ExecutionScopeWorkgroup = 2, + ExecutionScopeSubgroup = 3, }; enum GroupOperation { - GroupOpReduce, - GroupOpInclusiveScan, - GroupOpExclusiveScan, - - GroupOpCount + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, }; enum KernelEnqueueFlags { - EnqFlagNoWait, - EnqFlagWaitKernel, - EnqFlagWaitWaitWorgGroup, - - EnqFlagCount -}; - -enum KernelProfilingInfo { - ProfInfoCmdExecTime = 0x01, - ProfilingInfoCount = 1 -}; - -enum OpCode { - OpNop = 0, // Not used. - - OpSource, - OpSourceExtension, - OpExtension, - OpExtInstImport, - - OpMemoryModel, - OpEntryPoint, - OpExecutionMode, - - OpTypeVoid, - OpTypeBool, - OpTypeInt, - OpTypeFloat, - OpTypeVector, - OpTypeMatrix, - OpTypeSampler, - OpTypeFilter, - OpTypeArray, - OpTypeRuntimeArray, - OpTypeStruct, - OpTypeOpaque, - OpTypePointer, - OpTypeFunction, - OpTypeEvent, - OpTypeDeviceEvent, - OpTypeReserveId, - OpTypeQueue, - OpTypePipe, - - OpConstantTrue, - OpConstantFalse, - OpConstant, - OpConstantComposite, - OpConstantSampler, - OpConstantNullPointer, - OpConstantNullObject, - - OpSpecConstantTrue, - OpSpecConstantFalse, - OpSpecConstant, - OpSpecConstantComposite, - - OpVariable, - OpVariableArray, - - OpFunction, - OpFunctionParameter, - OpFunctionEnd, - OpFunctionCall, - - OpExtInst, - - OpUndef, - - OpLoad, - OpStore, - - OpPhi, - - OpDecorationGroup, - OpDecorate, - OpMemberDecorate, - OpGroupDecorate, - OpGroupMemberDecorate, - - OpName, - OpMemberName, - OpString, - OpLine, - - OpVectorExtractDynamic, - OpVectorInsertDynamic, - OpVectorShuffle, - - OpCompositeConstruct, - OpCompositeExtract, - OpCompositeInsert, - - OpCopyObject, - OpCopyMemory, - OpCopyMemorySized, - - OpSampler, - - OpTextureSample, - OpTextureSampleDref, - OpTextureSampleLod, - OpTextureSampleProj, - OpTextureSampleGrad, - OpTextureSampleOffset, - OpTextureSampleProjLod, - OpTextureSampleProjGrad, - OpTextureSampleLodOffset, - OpTextureSampleProjOffset, - OpTextureSampleGradOffset, - OpTextureSampleProjLodOffset, - OpTextureSampleProjGradOffset, - - OpTextureFetchTexel, - OpTextureFetchTexelOffset, - OpTextureFetchSample, - OpTextureFetchBuffer, - OpTextureGather, - OpTextureGatherOffset, - OpTextureGatherOffsets, - - OpTextureQuerySizeLod, - OpTextureQuerySize, - OpTextureQueryLod, - OpTextureQueryLevels, - OpTextureQuerySamples, - - OpAccessChain, - OpInBoundsAccessChain, - - OpSNegate, - OpFNegate, - - OpNot, - - OpAny, - OpAll, - - OpConvertFToU, - OpConvertFToS, - OpConvertSToF, - OpConvertUToF, - OpUConvert, - OpSConvert, - OpFConvert, - OpConvertPtrToU, - OpConvertUToPtr, - OpPtrCastToGeneric, // cast a pointer storage class to be in storage generic - OpGenericCastToPtr, // cast a pointer in the generic storage class generic to another storage class - OpBitcast, - - OpTranspose, - - OpIsNan, - OpIsInf, - OpIsFinite, - OpIsNormal, - OpSignBitSet, - OpLessOrGreater, - OpOrdered, - OpUnordered, - - OpArrayLength, - - OpIAdd, - OpFAdd, - OpISub, - OpFSub, - OpIMul, - OpFMul, - OpUDiv, - OpSDiv, - OpFDiv, - - OpUMod, - OpSRem, - OpSMod, - OpFRem, - OpFMod, - - OpVectorTimesScalar, - OpMatrixTimesScalar, - OpVectorTimesMatrix, - OpMatrixTimesVector, - OpMatrixTimesMatrix, - OpOuterProduct, - - OpDot, - - OpShiftRightLogical, - OpShiftRightArithmetic, - OpShiftLeftLogical, - OpLogicalOr, - OpLogicalXor, - OpLogicalAnd, - - OpBitwiseOr, - OpBitwiseXor, - OpBitwiseAnd, - - OpSelect, - - OpIEqual, - OpFOrdEqual, - OpFUnordEqual, - - OpINotEqual, - OpFOrdNotEqual, - OpFUnordNotEqual, - - OpULessThan, - OpSLessThan, - OpFOrdLessThan, - OpFUnordLessThan, - - OpUGreaterThan, - OpSGreaterThan, - OpFOrdGreaterThan, - OpFUnordGreaterThan, - - OpULessThanEqual, - OpSLessThanEqual, - OpFOrdLessThanEqual, - OpFUnordLessThanEqual, - - OpUGreaterThanEqual, - OpSGreaterThanEqual, - OpFOrdGreaterThanEqual, - OpFUnordGreaterThanEqual, - - OpDPdx, - OpDPdy, - OpFwidth, - OpDPdxFine, - OpDPdyFine, - OpFwidthFine, - OpDPdxCoarse, - OpDPdyCoarse, - OpFwidthCoarse, - - OpEmitVertex, - OpEndPrimitive, - OpEmitStreamVertex, - OpEndStreamPrimitive, - - OpControlBarrier, - OpMemoryBarrier, - - OpImagePointer, - - OpAtomicInit, - OpAtomicLoad, - OpAtomicStore, - OpAtomicExchange, - OpAtomicCompareExchange, - OpAtomicCompareExchangeWeak, - OpAtomicIIncrement, - OpAtomicIDecrement, - OpAtomicIAdd, - OpAtomicISub, - OpAtomicUMin, - OpAtomicUMax, - OpAtomicAnd, - OpAtomicOr, - OpAtomicXor, - - OpLoopMerge, - OpSelectionMerge, - OpLabel, - OpBranch, - OpBranchConditional, - OpSwitch, - OpKill, - OpReturn, - OpReturnValue, - - OpUnreachable, - - OpLifetimeStart, - OpLifetimeStop, - - OpCompileFlag, - - OpAsyncGroupCopy, - OpWaitGroupEvents, - - OpGroupAll, - OpGroupAny, - OpGroupBroadcast, - - OpGroupIAdd, - OpGroupFAdd, - OpGroupFMin, - OpGroupUMin, - OpGroupSMin, - OpGroupFMax, - OpGroupUMax, - OpGroupSMax, - - OpGenericCastToPtrExplicit, - OpGenericPtrMemSemantics, - - OpReadPipe, - OpWritePipe, - OpReservedReadPipe, - OpReservedWritePipe, - OpReserveReadPipePackets, - OpReserveWritePipePackets, - OpCommitReadPipe, - OpCommitWritePipe, - OpIsValidReserveId, - OpGetNumPipePackets, - OpGetMaxPipePackets, - OpGroupReserveReadPipePackets, - OpGroupReserveWritePipePackets, - OpGroupCommitReadPipe, - OpGroupCommitWritePipe, - - OpEnqueueMarker, - OpEnqueueKernel, - OpGetKernelNDrangeSubGroupCount, - OpGetKernelNDrangeMaxSubGroupSize, - - OpGetKernelWorkGroupSize, - OpGetKernelPreferredWorkGroupSizeMultiple, - - OpRetainEvent, - OpReleaseEvent, - - OpCreateUserEvent, - OpIsValidEvent, - OpSetUserEventStatus, - OpCaptureEventProfilingInfo, - OpGetDefaultQueue, - - OpBuildNDRange, - - OpCount // guard for validation, "default:" statements, etc. + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Op { + OpNop = 0, + OpSource = 1, + OpSourceExtension = 2, + OpExtension = 3, + OpExtInstImport = 4, + OpMemoryModel = 5, + OpEntryPoint = 6, + OpExecutionMode = 7, + OpTypeVoid = 8, + OpTypeBool = 9, + OpTypeInt = 10, + OpTypeFloat = 11, + OpTypeVector = 12, + OpTypeMatrix = 13, + OpTypeSampler = 14, + OpTypeFilter = 15, + OpTypeArray = 16, + OpTypeRuntimeArray = 17, + OpTypeStruct = 18, + OpTypeOpaque = 19, + OpTypePointer = 20, + OpTypeFunction = 21, + OpTypeEvent = 22, + OpTypeDeviceEvent = 23, + OpTypeReserveId = 24, + OpTypeQueue = 25, + OpTypePipe = 26, + OpConstantTrue = 27, + OpConstantFalse = 28, + OpConstant = 29, + OpConstantComposite = 30, + OpConstantSampler = 31, + OpConstantNullPointer = 32, + OpConstantNullObject = 33, + OpSpecConstantTrue = 34, + OpSpecConstantFalse = 35, + OpSpecConstant = 36, + OpSpecConstantComposite = 37, + OpVariable = 38, + OpVariableArray = 39, + OpFunction = 40, + OpFunctionParameter = 41, + OpFunctionEnd = 42, + OpFunctionCall = 43, + OpExtInst = 44, + OpUndef = 45, + OpLoad = 46, + OpStore = 47, + OpPhi = 48, + OpDecorationGroup = 49, + OpDecorate = 50, + OpMemberDecorate = 51, + OpGroupDecorate = 52, + OpGroupMemberDecorate = 53, + OpName = 54, + OpMemberName = 55, + OpString = 56, + OpLine = 57, + OpVectorExtractDynamic = 58, + OpVectorInsertDynamic = 59, + OpVectorShuffle = 60, + OpCompositeConstruct = 61, + OpCompositeExtract = 62, + OpCompositeInsert = 63, + OpCopyObject = 64, + OpCopyMemory = 65, + OpCopyMemorySized = 66, + OpSampler = 67, + OpTextureSample = 68, + OpTextureSampleDref = 69, + OpTextureSampleLod = 70, + OpTextureSampleProj = 71, + OpTextureSampleGrad = 72, + OpTextureSampleOffset = 73, + OpTextureSampleProjLod = 74, + OpTextureSampleProjGrad = 75, + OpTextureSampleLodOffset = 76, + OpTextureSampleProjOffset = 77, + OpTextureSampleGradOffset = 78, + OpTextureSampleProjLodOffset = 79, + OpTextureSampleProjGradOffset = 80, + OpTextureFetchTexelLod = 81, + OpTextureFetchTexelOffset = 82, + OpTextureFetchSample = 83, + OpTextureFetchTexel = 84, + OpTextureGather = 85, + OpTextureGatherOffset = 86, + OpTextureGatherOffsets = 87, + OpTextureQuerySizeLod = 88, + OpTextureQuerySize = 89, + OpTextureQueryLod = 90, + OpTextureQueryLevels = 91, + OpTextureQuerySamples = 92, + OpAccessChain = 93, + OpInBoundsAccessChain = 94, + OpSNegate = 95, + OpFNegate = 96, + OpNot = 97, + OpAny = 98, + OpAll = 99, + OpConvertFToU = 100, + OpConvertFToS = 101, + OpConvertSToF = 102, + OpConvertUToF = 103, + OpUConvert = 104, + OpSConvert = 105, + OpFConvert = 106, + OpConvertPtrToU = 107, + OpConvertUToPtr = 108, + OpPtrCastToGeneric = 109, + OpGenericCastToPtr = 110, + OpBitcast = 111, + OpTranspose = 112, + OpIsNan = 113, + OpIsInf = 114, + OpIsFinite = 115, + OpIsNormal = 116, + OpSignBitSet = 117, + OpLessOrGreater = 118, + OpOrdered = 119, + OpUnordered = 120, + OpArrayLength = 121, + OpIAdd = 122, + OpFAdd = 123, + OpISub = 124, + OpFSub = 125, + OpIMul = 126, + OpFMul = 127, + OpUDiv = 128, + OpSDiv = 129, + OpFDiv = 130, + OpUMod = 131, + OpSRem = 132, + OpSMod = 133, + OpFRem = 134, + OpFMod = 135, + OpVectorTimesScalar = 136, + OpMatrixTimesScalar = 137, + OpVectorTimesMatrix = 138, + OpMatrixTimesVector = 139, + OpMatrixTimesMatrix = 140, + OpOuterProduct = 141, + OpDot = 142, + OpShiftRightLogical = 143, + OpShiftRightArithmetic = 144, + OpShiftLeftLogical = 145, + OpLogicalOr = 146, + OpLogicalXor = 147, + OpLogicalAnd = 148, + OpBitwiseOr = 149, + OpBitwiseXor = 150, + OpBitwiseAnd = 151, + OpSelect = 152, + OpIEqual = 153, + OpFOrdEqual = 154, + OpFUnordEqual = 155, + OpINotEqual = 156, + OpFOrdNotEqual = 157, + OpFUnordNotEqual = 158, + OpULessThan = 159, + OpSLessThan = 160, + OpFOrdLessThan = 161, + OpFUnordLessThan = 162, + OpUGreaterThan = 163, + OpSGreaterThan = 164, + OpFOrdGreaterThan = 165, + OpFUnordGreaterThan = 166, + OpULessThanEqual = 167, + OpSLessThanEqual = 168, + OpFOrdLessThanEqual = 169, + OpFUnordLessThanEqual = 170, + OpUGreaterThanEqual = 171, + OpSGreaterThanEqual = 172, + OpFOrdGreaterThanEqual = 173, + OpFUnordGreaterThanEqual = 174, + OpDPdx = 175, + OpDPdy = 176, + OpFwidth = 177, + OpDPdxFine = 178, + OpDPdyFine = 179, + OpFwidthFine = 180, + OpDPdxCoarse = 181, + OpDPdyCoarse = 182, + OpFwidthCoarse = 183, + OpEmitVertex = 184, + OpEndPrimitive = 185, + OpEmitStreamVertex = 186, + OpEndStreamPrimitive = 187, + OpControlBarrier = 188, + OpMemoryBarrier = 189, + OpImagePointer = 190, + OpAtomicInit = 191, + OpAtomicLoad = 192, + OpAtomicStore = 193, + OpAtomicExchange = 194, + OpAtomicCompareExchange = 195, + OpAtomicCompareExchangeWeak = 196, + OpAtomicIIncrement = 197, + OpAtomicIDecrement = 198, + OpAtomicIAdd = 199, + OpAtomicISub = 200, + OpAtomicUMin = 201, + OpAtomicUMax = 202, + OpAtomicAnd = 203, + OpAtomicOr = 204, + OpAtomicXor = 205, + OpLoopMerge = 206, + OpSelectionMerge = 207, + OpLabel = 208, + OpBranch = 209, + OpBranchConditional = 210, + OpSwitch = 211, + OpKill = 212, + OpReturn = 213, + OpReturnValue = 214, + OpUnreachable = 215, + OpLifetimeStart = 216, + OpLifetimeStop = 217, + OpCompileFlag = 218, + OpAsyncGroupCopy = 219, + OpWaitGroupEvents = 220, + OpGroupAll = 221, + OpGroupAny = 222, + OpGroupBroadcast = 223, + OpGroupIAdd = 224, + OpGroupFAdd = 225, + OpGroupFMin = 226, + OpGroupUMin = 227, + OpGroupSMin = 228, + OpGroupFMax = 229, + OpGroupUMax = 230, + OpGroupSMax = 231, + OpGenericCastToPtrExplicit = 232, + OpGenericPtrMemSemantics = 233, + OpReadPipe = 234, + OpWritePipe = 235, + OpReservedReadPipe = 236, + OpReservedWritePipe = 237, + OpReserveReadPipePackets = 238, + OpReserveWritePipePackets = 239, + OpCommitReadPipe = 240, + OpCommitWritePipe = 241, + OpIsValidReserveId = 242, + OpGetNumPipePackets = 243, + OpGetMaxPipePackets = 244, + OpGroupReserveReadPipePackets = 245, + OpGroupReserveWritePipePackets = 246, + OpGroupCommitReadPipe = 247, + OpGroupCommitWritePipe = 248, + OpEnqueueMarker = 249, + OpEnqueueKernel = 250, + OpGetKernelNDrangeSubGroupCount = 251, + OpGetKernelNDrangeMaxSubGroupSize = 252, + OpGetKernelWorkGroupSize = 253, + OpGetKernelPreferredWorkGroupSizeMultiple = 254, + OpRetainEvent = 255, + OpReleaseEvent = 256, + OpCreateUserEvent = 257, + OpIsValidEvent = 258, + OpSetUserEventStatus = 259, + OpCaptureEventProfilingInfo = 260, + OpGetDefaultQueue = 261, + OpBuildNDRange = 262, + OpSatConvertSToU = 263, + OpSatConvertUToS = 264, + OpAtomicIMin = 265, + OpAtomicIMax = 266, }; -#ifdef __cplusplus }; // end namespace spv -#endif -#endif // spirv_H +#endif // #ifdef __cplusplus + + +#ifndef __cplusplus + +const int SpvMagicNumber = 0x07230203; +const int SpvVersion = 99; + +typedef unsigned int SpvId; + +const unsigned int SpvOpCodeMask = 0xFFFF; +const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL = 3, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL12 = 2, + SpvMemoryModelOpenCL20 = 3, + SpvMemoryModelOpenCL21 = 4, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeEarlyFragmentTests = 8, + SpvExecutionModePointMode = 9, + SpvExecutionModeXfb = 10, + SpvExecutionModeDepthReplacing = 11, + SpvExecutionModeDepthAny = 12, + SpvExecutionModeDepthGreater = 13, + SpvExecutionModeDepthLess = 14, + SpvExecutionModeDepthUnchanged = 15, + SpvExecutionModeLocalSize = 16, + SpvExecutionModeLocalSizeHint = 17, + SpvExecutionModeInputPoints = 18, + SpvExecutionModeInputLines = 19, + SpvExecutionModeInputLinesAdjacency = 20, + SpvExecutionModeInputTriangles = 21, + SpvExecutionModeInputTrianglesAdjacency = 22, + SpvExecutionModeInputQuads = 23, + SpvExecutionModeInputIsolines = 24, + SpvExecutionModeOutputVertices = 25, + SpvExecutionModeOutputPoints = 26, + SpvExecutionModeOutputLineStrip = 27, + SpvExecutionModeOutputTriangleStrip = 28, + SpvExecutionModeVecTypeHint = 29, + SpvExecutionModeContractionOff = 30, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroupLocal = 4, + SpvStorageClassWorkgroupGlobal = 5, + SpvStorageClassPrivateGlobal = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPrivate = 9, + SpvStorageClassAtomicCounter = 10, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, +} SpvSamplerFilterMode; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeSVM = 6, + SpvFunctionParameterAttributeNoWrite = 7, + SpvFunctionParameterAttributeNoReadWrite = 8, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationPrecisionLow = 0, + SpvDecorationPrecisionMedium = 1, + SpvDecorationPrecisionHigh = 2, + SpvDecorationBlock = 3, + SpvDecorationBufferBlock = 4, + SpvDecorationRowMajor = 5, + SpvDecorationColMajor = 6, + SpvDecorationGLSLShared = 7, + SpvDecorationGLSLStd140 = 8, + SpvDecorationGLSLStd430 = 9, + SpvDecorationGLSLPacked = 10, + SpvDecorationSmooth = 11, + SpvDecorationNoperspective = 12, + SpvDecorationFlat = 13, + SpvDecorationPatch = 14, + SpvDecorationCentroid = 15, + SpvDecorationSample = 16, + SpvDecorationInvariant = 17, + SpvDecorationRestrict = 18, + SpvDecorationAliased = 19, + SpvDecorationVolatile = 20, + SpvDecorationConstant = 21, + SpvDecorationCoherent = 22, + SpvDecorationNonwritable = 23, + SpvDecorationNonreadable = 24, + SpvDecorationUniform = 25, + SpvDecorationNoStaticUse = 26, + SpvDecorationCPacked = 27, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationAlignment = 36, + SpvDecorationXfbBuffer = 37, + SpvDecorationStride = 38, + SpvDecorationBuiltIn = 39, + SpvDecorationFuncParamAttr = 40, + SpvDecorationFPRoundingMode = 41, + SpvDecorationFPFastMathMode = 42, + SpvDecorationLinkageAttributes = 43, + SpvDecorationSpecId = 44, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipVertex = 2, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragColor = 21, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInWorkgroupLinearId = 35, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsRelaxedShift = 0, + SpvMemorySemanticsSequentiallyConsistentShift = 1, + SpvMemorySemanticsAcquireShift = 2, + SpvMemorySemanticsReleaseShift = 3, + SpvMemorySemanticsUniformMemoryShift = 4, + SpvMemorySemanticsSubgroupMemoryShift = 5, + SpvMemorySemanticsWorkgroupLocalMemoryShift = 6, + SpvMemorySemanticsWorkgroupGlobalMemoryShift = 7, + SpvMemorySemanticsAtomicCounterMemoryShift = 8, + SpvMemorySemanticsImageMemoryShift = 9, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsRelaxedMask = 0x00000001, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000002, + SpvMemorySemanticsAcquireMask = 0x00000004, + SpvMemorySemanticsReleaseMask = 0x00000008, + SpvMemorySemanticsUniformMemoryMask = 0x00000010, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000020, + SpvMemorySemanticsWorkgroupLocalMemoryMask = 0x00000040, + SpvMemorySemanticsWorkgroupGlobalMemoryMask = 0x00000080, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000100, + SpvMemorySemanticsImageMemoryMask = 0x00000200, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, +} SpvMemoryAccessMask; + +typedef enum SpvExecutionScope_ { + SpvExecutionScopeCrossDevice = 0, + SpvExecutionScopeDevice = 1, + SpvExecutionScopeWorkgroup = 2, + SpvExecutionScopeSubgroup = 3, +} SpvExecutionScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpSource = 1, + SpvOpSourceExtension = 2, + SpvOpExtension = 3, + SpvOpExtInstImport = 4, + SpvOpMemoryModel = 5, + SpvOpEntryPoint = 6, + SpvOpExecutionMode = 7, + SpvOpTypeVoid = 8, + SpvOpTypeBool = 9, + SpvOpTypeInt = 10, + SpvOpTypeFloat = 11, + SpvOpTypeVector = 12, + SpvOpTypeMatrix = 13, + SpvOpTypeSampler = 14, + SpvOpTypeFilter = 15, + SpvOpTypeArray = 16, + SpvOpTypeRuntimeArray = 17, + SpvOpTypeStruct = 18, + SpvOpTypeOpaque = 19, + SpvOpTypePointer = 20, + SpvOpTypeFunction = 21, + SpvOpTypeEvent = 22, + SpvOpTypeDeviceEvent = 23, + SpvOpTypeReserveId = 24, + SpvOpTypeQueue = 25, + SpvOpTypePipe = 26, + SpvOpConstantTrue = 27, + SpvOpConstantFalse = 28, + SpvOpConstant = 29, + SpvOpConstantComposite = 30, + SpvOpConstantSampler = 31, + SpvOpConstantNullPointer = 32, + SpvOpConstantNullObject = 33, + SpvOpSpecConstantTrue = 34, + SpvOpSpecConstantFalse = 35, + SpvOpSpecConstant = 36, + SpvOpSpecConstantComposite = 37, + SpvOpVariable = 38, + SpvOpVariableArray = 39, + SpvOpFunction = 40, + SpvOpFunctionParameter = 41, + SpvOpFunctionEnd = 42, + SpvOpFunctionCall = 43, + SpvOpExtInst = 44, + SpvOpUndef = 45, + SpvOpLoad = 46, + SpvOpStore = 47, + SpvOpPhi = 48, + SpvOpDecorationGroup = 49, + SpvOpDecorate = 50, + SpvOpMemberDecorate = 51, + SpvOpGroupDecorate = 52, + SpvOpGroupMemberDecorate = 53, + SpvOpName = 54, + SpvOpMemberName = 55, + SpvOpString = 56, + SpvOpLine = 57, + SpvOpVectorExtractDynamic = 58, + SpvOpVectorInsertDynamic = 59, + SpvOpVectorShuffle = 60, + SpvOpCompositeConstruct = 61, + SpvOpCompositeExtract = 62, + SpvOpCompositeInsert = 63, + SpvOpCopyObject = 64, + SpvOpCopyMemory = 65, + SpvOpCopyMemorySized = 66, + SpvOpSampler = 67, + SpvOpTextureSample = 68, + SpvOpTextureSampleDref = 69, + SpvOpTextureSampleLod = 70, + SpvOpTextureSampleProj = 71, + SpvOpTextureSampleGrad = 72, + SpvOpTextureSampleOffset = 73, + SpvOpTextureSampleProjLod = 74, + SpvOpTextureSampleProjGrad = 75, + SpvOpTextureSampleLodOffset = 76, + SpvOpTextureSampleProjOffset = 77, + SpvOpTextureSampleGradOffset = 78, + SpvOpTextureSampleProjLodOffset = 79, + SpvOpTextureSampleProjGradOffset = 80, + SpvOpTextureFetchTexelLod = 81, + SpvOpTextureFetchTexelOffset = 82, + SpvOpTextureFetchSample = 83, + SpvOpTextureFetchTexel = 84, + SpvOpTextureGather = 85, + SpvOpTextureGatherOffset = 86, + SpvOpTextureGatherOffsets = 87, + SpvOpTextureQuerySizeLod = 88, + SpvOpTextureQuerySize = 89, + SpvOpTextureQueryLod = 90, + SpvOpTextureQueryLevels = 91, + SpvOpTextureQuerySamples = 92, + SpvOpAccessChain = 93, + SpvOpInBoundsAccessChain = 94, + SpvOpSNegate = 95, + SpvOpFNegate = 96, + SpvOpNot = 97, + SpvOpAny = 98, + SpvOpAll = 99, + SpvOpConvertFToU = 100, + SpvOpConvertFToS = 101, + SpvOpConvertSToF = 102, + SpvOpConvertUToF = 103, + SpvOpUConvert = 104, + SpvOpSConvert = 105, + SpvOpFConvert = 106, + SpvOpConvertPtrToU = 107, + SpvOpConvertUToPtr = 108, + SpvOpPtrCastToGeneric = 109, + SpvOpGenericCastToPtr = 110, + SpvOpBitcast = 111, + SpvOpTranspose = 112, + SpvOpIsNan = 113, + SpvOpIsInf = 114, + SpvOpIsFinite = 115, + SpvOpIsNormal = 116, + SpvOpSignBitSet = 117, + SpvOpLessOrGreater = 118, + SpvOpOrdered = 119, + SpvOpUnordered = 120, + SpvOpArrayLength = 121, + SpvOpIAdd = 122, + SpvOpFAdd = 123, + SpvOpISub = 124, + SpvOpFSub = 125, + SpvOpIMul = 126, + SpvOpFMul = 127, + SpvOpUDiv = 128, + SpvOpSDiv = 129, + SpvOpFDiv = 130, + SpvOpUMod = 131, + SpvOpSRem = 132, + SpvOpSMod = 133, + SpvOpFRem = 134, + SpvOpFMod = 135, + SpvOpVectorTimesScalar = 136, + SpvOpMatrixTimesScalar = 137, + SpvOpVectorTimesMatrix = 138, + SpvOpMatrixTimesVector = 139, + SpvOpMatrixTimesMatrix = 140, + SpvOpOuterProduct = 141, + SpvOpDot = 142, + SpvOpShiftRightLogical = 143, + SpvOpShiftRightArithmetic = 144, + SpvOpShiftLeftLogical = 145, + SpvOpLogicalOr = 146, + SpvOpLogicalXor = 147, + SpvOpLogicalAnd = 148, + SpvOpBitwiseOr = 149, + SpvOpBitwiseXor = 150, + SpvOpBitwiseAnd = 151, + SpvOpSelect = 152, + SpvOpIEqual = 153, + SpvOpFOrdEqual = 154, + SpvOpFUnordEqual = 155, + SpvOpINotEqual = 156, + SpvOpFOrdNotEqual = 157, + SpvOpFUnordNotEqual = 158, + SpvOpULessThan = 159, + SpvOpSLessThan = 160, + SpvOpFOrdLessThan = 161, + SpvOpFUnordLessThan = 162, + SpvOpUGreaterThan = 163, + SpvOpSGreaterThan = 164, + SpvOpFOrdGreaterThan = 165, + SpvOpFUnordGreaterThan = 166, + SpvOpULessThanEqual = 167, + SpvOpSLessThanEqual = 168, + SpvOpFOrdLessThanEqual = 169, + SpvOpFUnordLessThanEqual = 170, + SpvOpUGreaterThanEqual = 171, + SpvOpSGreaterThanEqual = 172, + SpvOpFOrdGreaterThanEqual = 173, + SpvOpFUnordGreaterThanEqual = 174, + SpvOpDPdx = 175, + SpvOpDPdy = 176, + SpvOpFwidth = 177, + SpvOpDPdxFine = 178, + SpvOpDPdyFine = 179, + SpvOpFwidthFine = 180, + SpvOpDPdxCoarse = 181, + SpvOpDPdyCoarse = 182, + SpvOpFwidthCoarse = 183, + SpvOpEmitVertex = 184, + SpvOpEndPrimitive = 185, + SpvOpEmitStreamVertex = 186, + SpvOpEndStreamPrimitive = 187, + SpvOpControlBarrier = 188, + SpvOpMemoryBarrier = 189, + SpvOpImagePointer = 190, + SpvOpAtomicInit = 191, + SpvOpAtomicLoad = 192, + SpvOpAtomicStore = 193, + SpvOpAtomicExchange = 194, + SpvOpAtomicCompareExchange = 195, + SpvOpAtomicCompareExchangeWeak = 196, + SpvOpAtomicIIncrement = 197, + SpvOpAtomicIDecrement = 198, + SpvOpAtomicIAdd = 199, + SpvOpAtomicISub = 200, + SpvOpAtomicUMin = 201, + SpvOpAtomicUMax = 202, + SpvOpAtomicAnd = 203, + SpvOpAtomicOr = 204, + SpvOpAtomicXor = 205, + SpvOpLoopMerge = 206, + SpvOpSelectionMerge = 207, + SpvOpLabel = 208, + SpvOpBranch = 209, + SpvOpBranchConditional = 210, + SpvOpSwitch = 211, + SpvOpKill = 212, + SpvOpReturn = 213, + SpvOpReturnValue = 214, + SpvOpUnreachable = 215, + SpvOpLifetimeStart = 216, + SpvOpLifetimeStop = 217, + SpvOpCompileFlag = 218, + SpvOpAsyncGroupCopy = 219, + SpvOpWaitGroupEvents = 220, + SpvOpGroupAll = 221, + SpvOpGroupAny = 222, + SpvOpGroupBroadcast = 223, + SpvOpGroupIAdd = 224, + SpvOpGroupFAdd = 225, + SpvOpGroupFMin = 226, + SpvOpGroupUMin = 227, + SpvOpGroupSMin = 228, + SpvOpGroupFMax = 229, + SpvOpGroupUMax = 230, + SpvOpGroupSMax = 231, + SpvOpGenericCastToPtrExplicit = 232, + SpvOpGenericPtrMemSemantics = 233, + SpvOpReadPipe = 234, + SpvOpWritePipe = 235, + SpvOpReservedReadPipe = 236, + SpvOpReservedWritePipe = 237, + SpvOpReserveReadPipePackets = 238, + SpvOpReserveWritePipePackets = 239, + SpvOpCommitReadPipe = 240, + SpvOpCommitWritePipe = 241, + SpvOpIsValidReserveId = 242, + SpvOpGetNumPipePackets = 243, + SpvOpGetMaxPipePackets = 244, + SpvOpGroupReserveReadPipePackets = 245, + SpvOpGroupReserveWritePipePackets = 246, + SpvOpGroupCommitReadPipe = 247, + SpvOpGroupCommitWritePipe = 248, + SpvOpEnqueueMarker = 249, + SpvOpEnqueueKernel = 250, + SpvOpGetKernelNDrangeSubGroupCount = 251, + SpvOpGetKernelNDrangeMaxSubGroupSize = 252, + SpvOpGetKernelWorkGroupSize = 253, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 254, + SpvOpRetainEvent = 255, + SpvOpReleaseEvent = 256, + SpvOpCreateUserEvent = 257, + SpvOpIsValidEvent = 258, + SpvOpSetUserEventStatus = 259, + SpvOpCaptureEventProfilingInfo = 260, + SpvOpGetDefaultQueue = 261, + SpvOpBuildNDRange = 262, + SpvOpSatConvertSToU = 263, + SpvOpSatConvertUToS = 264, + SpvOpAtomicIMin = 265, + SpvOpAtomicIMax = 266, +} SpvOp; + +#endif // #ifndef __cplusplus + +#endif // #ifndef spirv_H -- cgit v1.2.3 From 9761fdd2636bbd0bc03049adb3f732e0e92b8160 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Mon, 11 May 2015 09:34:20 -0700 Subject: Windows: Fix build from recent loader changes --- loader/CMakeLists.txt | 2 +- vk-generate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 9c1c2314..6365e8d1 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -12,7 +12,7 @@ if (WIN32) add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c table_ops.h gpa_helper.h vulkan.def) set_target_properties(vulkan PROPERTIES LINK_FLAGS "/DEF:${PROJECT_SOURCE_DIR}/loader/vulkan.def") - add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c dispatch.c table_ops.h gpa_helper.h) + add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c trampoline.c table_ops.h gpa_helper.h) set_target_properties(VKstatic PROPERTIES OUTPUT_NAME VKstatic) target_link_libraries(vulkan) endif() diff --git a/vk-generate.py b/vk-generate.py index 28d176b0..00327b75 100755 --- a/vk-generate.py +++ b/vk-generate.py @@ -243,7 +243,7 @@ class LayerInterceptProcSubcommand(Subcommand): # we could get the list from argv if wanted self.intercepted = [proto.name for proto in self.protos - if proto.name not in ["EnumeratePhysicalDevices"]] + if proto.name not in ["EnumeratePhysicalDevices", "GetInstanceProcAddr"]] for proto in self.protos: if proto.name == "GetProcAddr": -- cgit v1.2.3 From 78c72a600eda3bf4ecac9eb3164477cdaf6b71fa Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 9 May 2015 10:31:21 +1200 Subject: layers: remove assumption that there's a glslang source tree alongside We have an in-tree spirv.h now, just use that. --- layers/CMakeLists.txt | 1 - layers/shader_checker.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index ff746a0d..6988d8d8 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -38,7 +38,6 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../loader - ${CMAKE_CURRENT_SOURCE_DIR}/../../glslang ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index bd9a62e5..e56ad9da 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -38,7 +38,7 @@ // being used: #include "loader_platform.h" -#include "SPIRV/spirv.h" +#include "spirv/spirv.h" static std::unordered_map tableMap; -- cgit v1.2.3 From 06135b6641f8e9fee8d896d4eca76ca14fdecb31 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 5 May 2015 11:34:14 +1200 Subject: shader_checker: fix fs output/cb attachment walking after assert fixes --- layers/shader_checker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index e56ad9da..cb545d55 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -670,7 +670,7 @@ validate_fs_outputs_against_cb(shader_source const *fs, VkPipelineCbStateCreateI * are currently dense, but the parallel with matching between shader stages is nice. */ - while (outputs.size() > 0 && (it != outputs.end() || attachment < cb->attachmentCount)) { + while ((outputs.size() > 0 && it != outputs.end()) || attachment < cb->attachmentCount) { if (attachment == cb->attachmentCount || it->first < attachment) { sprintf(str, "FS writes to output location %d with no matching attachment", it->first); layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str); -- cgit v1.2.3 From f5959dbbeaa036de11313c44545469eeada09b5c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 4 May 2015 14:04:06 +1200 Subject: shader_checker: add helper to walk a type tree and return the basic type --- layers/shader_checker.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index cb545d55..bb3b9225 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -584,6 +584,38 @@ get_format_type(VkFormat fmt) { } +/* characterizes a SPIR-V type appearing in an interface to a FF stage, + * for comparison to a VkFormat's characterization above. */ +static unsigned +get_fundamental_type(shader_source const *src, unsigned type) +{ + auto type_def_it = src->type_def_index.find(type); + + if (type_def_it == src->type_def_index.end()) { + return FORMAT_TYPE_UNDEFINED; + } + + unsigned int const *code = (unsigned int const *)&src->words[type_def_it->second]; + unsigned opcode = code[0] & 0x0ffffu; + switch (opcode) { + case spv::OpTypeInt: + return code[3] ? FORMAT_TYPE_SINT : FORMAT_TYPE_UINT; + case spv::OpTypeFloat: + return FORMAT_TYPE_FLOAT; + case spv::OpTypeVector: + return get_fundamental_type(src, code[2]); + case spv::OpTypeMatrix: + return get_fundamental_type(src, code[2]); + case spv::OpTypeArray: + return get_fundamental_type(src, code[2]); + case spv::OpTypePointer: + return get_fundamental_type(src, code[3]); + default: + return FORMAT_TYPE_UNDEFINED; + } +} + + static void validate_vi_against_vs_inputs(VkPipelineVertexInputCreateInfo const *vi, shader_source const *vs) { -- cgit v1.2.3 From c353f05d730d64a43aaa227a5c995be2bb360e9d Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 4 May 2015 14:04:24 +1200 Subject: shader_checker: add type checking between VF and VS --- layers/shader_checker.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index bb3b9225..a24eb957 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -33,6 +33,7 @@ #include "vkLayer.h" #include "layers_config.h" #include "layers_msg.h" +#include "vk_enum_string_helper.h" #include "shader_checker.h" // The following is #included again to catch certain OS-specific functions // being used: @@ -652,7 +653,18 @@ validate_vi_against_vs_inputs(VkPipelineVertexInputCreateInfo const *vi, shader_ it_b++; } else { - /* TODO: type check */ + unsigned attrib_type = get_format_type(it_a->second->format); + unsigned input_type = get_fundamental_type(vs, it_b->second.type_id); + + /* type checking */ + if (attrib_type != FORMAT_TYPE_UNDEFINED && input_type != FORMAT_TYPE_UNDEFINED && attrib_type != input_type) { + char vs_type[1024]; + describe_type(vs_type, vs, it_b->second.type_id); + sprintf(str, "Attribute type of `%s` at location %d does not match VS input type of `%s`", + string_VkFormat(it_a->second->format), a_first, vs_type); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str); + } + /* OK! */ it_a++; it_b++; -- cgit v1.2.3 From 4edb1b973e2b35c5fce863cebafcbaf40474e29d Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 4 May 2015 14:20:10 +1200 Subject: shader_checker: check types between FS output and CB --- layers/shader_checker.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index a24eb957..8e08b372 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -726,8 +726,19 @@ validate_fs_outputs_against_cb(shader_source const *fs, VkPipelineCbStateCreateI attachment++; } else { + unsigned output_type = get_fundamental_type(fs, it->second.type_id); + unsigned att_type = get_format_type(cb->pAttachments[attachment].format); + + /* type checking */ + if (att_type != FORMAT_TYPE_UNDEFINED && output_type != FORMAT_TYPE_UNDEFINED && att_type != output_type) { + char fs_type[1024]; + describe_type(fs_type, fs, it->second.type_id); + sprintf(str, "Attachment %d of type `%s` does not match FS output type of `%s`", + attachment, string_VkFormat(cb->pAttachments[attachment].format), fs_type); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str); + } + /* OK! */ - /* TODO: typecheck */ it++; attachment++; } -- cgit v1.2.3 From 6baaec76e029716df70222decad278e277573666 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Mon, 11 May 2015 17:21:15 -0500 Subject: vulkan.h: V93 -- fine-grained memory binding synchronization. Bug# 13464 New names and behavior for QueueBind* APIs. --- demos/cube.c | 19 +++++++++---------- demos/tri.c | 16 +++++++--------- icd/nulldrv/nulldrv.c | 13 ++++++------- include/vkLayer.h | 6 +++--- include/vulkan.h | 21 ++++++++++----------- layers/mem_tracker.cpp | 31 +++++++++++++++---------------- layers/param_checker.cpp | 14 +++++++------- loader/gpa_helper.h | 12 ++++++------ loader/table_ops.h | 18 +++++++++--------- loader/trampoline.c | 14 +++++++------- loader/vulkan.def | 6 +++--- vk-layer-generate.py | 13 ++++--------- vulkan.py | 11 +++++------ 13 files changed, 91 insertions(+), 103 deletions(-) diff --git a/demos/cube.c b/demos/cube.c index e9ea5923..35789ab6 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -699,7 +699,7 @@ static void demo_prepare_depth(struct demo *demo) assert(!err); /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, i, demo->depth.mem[i], 0); assert(!err); @@ -942,7 +942,7 @@ static void demo_prepare_texture_image(struct demo *demo, assert(!err); /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image, j, tex_obj->mem[j], 0); assert(!err); @@ -991,7 +991,7 @@ static void demo_destroy_texture_image(struct demo *demo, struct texture_object { /* clean up staging resources */ for (uint32_t j = 0; j < tex_objs->num_mem; j ++) { - vkQueueBindObjectMemory(demo->queue, + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, tex_objs->image, j, VK_NULL_HANDLE, 0); vkFreeMemory(demo->device, tex_objs->mem[j]); } @@ -1179,7 +1179,7 @@ void demo_prepare_cube_data_buffer(struct demo *demo) err = vkUnmapMemory(demo->device, demo->uniform_data.mem[i]); assert(!err); - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_BUFFER, demo->uniform_data.buf, i, demo->uniform_data.mem[i], 0); assert(!err); @@ -1953,10 +1953,9 @@ static void demo_init_vk(struct demo *demo) // Graphics queue and MemMgr queue can be separate. // TODO: Add support for separate queues, including synchronization, - // and appropriate tracking for QueueSubmit and QueueBindObjectMemory + // and appropriate tracking for QueueSubmit for (i = 0; i < queue_count; i++) { - if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && - (demo->queue_props[i].queueFlags & VK_QUEUE_MEMMGR_BIT) ) + if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) break; } assert(i < queue_count); @@ -2051,7 +2050,7 @@ static void demo_cleanup(struct demo *demo) for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE_VIEW, demo->textures[i].view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image); for (j = 0; j < demo->textures[i].num_mem; j++) vkFreeMemory(demo->device, demo->textures[i].mem[j]); @@ -2061,14 +2060,14 @@ static void demo_cleanup(struct demo *demo) vkDestroySwapChainWSI(demo->swap_chain); vkDestroyObject(demo->device, VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW, demo->depth.view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->depth.image, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image); for (j = 0; j < demo->depth.num_mem; j++) { vkFreeMemory(demo->device, demo->depth.mem[j]); } vkDestroyObject(demo->device, VK_OBJECT_TYPE_BUFFER_VIEW, demo->uniform_data.view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_BUFFER, demo->uniform_data.buf, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_BUFFER, demo->uniform_data.buf, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_BUFFER, demo->uniform_data.buf); for (j = 0; j < demo->uniform_data.num_mem; j++) vkFreeMemory(demo->device, demo->uniform_data.mem[j]); diff --git a/demos/tri.c b/demos/tri.c index 58d19a24..625036b8 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -497,7 +497,7 @@ static void demo_prepare_depth(struct demo *demo) assert(!err); /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, i, demo->depth.mem[i], 0); assert(!err); @@ -580,7 +580,7 @@ static void demo_prepare_texture_image(struct demo *demo, assert(!err); /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image, j, tex_obj->mem[j], 0); assert(!err); @@ -632,7 +632,7 @@ static void demo_destroy_texture_image(struct demo *demo, struct texture_object { /* clean up staging resources */ for (uint32_t j = 0; j < tex_obj->num_mem; j ++) { - vkQueueBindObjectMemory(demo->queue, + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image, j, VK_NULL_HANDLE, 0); vkFreeMemory(demo->device, tex_obj->mem[j]); } @@ -811,7 +811,7 @@ static void demo_prepare_vertices(struct demo *demo) err = vkUnmapMemory(demo->device, demo->vertices.mem[i]); assert(!err); - err = vkQueueBindObjectMemory(demo->queue, + err = vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, i, demo->vertices.mem[i], 0); assert(!err); @@ -1453,8 +1453,6 @@ static void demo_init_vk(struct demo *demo) for (i = 0; i < queue_count; i++) { if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) break; - if (demo->queue_props[i].queueFlags & VK_QUEUE_MEMMGR_BIT) - break; } assert(i < queue_count); demo->graphics_queue_node_index = i; @@ -1549,14 +1547,14 @@ static void demo_cleanup(struct demo *demo) vkDestroyObject(demo->device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, demo->pipeline_layout); vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, demo->desc_layout); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf); for (j = 0; j < demo->vertices.num_mem; j++) vkFreeMemory(demo->device, demo->vertices.mem[j]); for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE_VIEW, demo->textures[i].view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image); for (j = 0; j < demo->textures[i].num_mem; j++) vkFreeMemory(demo->device, demo->textures[i].mem[j]); @@ -1565,7 +1563,7 @@ static void demo_cleanup(struct demo *demo) } vkDestroyObject(demo->device, VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW, demo->depth.view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->depth.image, 0, VK_NULL_HANDLE, 0); + vkBindObjectMemory(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, 0, VK_NULL_HANDLE, 0); vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image); for (j = 0; j < demo->depth.num_mem; j++) { vkFreeMemory(demo->device, demo->depth.mem[j]); diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c index 408f2caa..d6472c85 100644 --- a/icd/nulldrv/nulldrv.c +++ b/icd/nulldrv/nulldrv.c @@ -1517,7 +1517,7 @@ ICD_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo( if (pData == NULL) { return ret; } - props->queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_MEMMGR_BIT; + props->queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_SPARSE_MEMMGR_BIT; props->queueCount = 1; props->maxAtomicCounters = 1; props->supportsTimestamps = false; @@ -1868,8 +1868,8 @@ ICD_EXPORT VkResult VKAPI vkGetObjectInfo( return base->get_info(base, infoType, pDataSize, pData); } -ICD_EXPORT VkResult VKAPI vkQueueBindObjectMemory( - VkQueue queue, +ICD_EXPORT VkResult VKAPI vkBindObjectMemory( + VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, @@ -1880,10 +1880,9 @@ ICD_EXPORT VkResult VKAPI vkQueueBindObjectMemory( return VK_SUCCESS; } -ICD_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange( +ICD_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory( VkQueue queue, - VkObjectType objType, - VkObject object, + VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, @@ -1894,7 +1893,7 @@ ICD_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange( return VK_SUCCESS; } -ICD_EXPORT VkResult VKAPI vkQueueBindImageMemoryRange( +ICD_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory( VkQueue queue, VkImage image, uint32_t allocationIdx, diff --git a/include/vkLayer.h b/include/vkLayer.h index bd56f03d..7239ba55 100644 --- a/include/vkLayer.h +++ b/include/vkLayer.h @@ -55,9 +55,9 @@ typedef struct VkLayerDispatchTable_ PFN_vkOpenPeerImage OpenPeerImage; PFN_vkDestroyObject DestroyObject; PFN_vkGetObjectInfo GetObjectInfo; - PFN_vkQueueBindObjectMemory QueueBindObjectMemory; - PFN_vkQueueBindObjectMemoryRange QueueBindObjectMemoryRange; - PFN_vkQueueBindImageMemoryRange QueueBindImageMemoryRange; + PFN_vkBindObjectMemory BindObjectMemory; + PFN_vkQueueBindSparseBufferMemory QueueBindSparseBufferMemory; + PFN_vkQueueBindSparseImageMemory QueueBindSparseImageMemory; PFN_vkCreateFence CreateFence; PFN_vkGetFenceStatus GetFenceStatus; PFN_vkResetFences ResetFences; diff --git a/include/vulkan.h b/include/vulkan.h index e85ca9d2..8829222f 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -970,7 +970,7 @@ typedef enum VkQueueFlagBits_ VK_QUEUE_GRAPHICS_BIT = VK_BIT(0), // Queue supports graphics operations VK_QUEUE_COMPUTE_BIT = VK_BIT(1), // Queue supports compute operations VK_QUEUE_DMA_BIT = VK_BIT(2), // Queue supports DMA operations - VK_QUEUE_MEMMGR_BIT = VK_BIT(3), // Queue supports memory management operations + VK_QUEUE_SPARSE_MEMMGR_BIT = VK_BIT(3), // Queue supports sparse resource memory management operations VK_QUEUE_EXTENDED_BIT = VK_BIT(30), // Extended queue } VkQueueFlagBits; @@ -1401,7 +1401,7 @@ typedef struct VkMemoryRequirements_ { VkDeviceSize size; // Specified in bytes VkDeviceSize alignment; // Specified in bytes - VkDeviceSize granularity; // Granularity on which vkQueueBindObjectMemoryRange can bind sub-ranges of memory specified in bytes (usually the page size) + VkDeviceSize granularity; // Granularity at which memory can be bound to resource sub-ranges specified in bytes (usually the page size) VkMemoryPropertyFlags memPropsAllowed; // Allowed memory property flags VkMemoryPropertyFlags memPropsRequired; // Required memory property flags } VkMemoryRequirements; @@ -2161,9 +2161,9 @@ typedef VkResult (VKAPI *PFN_vkOpenPeerMemory)(VkDevice device, const VkPeerMemo typedef VkResult (VKAPI *PFN_vkOpenPeerImage)(VkDevice device, const VkPeerImageOpenInfo* pOpenInfo, VkImage* pImage, VkDeviceMemory* pMem); typedef VkResult (VKAPI *PFN_vkDestroyObject)(VkDevice device, VkObjectType objType, VkObject object); typedef VkResult (VKAPI *PFN_vkGetObjectInfo)(VkDevice device, VkObjectType objType, VkObject object, VkObjectInfoType infoType, size_t* pDataSize, void* pData); -typedef VkResult (VKAPI *PFN_vkQueueBindObjectMemory)(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset); -typedef VkResult (VKAPI *PFN_vkQueueBindObjectMemoryRange)(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset); -typedef VkResult (VKAPI *PFN_vkQueueBindImageMemoryRange)(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset); +typedef VkResult (VKAPI *PFN_vkBindObjectMemory)(VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset); +typedef VkResult (VKAPI *PFN_vkQueueBindSparseBufferMemory)(VkQueue queue, VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset); +typedef VkResult (VKAPI *PFN_vkQueueBindSparseImageMemory)(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset); typedef VkResult (VKAPI *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence); typedef VkResult (VKAPI *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, VkFence* pFences); typedef VkResult (VKAPI *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); @@ -2420,25 +2420,24 @@ VkResult VKAPI vkGetObjectInfo( // Memory management API functions -VkResult VKAPI vkQueueBindObjectMemory( - VkQueue queue, +VkResult VKAPI vkBindObjectMemory( + VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize memOffset); -VkResult VKAPI vkQueueBindObjectMemoryRange( +VkResult VKAPI vkQueueBindSparseBufferMemory( VkQueue queue, - VkObjectType objType, - VkObject object, + VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset); -VkResult VKAPI vkQueueBindImageMemoryRange( +VkResult VKAPI vkQueueBindSparseImageMemory( VkQueue queue, VkImage image, uint32_t allocationIdx, diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index 98b2df54..3d3a9965 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -1177,7 +1177,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject( else { char str[1024]; sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding " - "by calling vkQueueBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)", + "by calling vkBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)", object, (void*)pDelInfo->pMemObjInfo->mem, object); layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str); // From the spec : If an object has previous memory binding, it is required to unbind memory @@ -1203,22 +1203,22 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo( void *pData) { // TODO : What to track here? - // Could potentially save returned mem requirements and validate values passed into QueueBindObjectMemory for this object + // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, // command buffers, shaders and memory objects. VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData); return result; } -VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory( - VkQueue queue, +VK_LAYER_EXPORT VkResult VKAPI vkBindObjectMemory( + VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) { - VkResult result = nextTable.QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset); + VkResult result = nextTable.BindObjectMemory(device, objType, object, allocationIdx, mem, offset); loader_platform_thread_lock_mutex(&globalLock); // Track objects tied to memory if (VK_FALSE == updateObjectBinding(object, mem)) { @@ -1232,23 +1232,22 @@ VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory( return result; } -VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange( +VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory( VkQueue queue, - VkObjectType objType, - VkObject object, + VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) { - VkResult result = nextTable.QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset); + VkResult result = nextTable.QueueBindSparseBufferMemory(queue, buffer, allocationIdx, rangeOffset, rangeSize, mem, memOffset); loader_platform_thread_lock_mutex(&globalLock); // Track objects tied to memory - if (VK_FALSE == updateObjectBinding(object, mem)) { + if (VK_FALSE == updateObjectBinding(buffer, mem)) { char str[1024]; - sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem); - layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str); + sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)buffer, (void*)mem); + layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, buffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str); } printObjList(); printMemList(); @@ -2245,10 +2244,10 @@ VK_LAYER_EXPORT void* VKAPI vkGetProcAddr( return (void*) vkDestroyObject; if (!strcmp(funcName, "vkGetObjectInfo")) return (void*) vkGetObjectInfo; - if (!strcmp(funcName, "vkQueueBindObjectMemory")) - return (void*) vkQueueBindObjectMemory; - if (!strcmp(funcName, "vkQueueBindObjectMemoryRange")) - return (void*) vkQueueBindObjectMemoryRange; + if (!strcmp(funcName, "vkBindObjectMemory")) + return (void*) vkBindObjectMemory; + if (!strcmp(funcName, "vkQueueBindSparseBufferMemory")) + return (void*) vkQueueBindSparseBufferMemory; if (!strcmp(funcName, "vkCreateFence")) return (void*) vkCreateFence; if (!strcmp(funcName, "vkGetFenceStatus")) diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index 79783cb5..e9e8bb9f 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -516,32 +516,32 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(VkDevice device, VkObjectType obj return result; } -VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) +VK_LAYER_EXPORT VkResult VKAPI vkBindObjectMemory(VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) { - VkResult result = nextTable.QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset); + VkResult result = nextTable.BindObjectMemory(device, objType, object, allocationIdx, mem, offset); return result; } -VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) +VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(VkQueue queue, VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) { - VkResult result = nextTable.QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset); + VkResult result = nextTable.QueueBindSparseBufferMemory(queue, buffer, allocationIdx, rangeOffset, rangeSize, mem, memOffset); return result; } -VK_LAYER_EXPORT VkResult VKAPI vkQueueBindImageMemoryRange(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset) +VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset) { char str[1024]; if (!pBindInfo) { - sprintf(str, "Struct ptr parameter pBindInfo to function QueueBindImageMemoryRange is NULL."); + sprintf(str, "Struct ptr parameter pBindInfo to function QueueBindSparseImageMemory is NULL."); layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str); } else if (!vk_validate_vkimagememorybindinfo(pBindInfo)) { sprintf(str, "Parameter pBindInfo to function BindImageMemoryRange contains an invalid value."); layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str); } - VkResult result = nextTable.QueueBindImageMemoryRange(queue, image, allocationIdx, pBindInfo, mem, memOffset); + VkResult result = nextTable.QueueBindSparseImageMemory(queue, image, allocationIdx, pBindInfo, mem, memOffset); return result; } diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h index 775b29cf..28bb9e3b 100644 --- a/loader/gpa_helper.h +++ b/loader/gpa_helper.h @@ -90,12 +90,12 @@ static inline void* globalGetProcAddr(const char *name) return (void*) vkDestroyObject; if (!strcmp(name, "GetObjectInfo")) return (void*) vkGetObjectInfo; - if (!strcmp(name, "QueueBindObjectMemory")) - return (void*) vkQueueBindObjectMemory; - if (!strcmp(name, "QueueBindObjectMemoryRange")) - return (void*) vkQueueBindObjectMemoryRange; - if (!strcmp(name, "QueueBindImageMemoryRange")) - return (void*) vkQueueBindImageMemoryRange; + if (!strcmp(name, "BindObjectMemory")) + return (void*) vkBindObjectMemory; + if (!strcmp(name, "QueueBindSparseBufferMemory")) + return (void*) vkQueueBindSparseBufferMemory; + if (!strcmp(name, "QueueBindSparseImageMemory")) + return (void*) vkQueueBindSparseImageMemory; if (!strcmp(name, "CreateFence")) return (void*) vkCreateFence; if (!strcmp(name, "ResetFences")) diff --git a/loader/table_ops.h b/loader/table_ops.h index da2f7f11..1e2a99fb 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -61,9 +61,9 @@ static inline void loader_initialize_dispatch_table(VkLayerDispatchTable *table, table->OpenPeerImage = (PFN_vkOpenPeerImage) gpa(gpu, "vkOpenPeerImage"); table->DestroyObject = (PFN_vkDestroyObject) gpa(gpu, "vkDestroyObject"); table->GetObjectInfo = (PFN_vkGetObjectInfo) gpa(gpu, "vkGetObjectInfo"); - table->QueueBindObjectMemory = (PFN_vkQueueBindObjectMemory) gpa(gpu, "vkQueueBindObjectMemory"); - table->QueueBindObjectMemoryRange = (PFN_vkQueueBindObjectMemoryRange) gpa(gpu, "vkQueueBindObjectMemoryRange"); - table->QueueBindImageMemoryRange = (PFN_vkQueueBindImageMemoryRange) gpa(gpu, "vkQueueBindImageMemoryRange"); + table->BindObjectMemory = (PFN_vkBindObjectMemory) gpa(gpu, "vkBindObjectMemory"); + table->QueueBindSparseBufferMemory = (PFN_vkQueueBindSparseBufferMemory) gpa(gpu, "vkQueueBindSparseBufferMemory"); + table->QueueBindSparseImageMemory = (PFN_vkQueueBindSparseImageMemory) gpa(gpu, "vkQueueBindSparseImageMemory"); table->CreateFence = (PFN_vkCreateFence) gpa(gpu, "vkCreateFence"); table->ResetFences = (PFN_vkResetFences) gpa(gpu, "vkResetFences"); table->GetFenceStatus = (PFN_vkGetFenceStatus) gpa(gpu, "vkGetFenceStatus"); @@ -226,12 +226,12 @@ static inline void *loader_lookup_dispatch_table(const VkLayerDispatchTable *tab return (void *) table->DestroyObject; if (!strcmp(name, "GetObjectInfo")) return (void *) table->GetObjectInfo; - if (!strcmp(name, "QueueBindObjectMemory")) - return (void *) table->QueueBindObjectMemory; - if (!strcmp(name, "QueueBindObjectMemoryRange")) - return (void *) table->QueueBindObjectMemoryRange; - if (!strcmp(name, "QueueBindImageMemoryRange")) - return (void *) table->QueueBindImageMemoryRange; + if (!strcmp(name, "BindObjectMemory")) + return (void *) table->BindObjectMemory; + if (!strcmp(name, "QueueBindSparseBufferMemory")) + return (void *) table->QueueBindSparseBufferMemory; + if (!strcmp(name, "QueueBindSparseImageMemory")) + return (void *) table->QueueBindSparseImageMemory; if (!strcmp(name, "CreateFence")) return (void *) table->CreateFence; if (!strcmp(name, "ResetFences")) diff --git a/loader/trampoline.c b/loader/trampoline.c index d393c2be..f31bd647 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -254,31 +254,31 @@ LOADER_EXPORT VkResult VKAPI vkGetObjectInfo(VkDevice device, VkObjectType objTy return disp->GetObjectInfo(device, objType, object, infoType, pDataSize, pData); } -LOADER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) +LOADER_EXPORT VkResult VKAPI vkBindObjectMemory(VkDevice device, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceMemory mem, VkDeviceSize offset) { const VkLayerDispatchTable *disp; - disp = loader_get_dispatch(queue); + disp = loader_get_dispatch(device); - return disp->QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset); + return disp->BindObjectMemory(device, objType, object, allocationIdx, mem, offset); } -LOADER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(VkQueue queue, VkObjectType objType, VkObject object, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) +LOADER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(VkQueue queue, VkBuffer buffer, uint32_t allocationIdx, VkDeviceSize rangeOffset, VkDeviceSize rangeSize, VkDeviceMemory mem, VkDeviceSize memOffset) { const VkLayerDispatchTable *disp; disp = loader_get_dispatch(queue); - return disp->QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset); + return disp->QueueBindSparseBufferMemory(queue, buffer, allocationIdx, rangeOffset, rangeSize, mem, memOffset); } -LOADER_EXPORT VkResult VKAPI vkQueueBindImageMemoryRange(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset) +LOADER_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory(VkQueue queue, VkImage image, uint32_t allocationIdx, const VkImageMemoryBindInfo* pBindInfo, VkDeviceMemory mem, VkDeviceSize memOffset) { const VkLayerDispatchTable *disp; disp = loader_get_dispatch(queue); - return disp->QueueBindImageMemoryRange(queue, image, allocationIdx, pBindInfo, mem, memOffset); + return disp->QueueBindSparseImageMemory(queue, image, allocationIdx, pBindInfo, mem, memOffset); } LOADER_EXPORT VkResult VKAPI vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence) diff --git a/loader/vulkan.def b/loader/vulkan.def index d3bfe35d..57499981 100644 --- a/loader/vulkan.def +++ b/loader/vulkan.def @@ -55,9 +55,9 @@ EXPORTS vkOpenPeerImage vkDestroyObject vkGetObjectInfo - vkQueueBindObjectMemory - vkQueueBindObjectMemoryRange - vkQueueBindImageMemoryRange + vkBindObjectMemory + vkQueueBindSparseBufferMemory + vkQueueBindSparseImageMemory vkCreateFence vkResetFences vkGetFenceStatus diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 0d375c7b..cc30a227 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -1115,11 +1115,11 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' }') header_txt.append(' if (pQueueInfo != NULL) {') header_txt.append(' char str[1024];\n') - header_txt.append(' if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_MEMMGR_BIT) == 0) {') - header_txt.append(' sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not set", function);') + header_txt.append(' if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_MEMMGR_BIT) == 0) {') + header_txt.append(' sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not set", function);') header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);') header_txt.append(' } else {') - header_txt.append(' sprintf(str, "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_MEMMGR_BIT not known", function);') + header_txt.append(' sprintf(str, "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not known", function);') header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);') header_txt.append(' }') header_txt.append(' }') @@ -1184,19 +1184,14 @@ class ObjectTrackerSubcommand(Subcommand): using_line += ' // validate_memory_mapping_status(pMemRefs, memRefCount);\n' using_line += ' // validate_mem_ref_count(memRefCount);\n' using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - elif 'QueueBindObjectMemoryRange' in proto.name: + elif 'QueueBindSparse' in proto.name: using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' - using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'QueueBindObject' in proto.name: using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' - elif 'QueueBindImage' in proto.name: - using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' - using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name) - using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' elif 'GetObjectInfo' in proto.name: using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name) diff --git a/vulkan.py b/vulkan.py index 9030ea43..e2a6905e 100755 --- a/vulkan.py +++ b/vulkan.py @@ -370,25 +370,24 @@ core = Extension( Param("size_t*", "pDataSize"), Param("void*", "pData")]), - Proto("VkResult", "QueueBindObjectMemory", - [Param("VkQueue", "queue"), + Proto("VkResult", "BindObjectMemory", + [Param("VkDevice", "device"), Param("VkObjectType", "objType"), Param("VkObject", "object"), Param("uint32_t", "allocationIdx"), Param("VkDeviceMemory", "mem"), Param("VkDeviceSize", "offset")]), - Proto("VkResult", "QueueBindObjectMemoryRange", + Proto("VkResult", "QueueBindSparseBufferMemory", [Param("VkQueue", "queue"), - Param("VkObjectType", "objType"), - Param("VkObject", "object"), + Param("VkBuffer", "buffer"), Param("uint32_t", "allocationIdx"), Param("VkDeviceSize", "rangeOffset"), Param("VkDeviceSize", "rangeSize"), Param("VkDeviceMemory", "mem"), Param("VkDeviceSize", "memOffset")]), - Proto("VkResult", "QueueBindImageMemoryRange", + Proto("VkResult", "QueueBindSparseImageMemory", [Param("VkQueue", "queue"), Param("VkImage", "image"), Param("uint32_t", "allocationIdx"), -- cgit v1.2.3 From e03c95bd7fbff4237cbac0279e256aca8aecf0c3 Mon Sep 17 00:00:00 2001 From: Mike Stroyan Date: Mon, 11 May 2015 13:44:24 -0600 Subject: layers: fix calculation of intercepting functions. Assign _gen_layer_get_global_extension_info to intercept. Remove duplicate calculation of lookups. --- vk-layer-generate.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/vk-layer-generate.py b/vk-layer-generate.py index cc30a227..ab112232 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -285,8 +285,7 @@ class Subcommand(object): elif 'DbgUnregisterMsgCallback' == proto.name: intercept = self._gen_layer_dbg_callback_unregister() elif 'GetGlobalExtensionInfo' == proto.name: - funcs.append(self._gen_layer_get_global_extension_info(self.layer_name)) - intercepted.append(proto) + intercept = self._gen_layer_get_global_extension_info(self.layer_name) if intercept is not None: funcs.append(intercept) intercepted.append(proto) @@ -298,13 +297,6 @@ class Subcommand(object): lookups.append(" return (void*) %s%s;" % (prefix, proto.name)) - prefix="vk" - lookups = [] - for proto in intercepted: - lookups.append("if (!strcmp(name, \"%s\"))" % proto.name) - lookups.append(" return (void*) %s%s;" % - (prefix, proto.name)) - # add customized layer_intercept_proc body = [] body.append("static inline void* layer_intercept_proc(const char *name)") -- cgit v1.2.3 From 8cf6756e49e60b7a10751e5b31e77daebf0ae13b Mon Sep 17 00:00:00 2001 From: Mike Stroyan Date: Mon, 11 May 2015 17:18:14 -0600 Subject: layers: rework Threading layer to match version 91 Handle multiple thread checked parameters. Thread-check parameters in some calls that start with a VkDevice parameter. Use more recent WSI name pattern. --- vk-layer-generate.py | 82 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/vk-layer-generate.py b/vk-layer-generate.py index ab112232..369d63b1 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -1364,7 +1364,7 @@ class ThreadingSubcommand(Subcommand): header_txt.append(' if (objectsInUse.find(object) == objectsInUse.end()) {') header_txt.append(' objectsInUse[object] = tid;') header_txt.append(' } else {') - header_txt.append(' if (objectsInUse[object] == tid) {') + header_txt.append(' if (objectsInUse[object] != tid) {') header_txt.append(' char str[1024];') header_txt.append(' sprintf(str, "THREADING ERROR : object of type %s is simultaneously used in thread %ld and thread %ld", type, objectsInUse[object], tid);') header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING", str);') @@ -1390,6 +1390,17 @@ class ThreadingSubcommand(Subcommand): # use default version return None decl = proto.c_func(prefix="vk", attr="VKAPI") + thread_check_objects = [ + "VkQueue", + "VkDeviceMemory", + "VkObject", + "VkBuffer", + "VkImage", + "VkDescriptorSet", + "VkDescriptorPool", + "VkCmdBuffer", + "VkSemaphore" + ] ret_val = '' stmt = '' funcs = [] @@ -1414,35 +1425,68 @@ class ThreadingSubcommand(Subcommand): ' return VK_SUCCESS;\n' ' }\n' '}' % (qual, decl, proto.params[0].name, self.layer_name, ret_val, proto.c_call(), stmt, self.layer_name)) + return "\n".join(funcs) + # Memory range calls are special in needed thread checking within structs + if proto.name in ["FlushMappedMemoryRanges","InvalidateMappedMemoryRanges"]: + funcs.append('%s%s\n' + '{\n' + ' for (int i=0; i Date: Wed, 13 May 2015 11:57:18 -0600 Subject: loader: On Windows disable global optimization for API entrypoints Without this change, on a Windows Release build, mhook is unable to hook the entrypoint functions. --- loader/trampoline.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/loader/trampoline.c b/loader/trampoline.c index f31bd647..2f255fbd 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -24,6 +24,12 @@ #include "loader.h" +#if defined(WIN32) +// On Windows need to disable global optimization for function entrypoints or +// else mhook will not be able to hook all of them +#pragma optimize( "g", off ) +#endif + /* Trampoline entrypoints */ LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo(VkPhysicalDevice gpu, VkPhysicalDeviceInfoType infoType, size_t* pDataSize, void* pData) { @@ -1138,3 +1144,7 @@ LOADER_EXPORT VkResult VKAPI vkQueuePresentWSI(VkQueue queue, const VkPresentInf return disp->QueuePresentWSI(queue, pPresentInfo); } + +#if defined(WIN32) +#pragma optimize( "", on ) +#endif -- cgit v1.2.3 From 5a1a158dc7207eab9c8bde56f4603e3543c0dde4 Mon Sep 17 00:00:00 2001 From: Henry Song Date: Wed, 13 May 2015 14:53:31 -0700 Subject: demos: Add msaa-tri.c for msaa rendering example modified from tri.c --- demos/msaa-tri.c | 1948 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1948 insertions(+) create mode 100644 demos/msaa-tri.c diff --git a/demos/msaa-tri.c b/demos/msaa-tri.c new file mode 100644 index 00000000..a8e10c9b --- /dev/null +++ b/demos/msaa-tri.c @@ -0,0 +1,1948 @@ +/* + * Vulkan + * + * Copyright (C) 2014-2015 LunarG, Inc. + * Copyright (c) 2015 Samsung Electronics, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Draw a textured triangle with depth testing. This is written against Intel + * ICD. It does not do state transition nor object memory binding like it + * should. It also does no error checking. + */ +/* Modified to use MSAA + * + * Changes to tri.c + * (1) No color attachment views created for swap chain images + * (2) create an offscreen MSAA (samples = 4) image as color attachment + * (3) create msaa depth/stencil image + * (4) during draw time, attach msaa image and msaa depth/stencil buffer + * as color and depth/stencil attachment + * (5) once drawn to msaa color image, resolve it to swap chain image + */ +/* Contributed by Henry Song (henry.song@samsung.com) */ + +#ifndef VK_PROTOTYPES +#define VK_PROTOTYPES +#endif + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#pragma comment(linker, "/subsystem:windows") +#include +#include +#include +#define APP_NAME_STR_LEN 80 +#else // _WIN32 +#include +#endif // _WIN32 + +#include +#include +#include + +#include "icd-spv.h" + +#define DEMO_BUFFER_COUNT 2 +#define DEMO_TEXTURE_COUNT 1 +#define VERTEX_BUFFER_BIND_ID 0 +#define APP_SHORT_NAME "tri" +#define APP_LONG_NAME "The Vulkan Triangle Demo Program" + +#ifdef _WIN32 +bool consoleCreated = false; + +#define WAIT_FOR_CONSOLE_DESTROY \ + do { \ + if (consoleCreated) \ + Sleep(INFINITE); \ + } while (0) + +#define ERR_EXIT(err_msg, err_class) \ + do { \ + MessageBox(NULL, err_msg, err_class, MB_OK); \ + if (consoleCreated) { \ + printf("\nPlease close this window when you are finished " \ + "looking at the console output.\n"); \ + fflush(stdout); \ + } \ + WAIT_FOR_CONSOLE_DESTROY; \ + exit(1); \ + } while (0) + +// NOTE: If the following values (copied from "loader_platform.h") change, they +// need to change here as well: +#define LAYER_NAMES_ENV "VK_LAYER_NAMES" +#define LAYER_NAMES_REGISTRY_VALUE "VK_LAYER_NAMES" +#else // _WIN32 + #define WAIT_FOR_CONSOLE_DESTROY + +#define ERR_EXIT(err_msg, err_class) \ + do { \ + printf(err_msg); \ + fflush(stdout); \ + exit(1); \ + } while (0) +#endif // _WIN32 + +struct texture_object { + VkSampler sampler; + + VkImage image; + VkImageLayout imageLayout; + + uint32_t num_mem; + VkDeviceMemory *mem; + VkImageView view; + int32_t tex_width, tex_height; +}; + +struct demo { +#ifdef _WIN32 +#define APP_NAME_STR_LEN 80 + HINSTANCE connection; // hInstance - Windows Instance + char name[APP_NAME_STR_LEN]; // Name to put on the window/icon + HWND window; // hWnd - window handle +#else // _WIN32 + xcb_connection_t *connection; + xcb_screen_t *screen; + xcb_window_t window; + xcb_intern_atom_reply_t *atom_wm_delete_window; +#endif // _WIN32 + bool prepared; + bool use_staging_buffer; + + VkInstance inst; + VkPhysicalDevice gpu; + VkDevice device; + VkQueue queue; + VkPhysicalDeviceProperties *gpu_props; + VkPhysicalDeviceQueueProperties *queue_props; + uint32_t graphics_queue_node_index; + + int width, height; + VkFormat format; + + VkSwapChainWSI swap_chain; + struct { + VkImage image; + VkDeviceMemory mem; + } buffers[DEMO_BUFFER_COUNT]; + + struct { + VkFormat format; + + VkImage image; + uint32_t num_mem; + VkDeviceMemory *mem; + VkColorAttachmentView view; + } msaa_color; + + struct { + VkFormat format; + + VkImage image; + uint32_t num_mem; + VkDeviceMemory *mem; + VkDepthStencilView view; + } msaa_depth; + + struct texture_object textures[DEMO_TEXTURE_COUNT]; + + struct { + VkBuffer buf; + uint32_t num_mem; + VkDeviceMemory *mem; + + VkPipelineVertexInputCreateInfo vi; + VkVertexInputBindingDescription vi_bindings[1]; + VkVertexInputAttributeDescription vi_attrs[2]; + } vertices; + + VkCmdBuffer cmd; // Buffer for initialization commands + VkPipelineLayout pipeline_layout; + VkDescriptorSetLayout desc_layout; + VkPipeline pipeline; + + VkDynamicVpState viewport; + VkDynamicRsState raster; + VkDynamicCbState color_blend; + VkDynamicDsState depth_stencil; + + VkDescriptorPool desc_pool; + VkDescriptorSet desc_set; + + bool quit; + uint32_t current_buffer; +}; + +static void demo_flush_init_cmd(struct demo *demo) +{ + VkResult err; + + if (demo->cmd == VK_NULL_HANDLE) + return; + + err = vkEndCommandBuffer(demo->cmd); + assert(!err); + + const VkCmdBuffer cmd_bufs[] = { demo->cmd }; + + err = vkQueueSubmit(demo->queue, 1, cmd_bufs, VK_NULL_HANDLE); + assert(!err); + + err = vkQueueWaitIdle(demo->queue); + assert(!err); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_COMMAND_BUFFER, demo->cmd); + demo->cmd = VK_NULL_HANDLE; +} + +static void demo_add_mem_refs( + struct demo *demo, + int num_refs, VkDeviceMemory *mem) +{ + vkQueueAddMemReferences(demo->queue, num_refs, mem); +} + +static void demo_remove_mem_refs( + struct demo *demo, + int num_refs, VkDeviceMemory *mem) +{ + vkQueueRemoveMemReferences(demo->queue, num_refs, mem); +} + +static void demo_set_image_layout( + struct demo *demo, + VkImage image, + VkImageLayout old_image_layout, + VkImageLayout new_image_layout) +{ + VkResult err; + + if (demo->cmd == VK_NULL_HANDLE) { + const VkCmdBufferCreateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, + .pNext = NULL, + .queueNodeIndex = demo->graphics_queue_node_index, + .flags = 0, + }; + + err = vkCreateCommandBuffer(demo->device, &cmd, &demo->cmd); + assert(!err); + + VkCmdBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | + VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + }; + err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info); + } + + VkImageMemoryBarrier image_memory_barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .outputMask = 0, + .inputMask = 0, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .image = image, + .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } + }; + + if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL) { + /* Make sure anything that was copying from this image has completed */ + image_memory_barrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + /* Make sure any Copy or CPU writes to image are flushed */ + image_memory_barrier.outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT | VK_MEMORY_OUTPUT_CPU_WRITE_BIT; + } + + VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier; + + VkPipeEvent set_events[] = { VK_PIPE_EVENT_TOP_OF_PIPE }; + + vkCmdPipelineBarrier(demo->cmd, VK_WAIT_EVENT_TOP_OF_PIPE, 1, set_events, 1, (const void **)&pmemory_barrier); +} + +static void demo_draw_build_cmd(struct demo *demo) +{ + const VkColorAttachmentBindInfo color_attachment = { + .view = demo->msaa_color.view, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + const VkDepthStencilBindInfo depth_stencil = { + .view = demo->msaa_depth.view, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }; + const VkClearColor clear_color = { + .color.floatColor = { 0.2f, 0.2f, 0.2f, 1.0f }, + .useRawValue = false, + }; + const float clear_depth = 0.0f; + VkImageSubresourceRange clear_range; + VkCmdBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | + VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + }; + VkResult err; + VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + VkAttachmentStoreOp store_op = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; + const VkFramebufferCreateInfo fb_info = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = NULL, + .colorAttachmentCount = 1, + .pColorAttachments = (VkColorAttachmentBindInfo*) &color_attachment, + .pDepthStencilAttachment = (VkDepthStencilBindInfo*) &depth_stencil, + .sampleCount = 4, + .width = demo->width, + .height = demo->height, + .layers = 1, + }; + VkRenderPassCreateInfo rp_info; + VkRenderPassBegin rp_begin; + + memset(&rp_info, 0 , sizeof(rp_info)); + err = vkCreateFramebuffer(demo->device, &fb_info, &rp_begin.framebuffer); + assert(!err); + rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rp_info.renderArea.extent.width = demo->width; + rp_info.renderArea.extent.height = demo->height; + rp_info.colorAttachmentCount = fb_info.colorAttachmentCount; + rp_info.pColorFormats = &demo->format; + rp_info.pColorLayouts = &color_attachment.layout; + rp_info.pColorLoadOps = &load_op; + rp_info.pColorStoreOps = &store_op; + rp_info.pColorLoadClearValues = &clear_color; + rp_info.depthStencilFormat = VK_FORMAT_D16_UNORM; + rp_info.depthStencilLayout = depth_stencil.layout; + rp_info.depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + rp_info.depthLoadClearValue = clear_depth; + rp_info.depthStoreOp = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; + rp_info.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + rp_info.stencilLoadClearValue = 0; + rp_info.stencilStoreOp = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; + err = vkCreateRenderPass(demo->device, &rp_info, &(rp_begin.renderPass)); + assert(!err); + + err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info); + assert(!err); + + + vkCmdBindPipeline(demo->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + demo->pipeline); + vkCmdBindDescriptorSets(demo->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, 1, & demo->desc_set, 0, NULL); + + vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_VIEWPORT, demo->viewport); + vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_RASTER, demo->raster); + vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_COLOR_BLEND, + demo->color_blend); + vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_DEPTH_STENCIL, + demo->depth_stencil); + + VkDeviceSize offsets[1] = {0}; + vkCmdBindVertexBuffers(demo->cmd, VERTEX_BUFFER_BIND_ID, 1, &demo->vertices.buf, offsets); + + vkCmdBeginRenderPass(demo->cmd, &rp_begin); + clear_range.aspect = VK_IMAGE_ASPECT_COLOR; + clear_range.baseMipLevel = 0; + clear_range.mipLevels = 1; + clear_range.baseArraySlice = 0; + clear_range.arraySize = 1; + + vkCmdClearColorImage(demo->cmd, + demo->msaa_color.image, + VK_IMAGE_LAYOUT_CLEAR_OPTIMAL, + clear_color, 1, &clear_range); + + clear_range.aspect = VK_IMAGE_ASPECT_DEPTH; + vkCmdClearDepthStencil(demo->cmd, + demo->msaa_depth.image, VK_IMAGE_LAYOUT_CLEAR_OPTIMAL, + clear_depth, 0, 1, &clear_range); + + vkCmdDraw(demo->cmd, 0, 3, 0, 1); + vkCmdEndRenderPass(demo->cmd, rp_begin.renderPass); + + VkImageResolve resolve = { + .srcSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, + .srcOffset = { 0, 0, 0 }, + .destSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, + .destOffset = { 0, 0, 0 }, + .extent = { demo->width, demo->height, 1 } + }; + + demo_set_image_layout(demo, demo->msaa_color.image, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); + + vkCmdResolveImage(demo->cmd, demo->msaa_color.image, + VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, + demo->buffers[demo->current_buffer].image, + VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, &resolve); + + err = vkEndCommandBuffer(demo->cmd); + assert(!err); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_RENDER_PASS, rp_begin.renderPass); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_FRAMEBUFFER, rp_begin.framebuffer); +} + +static void demo_draw(struct demo *demo) +{ + const VkPresentInfoWSI present = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_WSI, + .pNext = NULL, + .image = demo->buffers[demo->current_buffer].image, + .flipInterval = 0, + }; + VkResult err; + + demo_draw_build_cmd(demo); + + err = vkQueueSubmit(demo->queue, 1, &demo->cmd, VK_NULL_HANDLE); + assert(!err); + + err = vkQueuePresentWSI(demo->queue, &present); + assert(!err); + + demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; + + err = vkQueueWaitIdle(demo->queue); + assert(err == VK_SUCCESS); +} + +static void demo_prepare_buffers(struct demo *demo) +{ + const VkSwapChainCreateInfoWSI swap_chain = { + .sType = VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI, + .pNext = NULL, + .pNativeWindowSystemHandle = demo->connection, + .pNativeWindowHandle = (void *) (intptr_t) demo->window, + .imageCount = DEMO_BUFFER_COUNT, + .imageFormat = demo->format, + .imageExtent = { + .width = demo->width, + .height = demo->height, + }, + .imageArraySize = 1, + .imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, + }; + VkSwapChainImageInfoWSI images[DEMO_BUFFER_COUNT]; + size_t images_size = sizeof(images); + VkResult err; + uint32_t i; + + err = vkCreateSwapChainWSI(demo->device, &swap_chain, &demo->swap_chain); + assert(!err); + + err = vkGetSwapChainInfoWSI(demo->swap_chain, + VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI, + &images_size, images); + assert(!err && images_size == sizeof(images)); + + for (i = 0; i < DEMO_BUFFER_COUNT; i++) { + demo->buffers[i].image = images[i].image; + demo->buffers[i].mem = images[i].memory; + + demo_add_mem_refs(demo, 1, &demo->buffers[i].mem); + demo_set_image_layout(demo, demo->buffers[i].image, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); + } + + demo->current_buffer = 0; + + /* create MSAA image */ + const VkFormat msaa_format = VK_FORMAT_B8G8R8A8_UNORM; + + const VkImageCreateInfo msaa_image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = msaa_format, + .extent = { demo->width, demo->height, 1 }, + .mipLevels = 1, + .arraySize = 1, + .samples = 4, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .flags = 0, + }; + VkMemoryAllocInfo msaa_mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, + .pNext = NULL, + .allocationSize = 0, + .memProps = 0, + .memPriority = VK_MEMORY_PRIORITY_NORMAL, + }; + + VkMemoryRequirements *msaa_mem_reqs; + size_t msaa_mem_reqs_size = sizeof(VkMemoryRequirements); + uint32_t msaa_num_allocations = 0; + size_t msaa_num_alloc_size = sizeof(msaa_num_allocations); + + err = vkCreateImage(demo->device, &msaa_image_create_info, + &demo->msaa_color.image); + assert(!err); + + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, + VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, + &msaa_num_alloc_size, &msaa_num_allocations); + assert(!err && msaa_num_alloc_size == sizeof(msaa_num_allocations)); + msaa_mem_reqs = malloc(msaa_num_allocations * sizeof(VkMemoryRequirements)); + demo->msaa_color.mem = malloc(msaa_num_allocations * sizeof(VkDeviceMemory)); + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, + VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, + &msaa_mem_reqs_size, msaa_mem_reqs); + assert(!err && msaa_mem_reqs_size == msaa_num_allocations * sizeof(VkMemoryRequirements)); + for (uint32_t j = 0; j < msaa_num_allocations; j ++) { + msaa_mem_alloc.allocationSize = msaa_mem_reqs[j].size; + + /* allocate memory */ + err = vkAllocMemory(demo->device, &msaa_mem_alloc, + &(demo->msaa_color.mem[j])); + assert(!err); + + /* bind memory */ + err = vkQueueBindObjectMemory(demo->queue, + VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, + j, demo->msaa_color.mem[j], 0); + assert(!err); + } + free(msaa_mem_reqs); + msaa_mem_reqs = NULL; + + demo->msaa_color.num_mem = msaa_num_allocations; + + demo_add_mem_refs(demo, 1, demo->msaa_color.mem); + demo_set_image_layout(demo, demo->msaa_color.image, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + VkColorAttachmentViewCreateInfo msaa_color_attachment_view = { + .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, + .pNext = NULL, + .format = demo->format, + .mipLevel = 0, + .baseArraySlice = 0, + .arraySize = 1, + }; + + msaa_color_attachment_view.image = demo->msaa_color.image; + + err = vkCreateColorAttachmentView(demo->device, + &msaa_color_attachment_view, &demo->msaa_color.view); + assert(!err); +} + +static void demo_prepare_depth(struct demo *demo) +{ + const VkFormat depth_format = VK_FORMAT_D16_UNORM; + const VkImageCreateInfo image = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = depth_format, + .extent = { demo->width, demo->height, 1 }, + .mipLevels = 1, + .arraySize = 1, + .samples = 4, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_BIT, + .flags = 0, + }; + VkMemoryAllocInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, + .pNext = NULL, + .allocationSize = 0, + .memProps = VK_MEMORY_PROPERTY_DEVICE_ONLY, + .memPriority = VK_MEMORY_PRIORITY_NORMAL, + }; + VkDepthStencilViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .mipLevel = 0, + .baseArraySlice = 0, + .arraySize = 1, + .flags = 0, + }; + + VkMemoryRequirements *mem_reqs; + size_t mem_reqs_size = sizeof(VkMemoryRequirements); + VkResult err; + uint32_t num_allocations = 0; + size_t num_alloc_size = sizeof(num_allocations); + + demo->msaa_depth.format = depth_format; + + /* create image */ + err = vkCreateImage(demo->device, &image, + &demo->msaa_depth.image); + assert(!err); + + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, + VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, + &num_alloc_size, &num_allocations); + assert(!err && num_alloc_size == sizeof(num_allocations)); + mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); + demo->msaa_depth.mem = malloc(num_allocations * sizeof(VkDeviceMemory)); + demo->msaa_depth.num_mem = num_allocations; + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, + VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, + &mem_reqs_size, mem_reqs); + assert(!err && mem_reqs_size == num_allocations * sizeof(VkMemoryRequirements)); + for (uint32_t i = 0; i < num_allocations; i ++) { + mem_alloc.allocationSize = mem_reqs[i].size; + + /* allocate memory */ + err = vkAllocMemory(demo->device, &mem_alloc, + &(demo->msaa_depth.mem[i])); + assert(!err); + + /* bind memory */ + err = vkQueueBindObjectMemory(demo->queue, + VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, + i, demo->msaa_depth.mem[i], 0); + assert(!err); + } + + demo_set_image_layout(demo, demo->msaa_depth.image, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + demo_add_mem_refs(demo, demo->msaa_depth.num_mem, demo->msaa_depth.mem); + + /* create image view */ + view.image = demo->msaa_depth.image; + err = vkCreateDepthStencilView(demo->device, &view, + &demo->msaa_depth.view); + assert(!err); +} + +static void demo_prepare_texture_image(struct demo *demo, + const uint32_t *tex_colors, + struct texture_object *tex_obj, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkFlags mem_props) +{ + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + const int32_t tex_width = 2; + const int32_t tex_height = 2; + VkResult err; + + tex_obj->tex_width = tex_width; + tex_obj->tex_height = tex_height; + + const VkImageCreateInfo image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = tex_format, + .extent = { tex_width, tex_height, 1 }, + .mipLevels = 1, + .arraySize = 1, + .samples = 1, + .tiling = tiling, + .usage = usage, + .flags = 0, + }; + VkMemoryAllocInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, + .pNext = NULL, + .allocationSize = 0, + .memProps = mem_props, + .memPriority = VK_MEMORY_PRIORITY_NORMAL, + }; + + VkMemoryRequirements *mem_reqs; + size_t mem_reqs_size = sizeof(VkMemoryRequirements); + uint32_t num_allocations = 0; + size_t num_alloc_size = sizeof(num_allocations); + + err = vkCreateImage(demo->device, &image_create_info, + &tex_obj->image); + assert(!err); + + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, tex_obj->image, + VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, + &num_alloc_size, &num_allocations); + assert(!err && num_alloc_size == sizeof(num_allocations)); + mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); + tex_obj->mem = malloc(num_allocations * sizeof(VkDeviceMemory)); + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_IMAGE, tex_obj->image, + VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, + &mem_reqs_size, mem_reqs); + assert(!err && mem_reqs_size == num_allocations * sizeof(VkMemoryRequirements)); + for (uint32_t j = 0; j < num_allocations; j ++) { + mem_alloc.allocationSize = mem_reqs[j].size; + + /* allocate memory */ + err = vkAllocMemory(demo->device, &mem_alloc, + &(tex_obj->mem[j])); + assert(!err); + + /* bind memory */ + err = vkQueueBindObjectMemory(demo->queue, + VK_OBJECT_TYPE_IMAGE, tex_obj->image, + j, tex_obj->mem[j], 0); + assert(!err); + } + free(mem_reqs); + mem_reqs = NULL; + + tex_obj->num_mem = num_allocations; + + if (mem_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + const VkImageSubresource subres = { + .aspect = VK_IMAGE_ASPECT_COLOR, + .mipLevel = 0, + .arraySlice = 0, + }; + VkSubresourceLayout layout; + size_t layout_size = sizeof(VkSubresourceLayout); + void *data; + int32_t x, y; + + err = vkGetImageSubresourceInfo(demo->device, tex_obj->image, &subres, + VK_SUBRESOURCE_INFO_TYPE_LAYOUT, + &layout_size, &layout); + assert(!err && layout_size == sizeof(layout)); + /* Linear texture must be within a single memory object */ + assert(num_allocations == 1); + + err = vkMapMemory(demo->device, tex_obj->mem[0], 0, 0, 0, &data); + assert(!err); + + for (y = 0; y < tex_height; y++) { + uint32_t *row = (uint32_t *) ((char *) data + layout.rowPitch * y); + for (x = 0; x < tex_width; x++) + row[x] = tex_colors[(x & 1) ^ (y & 1)]; + } + + err = vkUnmapMemory(demo->device, tex_obj->mem[0]); + assert(!err); + } + + tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + demo_set_image_layout(demo, tex_obj->image, + VK_IMAGE_LAYOUT_UNDEFINED, + tex_obj->imageLayout); + /* setting the image layout does not reference the actual memory so no need to add a mem ref */ +} + +static void demo_destroy_texture_image(struct demo *demo, struct texture_object *tex_obj) +{ + /* clean up staging resources */ + for (uint32_t j = 0; j < tex_obj->num_mem; j ++) { + vkQueueBindObjectMemory(demo->queue, + VK_OBJECT_TYPE_IMAGE, tex_obj->image, j, VK_NULL_HANDLE, 0); + vkFreeMemory(demo->device, tex_obj->mem[j]); + } + + free(tex_obj->mem); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image); +} + +static void demo_prepare_textures(struct demo *demo) +{ + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + VkFormatProperties props; + size_t size = sizeof(props); + const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = { + { 0xffff0000, 0xff00ff00 }, + }; + VkResult err; + uint32_t i; + + err = vkGetFormatInfo(demo->device, tex_format, + VK_FORMAT_INFO_TYPE_PROPERTIES, + &size, &props); + assert(!err); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + if ((props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && !demo->use_staging_buffer) { + /* Device can texture using linear textures */ + demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + } else if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT){ + /* Must use staging buffer to copy linear texture to optimized */ + struct texture_object staging_texture; + + memset(&staging_texture, 0, sizeof(staging_texture)); + demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, + VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_OPTIMAL, + (VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), + VK_MEMORY_PROPERTY_DEVICE_ONLY); + + demo_set_image_layout(demo, staging_texture.image, + staging_texture.imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); + + demo_set_image_layout(demo, demo->textures[i].image, + demo->textures[i].imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); + + VkImageCopy copy_region = { + .srcSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, + .srcOffset = { 0, 0, 0 }, + .destSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, + .destOffset = { 0, 0, 0 }, + .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 }, + }; + vkCmdCopyImage(demo->cmd, + staging_texture.image, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, + demo->textures[i].image, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + 1, ©_region); + + demo_add_mem_refs(demo, staging_texture.num_mem, staging_texture.mem); + demo_add_mem_refs(demo, demo->textures[i].num_mem, demo->textures[i].mem); + + demo_set_image_layout(demo, demo->textures[i].image, + VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + demo->textures[i].imageLayout); + + demo_flush_init_cmd(demo); + + demo_remove_mem_refs(demo, staging_texture.num_mem, staging_texture.mem); + demo_destroy_texture_image(demo, &staging_texture); + } else { + /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */ + assert(!"No support for B8G8R8A8_UNORM as texture image format"); + } + + const VkSamplerCreateInfo sampler = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = NULL, + .magFilter = VK_TEX_FILTER_NEAREST, + .minFilter = VK_TEX_FILTER_NEAREST, + .mipMode = VK_TEX_MIPMAP_MODE_BASE, + .addressU = VK_TEX_ADDRESS_WRAP, + .addressV = VK_TEX_ADDRESS_WRAP, + .addressW = VK_TEX_ADDRESS_WRAP, + .mipLodBias = 0.0f, + .maxAnisotropy = 1, + .compareOp = VK_COMPARE_OP_NEVER, + .minLod = 0.0f, + .maxLod = 0.0f, + .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE, + }; + VkImageViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = tex_format, + .channels = { VK_CHANNEL_SWIZZLE_R, + VK_CHANNEL_SWIZZLE_G, + VK_CHANNEL_SWIZZLE_B, + VK_CHANNEL_SWIZZLE_A, }, + .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 }, + .minLod = 0.0f, + }; + + /* create sampler */ + err = vkCreateSampler(demo->device, &sampler, + &demo->textures[i].sampler); + assert(!err); + + /* create image view */ + view.image = demo->textures[i].image; + err = vkCreateImageView(demo->device, &view, + &demo->textures[i].view); + assert(!err); + } +} + +static void demo_prepare_vertices(struct demo *demo) +{ + const float vb[3][5] = { + /* position texcoord */ + { -1.0f, -1.0f, -0.6f, 0.0f, 0.0f }, + { 1.0f, -1.0f, -0.5f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.5f, 1.0f }, + }; + const VkBufferCreateInfo buf_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = NULL, + .size = sizeof(vb), + .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + .flags = 0, + }; + VkMemoryAllocInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, + .pNext = NULL, + .allocationSize = 0, + .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memPriority = VK_MEMORY_PRIORITY_NORMAL, + }; + VkMemoryRequirements *mem_reqs; + size_t mem_reqs_size = sizeof(VkMemoryRequirements); + uint32_t num_allocations = 0; + size_t num_alloc_size = sizeof(num_allocations); + VkResult err; + void *data; + + memset(&demo->vertices, 0, sizeof(demo->vertices)); + + err = vkCreateBuffer(demo->device, &buf_info, &demo->vertices.buf); + assert(!err); + + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, + VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, + &num_alloc_size, &num_allocations); + assert(!err && num_alloc_size == sizeof(num_allocations)); + mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); + demo->vertices.mem = malloc(num_allocations * sizeof(VkDeviceMemory)); + demo->vertices.num_mem = num_allocations; + err = vkGetObjectInfo(demo->device, + VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, + VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, + &mem_reqs_size, mem_reqs); + assert(!err && mem_reqs_size == sizeof(*mem_reqs)); + for (uint32_t i = 0; i < num_allocations; i ++) { + mem_alloc.allocationSize = mem_reqs[i].size; + + err = vkAllocMemory(demo->device, &mem_alloc, &demo->vertices.mem[i]); + assert(!err); + + err = vkMapMemory(demo->device, demo->vertices.mem[i], 0, 0, 0, &data); + assert(!err); + + memcpy(data, vb, sizeof(vb)); + + err = vkUnmapMemory(demo->device, demo->vertices.mem[i]); + assert(!err); + + err = vkQueueBindObjectMemory(demo->queue, + VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, + i, demo->vertices.mem[i], 0); + assert(!err); + } + + demo_add_mem_refs(demo, demo->vertices.num_mem, demo->vertices.mem); + + demo->vertices.vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO; + demo->vertices.vi.pNext = NULL; + demo->vertices.vi.bindingCount = 1; + demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; + demo->vertices.vi.attributeCount = 2; + demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs; + + demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_bindings[0].strideInBytes = sizeof(vb[0]); + demo->vertices.vi_bindings[0].stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX; + + demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[0].location = 0; + demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT; + demo->vertices.vi_attrs[0].offsetInBytes = 0; + + demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[1].location = 1; + demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT; + demo->vertices.vi_attrs[1].offsetInBytes = sizeof(float) * 3; +} + +static void demo_prepare_descriptor_layout(struct demo *demo) +{ + const VkDescriptorSetLayoutBinding layout_binding = { + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .count = DEMO_TEXTURE_COUNT, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL, + }; + const VkDescriptorSetLayoutCreateInfo descriptor_layout = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = NULL, + .count = 1, + .pBinding = &layout_binding, + }; + VkResult err; + + err = vkCreateDescriptorSetLayout(demo->device, + &descriptor_layout, &demo->desc_layout); + assert(!err); + + const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = NULL, + .descriptorSetCount = 1, + .pSetLayouts = &demo->desc_layout, + }; + + err = vkCreatePipelineLayout(demo->device, + &pPipelineLayoutCreateInfo, + &demo->pipeline_layout); + assert(!err); +} + +static VkShader demo_prepare_shader(struct demo *demo, + VkShaderStage stage, + const void *code, + size_t size) +{ + VkShaderCreateInfo createInfo; + VkShader shader; + VkResult err; + + createInfo.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO; + createInfo.pNext = NULL; + + // Create fake SPV structure to feed GLSL + // to the driver "under the covers" + createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; + createInfo.pCode = malloc(createInfo.codeSize); + createInfo.flags = 0; + + /* try version 0 first: VkShaderStage followed by GLSL */ + ((uint32_t *) createInfo.pCode)[0] = ICD_SPV_MAGIC; + ((uint32_t *) createInfo.pCode)[1] = 0; + ((uint32_t *) createInfo.pCode)[2] = stage; + memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); + + err = vkCreateShader(demo->device, &createInfo, &shader); + if (err) { + free((void *) createInfo.pCode); + return VK_NULL_HANDLE; + } + + return shader; +} + +static VkShader demo_prepare_vs(struct demo *demo) +{ + static const char *vertShaderText = + "#version 140\n" + "#extension GL_ARB_separate_shader_objects : enable\n" + "#extension GL_ARB_shading_language_420pack : enable\n" + "layout (location = 0) in vec4 pos;\n" + "layout (location = 1) in vec2 attr;\n" + "out vec2 texcoord;\n" + "void main() {\n" + " texcoord = attr;\n" + " gl_Position = pos;\n" + "}\n"; + + return demo_prepare_shader(demo, VK_SHADER_STAGE_VERTEX, + (const void *) vertShaderText, + strlen(vertShaderText)); +} + +static VkShader demo_prepare_fs(struct demo *demo) +{ + static const char *fragShaderText = + "#version 140\n" + "#extension GL_ARB_separate_shader_objects : enable\n" + "#extension GL_ARB_shading_language_420pack : enable\n" + "layout (binding = 0) uniform sampler2D tex;\n" + "layout (location = 0) in vec2 texcoord;\n" + "void main() {\n" + " gl_FragColor = texture(tex, texcoord);\n" + "}\n"; + + return demo_prepare_shader(demo, VK_SHADER_STAGE_FRAGMENT, + (const void *) fragShaderText, + strlen(fragShaderText)); +} + +static void demo_prepare_pipeline(struct demo *demo) +{ + VkGraphicsPipelineCreateInfo pipeline; + VkPipelineVertexInputCreateInfo vi; + VkPipelineIaStateCreateInfo ia; + VkPipelineRsStateCreateInfo rs; + VkPipelineCbStateCreateInfo cb; + VkPipelineDsStateCreateInfo ds; + VkPipelineShaderStageCreateInfo vs; + VkPipelineShaderStageCreateInfo fs; + VkPipelineVpStateCreateInfo vp; + VkPipelineMsStateCreateInfo ms; + VkResult err; + + memset(&pipeline, 0, sizeof(pipeline)); + pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline.layout = demo->pipeline_layout; + + vi = demo->vertices.vi; + + memset(&ia, 0, sizeof(ia)); + ia.sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO; + ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + memset(&rs, 0, sizeof(rs)); + rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO; + rs.fillMode = VK_FILL_MODE_SOLID; + rs.cullMode = VK_CULL_MODE_NONE; + rs.frontFace = VK_FRONT_FACE_CCW; + + memset(&cb, 0, sizeof(cb)); + cb.sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO; + VkPipelineCbAttachmentState att_state[1]; + memset(att_state, 0, sizeof(att_state)); + att_state[0].format = demo->format; + att_state[0].channelWriteMask = 0xf; + att_state[0].blendEnable = VK_FALSE; + cb.attachmentCount = 1; + cb.pAttachments = att_state; + + + memset(&vp, 0, sizeof(vp)); + vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO; + vp.viewportCount = 1; + vp.clipOrigin = VK_COORDINATE_ORIGIN_UPPER_LEFT; + + memset(&ds, 0, sizeof(ds)); + ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO; + ds.format = demo->msaa_depth.format; + ds.depthTestEnable = VK_TRUE; + ds.depthWriteEnable = VK_TRUE; + ds.depthCompareOp = VK_COMPARE_OP_LESS_EQUAL; + ds.depthBoundsEnable = VK_FALSE; + ds.back.stencilFailOp = VK_STENCIL_OP_KEEP; + ds.back.stencilPassOp = VK_STENCIL_OP_KEEP; + ds.back.stencilCompareOp = VK_COMPARE_OP_ALWAYS; + ds.stencilTestEnable = VK_FALSE; + ds.front = ds.back; + + memset(&vs, 0, sizeof(vs)); + vs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vs.shader.stage = VK_SHADER_STAGE_VERTEX; + vs.shader.shader = demo_prepare_vs(demo); + vs.shader.linkConstBufferCount = 0; + + memset(&fs, 0, sizeof(fs)); + fs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fs.shader.stage = VK_SHADER_STAGE_FRAGMENT; + fs.shader.shader = demo_prepare_fs(demo); + + memset(&ms, 0, sizeof(ms)); + ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; + ms.sampleMask = 0xffff; + ms.multisampleEnable = VK_TRUE; + ms.samples = 4; + + pipeline.pNext = (const void *) &vi; + vi.pNext = (void *) &ia; + ia.pNext = (const void *) &rs; + rs.pNext = (const void *) &cb; + cb.pNext = (const void *) &ms; + ms.pNext = (const void *) &vp; + vp.pNext = (const void *) &ds; + ds.pNext = (const void *) &vs; + vs.pNext = (const void *) &fs; + + err = vkCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); + assert(!err); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, vs.shader.shader); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, fs.shader.shader); +} + +static void demo_prepare_dynamic_states(struct demo *demo) +{ + VkDynamicVpStateCreateInfo viewport_create; + VkDynamicRsStateCreateInfo raster; + VkDynamicCbStateCreateInfo color_blend; + VkDynamicDsStateCreateInfo depth_stencil; + VkResult err; + + memset(&viewport_create, 0, sizeof(viewport_create)); + viewport_create.sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO; + viewport_create.viewportAndScissorCount = 1; + VkViewport viewport; + memset(&viewport, 0, sizeof(viewport)); + viewport.height = (float) demo->height; + viewport.width = (float) demo->width; + viewport.minDepth = (float) 0.0f; + viewport.maxDepth = (float) 1.0f; + viewport_create.pViewports = &viewport; + VkRect scissor; + memset(&scissor, 0, sizeof(scissor)); + scissor.extent.width = demo->width; + scissor.extent.height = demo->height; + scissor.offset.x = 0; + scissor.offset.y = 0; + viewport_create.pScissors = &scissor; + + memset(&raster, 0, sizeof(raster)); + raster.sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO; + raster.pointSize = 1.0; + raster.lineWidth = 1.0; + + memset(&color_blend, 0, sizeof(color_blend)); + color_blend.sType = VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO; + color_blend.blendConst[0] = 1.0f; + color_blend.blendConst[1] = 1.0f; + color_blend.blendConst[2] = 1.0f; + color_blend.blendConst[3] = 1.0f; + + memset(&depth_stencil, 0, sizeof(depth_stencil)); + depth_stencil.sType = VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO; + depth_stencil.minDepth = 0.0f; + depth_stencil.maxDepth = 1.0f; + depth_stencil.stencilBackRef = 0; + depth_stencil.stencilFrontRef = 0; + depth_stencil.stencilReadMask = 0xff; + depth_stencil.stencilWriteMask = 0xff; + + err = vkCreateDynamicViewportState(demo->device, &viewport_create, &demo->viewport); + assert(!err); + + err = vkCreateDynamicRasterState(demo->device, &raster, &demo->raster); + assert(!err); + + err = vkCreateDynamicColorBlendState(demo->device, + &color_blend, &demo->color_blend); + assert(!err); + + err = vkCreateDynamicDepthStencilState(demo->device, + &depth_stencil, &demo->depth_stencil); + assert(!err); +} + +static void demo_prepare_descriptor_pool(struct demo *demo) +{ + const VkDescriptorTypeCount type_count = { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .count = DEMO_TEXTURE_COUNT, + }; + const VkDescriptorPoolCreateInfo descriptor_pool = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = NULL, + .count = 1, + .pTypeCount = &type_count, + }; + VkResult err; + + err = vkCreateDescriptorPool(demo->device, + VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, + &descriptor_pool, &demo->desc_pool); + assert(!err); +} + +static void demo_prepare_descriptor_set(struct demo *demo) +{ + VkImageViewAttachInfo view_info[DEMO_TEXTURE_COUNT]; + VkSamplerImageViewInfo combined_info[DEMO_TEXTURE_COUNT]; + VkUpdateSamplerTextures update; + const void *update_array[1] = { &update }; + VkResult err; + uint32_t count; + uint32_t i; + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + view_info[i].sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO; + view_info[i].pNext = NULL; + view_info[i].view = demo->textures[i].view, + view_info[i].layout = VK_IMAGE_LAYOUT_GENERAL; + + combined_info[i].sampler = demo->textures[i].sampler; + combined_info[i].pImageView = &view_info[i]; + } + + memset(&update, 0, sizeof(update)); + update.sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES; + update.count = DEMO_TEXTURE_COUNT; + update.pSamplerImageViews = combined_info; + + err = vkAllocDescriptorSets(demo->device, demo->desc_pool, + VK_DESCRIPTOR_SET_USAGE_STATIC, + 1, &demo->desc_layout, + &demo->desc_set, &count); + assert(!err && count == 1); + + vkBeginDescriptorPoolUpdate(demo->device, + VK_DESCRIPTOR_UPDATE_MODE_FASTEST); + + vkClearDescriptorSets(demo->device, demo->desc_pool, 1, &demo->desc_set); + vkUpdateDescriptors(demo->device, demo->desc_set, 1, update_array); + + vkEndDescriptorPoolUpdate(demo->device, demo->cmd); +} + +static void demo_prepare(struct demo *demo) +{ + const VkCmdBufferCreateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, + .pNext = NULL, + .queueNodeIndex = demo->graphics_queue_node_index, + .flags = 0, + }; + VkResult err; + + demo_prepare_buffers(demo); + demo_prepare_depth(demo); + demo_prepare_textures(demo); + demo_prepare_vertices(demo); + demo_prepare_descriptor_layout(demo); + demo_prepare_pipeline(demo); + demo_prepare_dynamic_states(demo); + + err = vkCreateCommandBuffer(demo->device, &cmd, &demo->cmd); + assert(!err); + + demo_prepare_descriptor_pool(demo); + demo_prepare_descriptor_set(demo); + demo->prepared = true; +} + +#ifdef _WIN32 +static void demo_run(struct demo *demo) +{ + if (!demo->prepared) + return; + demo_draw(demo); +} + +// On MS-Windows, make this a global, so it's available to WndProc() +struct demo demo; + +// MS-Windows event handling function: +LRESULT CALLBACK WndProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + char tmp_str[] = APP_LONG_NAME; + + switch(uMsg) + { + case WM_CREATE: + return 0; + case WM_CLOSE: + demo.prepared = false; + DestroyWindow(hWnd); + PostQuitMessage(0); + return 0; + case WM_PAINT: + demo_run(&demo); + return 0; + default: + break; + } + return (DefWindowProc(hWnd, uMsg, wParam, lParam)); +} + +static void demo_create_window(struct demo *demo) +{ + WNDCLASSEX win_class; + + // Initialize the window class structure: + win_class.cbSize = sizeof(WNDCLASSEX); + win_class.style = CS_HREDRAW | CS_VREDRAW; + win_class.lpfnWndProc = WndProc; + win_class.cbClsExtra = 0; + win_class.cbWndExtra = 0; + win_class.hInstance = demo->connection; // hInstance + win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + win_class.hCursor = LoadCursor(NULL, IDC_ARROW); + win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + win_class.lpszMenuName = NULL; + win_class.lpszClassName = demo->name; + win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); + // Register window class: + if (!RegisterClassEx(&win_class)) { + // It didn't work, so try to give a useful error: + printf("Unexpected error trying to start the application!\n"); + fflush(stdout); + WAIT_FOR_CONSOLE_DESTROY; + exit(1); + } + // Create window with the registered class: + demo->window = CreateWindowEx(0, + demo->name, // class name + demo->name, // app name + WS_OVERLAPPEDWINDOW | // window style + WS_VISIBLE | + WS_SYSMENU, + 100,100, // x/y coords + demo->width, // width + demo->height, // height + NULL, // handle to parent + NULL, // handle to menu + demo->connection, // hInstance + NULL); // no extra parameters + if (!demo->window) { + // It didn't work, so try to give a useful error: + printf("Cannot create a window in which to draw!\n"); + fflush(stdout); + WAIT_FOR_CONSOLE_DESTROY; + exit(1); + } +} +#else // _WIN32 + +static void demo_handle_event(struct demo *demo, + const xcb_generic_event_t *event) +{ + switch (event->response_type & 0x7f) { + case XCB_EXPOSE: + demo_draw(demo); + break; + case XCB_CLIENT_MESSAGE: + if((*(xcb_client_message_event_t*)event).data.data32[0] == + (*demo->atom_wm_delete_window).atom) { + demo->quit = true; + } + break; + case XCB_KEY_RELEASE: + { + const xcb_key_release_event_t *key = + (const xcb_key_release_event_t *) event; + + if (key->detail == 0x9) + demo->quit = true; + } + break; + case XCB_DESTROY_NOTIFY: + demo->quit = true; + break; + default: + break; + } +} + +static void demo_run(struct demo *demo) +{ + xcb_flush(demo->connection); + + while (!demo->quit) { + xcb_generic_event_t *event; + + event = xcb_wait_for_event(demo->connection); + if (event) { + demo_handle_event(demo, event); + free(event); + } + } +} + +static void demo_create_window(struct demo *demo) +{ + uint32_t value_mask, value_list[32]; + + demo->window = xcb_generate_id(demo->connection); + + value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + value_list[0] = demo->screen->black_pixel; + value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY; + + xcb_create_window(demo->connection, + XCB_COPY_FROM_PARENT, + demo->window, demo->screen->root, + 0, 0, demo->width, demo->height, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + demo->screen->root_visual, + value_mask, value_list); + + /* Magic code that will send notification when window is destroyed */ + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, + "WM_PROTOCOLS"); + xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0); + + xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); + demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); + + xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, + demo->window, (*reply).atom, 4, 32, 1, + &(*demo->atom_wm_delete_window).atom); + free(reply); + + xcb_map_window(demo->connection, demo->window); +} +#endif // _WIN32 + +static void demo_init_vk(struct demo *demo) +{ + VkResult err; + // Extensions to enable + const char *ext_names[] = { + "VK_WSI_LunarG", + }; + size_t extSize = sizeof(uint32_t); + uint32_t extCount = 0; + err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount); + assert(!err); + + VkExtensionProperties extProp; + extSize = sizeof(VkExtensionProperties); + bool32_t extFound = 0; + for (uint32_t i = 0; i < extCount; i++) { + err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &extSize, &extProp); + if (!strcmp(ext_names[0], extProp.extName)) + extFound = 1; + } + if (!extFound) { + ERR_EXIT("vkGetGlobalExtensionInfo failed to find the " + "\"VK_WSI_LunarG\" extension.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + const VkApplicationInfo app = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = NULL, + .pAppName = APP_SHORT_NAME, + .appVersion = 0, + .pEngineName = APP_SHORT_NAME, + .engineVersion = 0, + .apiVersion = VK_API_VERSION, + }; + const VkInstanceCreateInfo inst_info = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = NULL, + .pAppInfo = &app, + .pAllocCb = NULL, + .extensionCount = 1, + .ppEnabledExtensionNames = ext_names, + }; + const VkDeviceQueueCreateInfo queue = { + .queueNodeIndex = 0, + .queueCount = 1, + }; + const VkDeviceCreateInfo device = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = NULL, + .queueRecordCount = 1, + .pRequestedQueues = &queue, + .extensionCount = 1, + .ppEnabledExtensionNames = ext_names, + .flags = VK_DEVICE_CREATE_VALIDATION_BIT, + }; + uint32_t gpu_count; + uint32_t i; + size_t data_size; + uint32_t queue_count; + + err = vkCreateInstance(&inst_info, &demo->inst); + if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { + ERR_EXIT("Cannot find a compatible Vulkan installable client driver " + "(ICD).\n\nPlease look at the Getting Started guide for " + "additional information.\n", + "vkCreateInstance Failure"); + } else if (err) { + ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan " + "installable client driver (ICD) installed?\nPlease look at " + "the Getting Started guide for additional information.\n", + "vkCreateInstance Failure"); + } + + gpu_count = 1; + err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, &demo->gpu); + assert(!err && gpu_count == 1); + + err = vkCreateDevice(demo->gpu, &device, &demo->device); + assert(!err); + + err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, + &data_size, NULL); + assert(!err); + + demo->gpu_props = (VkPhysicalDeviceProperties *) malloc(data_size); + err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, + &data_size, demo->gpu_props); + assert(!err); + + err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES, + &data_size, NULL); + assert(!err); + + demo->queue_props = (VkPhysicalDeviceQueueProperties *) malloc(data_size); + err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES, + &data_size, demo->queue_props); + assert(!err); + queue_count = (uint32_t) (data_size / sizeof(VkPhysicalDeviceQueueProperties)); + assert(queue_count >= 1); + + for (i = 0; i < queue_count; i++) { + if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + break; + if (demo->queue_props[i].queueFlags & VK_QUEUE_MEMMGR_BIT) + break; + } + assert(i < queue_count); + demo->graphics_queue_node_index = i; + + err = vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, + 0, &demo->queue); + assert(!err); +} + +static void demo_init_connection(struct demo *demo) +{ +#ifndef _WIN32 + const xcb_setup_t *setup; + xcb_screen_iterator_t iter; + int scr; + + demo->connection = xcb_connect(NULL, &scr); + if (demo->connection == NULL) { + printf("Cannot find a compatible Vulkan installable client driver " + "(ICD).\nExiting ...\n"); + fflush(stdout); + exit(1); + } + + setup = xcb_get_setup(demo->connection); + iter = xcb_setup_roots_iterator(setup); + while (scr-- > 0) + xcb_screen_next(&iter); + + demo->screen = iter.data; +#endif // _WIN32 +} + +#ifdef _WIN32 +static void demo_init(struct demo *demo, HINSTANCE hInstance, LPSTR pCmdLine) +#else // _WIN32 +static void demo_init(struct demo *demo, const int argc, const char *argv[]) +#endif // _WIN32 +{ + bool argv_error = false; + + memset(demo, 0, sizeof(*demo)); + +#ifdef _WIN32 + demo->connection = hInstance; + strncpy(demo->name, APP_SHORT_NAME, APP_NAME_STR_LEN); + + if (strncmp(pCmdLine, "--use_staging", strlen("--use_staging")) == 0) + demo->use_staging_buffer = true; + else if (strlen(pCmdLine) != 0) { + fprintf(stderr, "Do not recognize argument \"%s\".\n", pCmdLine); + argv_error = true; + } +#else // _WIN32 + for (int i = 0; i < argc; i++) { + if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0) + demo->use_staging_buffer = true; + } +#endif // _WIN32 + if (argv_error) { + fprintf(stderr, "Usage:\n %s [--use_staging]\n", APP_SHORT_NAME); + fflush(stderr); + WAIT_FOR_CONSOLE_DESTROY; + exit(1); + } + + demo_init_connection(demo); + demo_init_vk(demo); + + demo->width = 300; + demo->height = 300; + demo->format = VK_FORMAT_B8G8R8A8_UNORM; +} + +static void demo_cleanup(struct demo *demo) +{ + uint32_t i, j; + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_SET, demo->desc_set); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_POOL, demo->desc_pool); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_COMMAND_BUFFER, demo->cmd); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_VP_STATE, demo->viewport); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_RS_STATE, demo->raster); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_CB_STATE, demo->color_blend); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_DS_STATE, demo->depth_stencil); + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_PIPELINE, demo->pipeline); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, demo->pipeline_layout); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, demo->desc_layout); + + vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, 0, VK_NULL_HANDLE, 0); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf); + demo_remove_mem_refs(demo, demo->vertices.num_mem, demo->vertices.mem); + for (j = 0; j < demo->vertices.num_mem; j++) + vkFreeMemory(demo->device, demo->vertices.mem[j]); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE_VIEW, demo->textures[i].view); + vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image); + demo_remove_mem_refs(demo, demo->textures[i].num_mem, demo->textures[i].mem); + for (j = 0; j < demo->textures[i].num_mem; j++) + vkFreeMemory(demo->device, demo->textures[i].mem[j]); + free(demo->textures[i].mem); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_SAMPLER, demo->textures[i].sampler); + } + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW, demo->msaa_color.view); + vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, 0, VK_NULL_HANDLE, 0); + demo_remove_mem_refs(demo, demo->msaa_color.num_mem, demo->msaa_color.mem); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image); + for (j = 0; j < demo->msaa_color.num_mem; j++) { + vkFreeMemory(demo->device, demo->msaa_color.mem[j]); + } + + vkDestroyObject(demo->device, VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW, demo->msaa_depth.view); + vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, 0, VK_NULL_HANDLE, 0); + demo_remove_mem_refs(demo, demo->msaa_depth.num_mem, demo->msaa_depth.mem); + vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image); + for (j = 0; j < demo->msaa_depth.num_mem; j++) { + vkFreeMemory(demo->device, demo->msaa_depth.mem[j]); + } + + for (i = 0; i < DEMO_BUFFER_COUNT; i++) { + demo_remove_mem_refs(demo, 1, &demo->buffers[i].mem); + } + vkDestroySwapChainWSI(demo->swap_chain); + + vkDestroyDevice(demo->device); + vkDestroyInstance(demo->inst); + +#ifndef _WIN32 + xcb_destroy_window(demo->connection, demo->window); + xcb_disconnect(demo->connection); +#endif // _WIN32 +} + +#ifdef _WIN32 +// The following function was copied from the Vulkan loader: +char *get_registry_string(const HKEY hive, + const LPCTSTR sub_key, + const char *value) +{ + DWORD access_flags = KEY_QUERY_VALUE; + DWORD value_type; + HKEY key; + VkResult rtn_value; + char *rtn_str = NULL; + size_t rtn_len = 0; + size_t allocated_len = 0; + + rtn_value = RegOpenKeyEx(hive, sub_key, 0, access_flags, &key); + if (rtn_value != ERROR_SUCCESS) { + // We didn't find the key. Try the 32-bit hive (where we've seen the + // key end up on some people's systems): + access_flags |= KEY_WOW64_32KEY; + rtn_value = RegOpenKeyEx(hive, sub_key, 0, access_flags, &key); + if (rtn_value != ERROR_SUCCESS) { + // We still couldn't find the key, so give up: + return NULL; + } + } + + rtn_value = RegQueryValueEx(key, value, NULL, &value_type, + (PVOID) rtn_str, (LPDWORD) &rtn_len); + if (rtn_value == ERROR_SUCCESS) { + // If we get to here, we found the key, and need to allocate memory + // large enough for rtn_str, and query again: + allocated_len = rtn_len + 4; + rtn_str = malloc(allocated_len); + rtn_value = RegQueryValueEx(key, value, NULL, &value_type, + (PVOID) rtn_str, (LPDWORD) &rtn_len); + if (rtn_value == ERROR_SUCCESS) { + // We added 4 extra bytes to rtn_str, so that we can ensure that + // the string is NULL-terminated (albeit, in a brute-force manner): + rtn_str[allocated_len-1] = '\0'; + } else { + // This should never occur, but in case it does, clean up: + free(rtn_str); + rtn_str = NULL; + } + } // else - shouldn't happen, but if it does, return rtn_str, which is NULL + + // Close the registry key that was opened: + RegCloseKey(key); + + return rtn_str; +} + + +// The following function was copied from the Vulkan loader: +static char *get_registry_and_env(const char *env_var, + const char *registry_value) +{ + char *env_str = getenv(env_var); + size_t env_len = (env_str == NULL) ? 0 : strlen(env_str); + char *registry_str = NULL; + DWORD registry_len = 0; + char *rtn_str = NULL; + size_t rtn_len; + + registry_str = get_registry_string(HKEY_LOCAL_MACHINE, + "Software\\Vulkan", + registry_value); + registry_len = (registry_str) ? (DWORD) strlen(registry_str) : 0; + + rtn_len = env_len + registry_len + 1; + if (rtn_len <= 2) { + // We found neither the desired registry value, nor the environment + // variable; return NULL: + return NULL; + } else { + // We found something, and so we need to allocate memory for the string + // to return: + rtn_str = malloc(rtn_len); + } + + if (registry_len == 0) { + // We didn't find the desired registry value, and so we must have found + // only the environment variable: + _snprintf(rtn_str, rtn_len, "%s", env_str); + } else if (env_str != NULL) { + // We found both the desired registry value and the environment + // variable, so concatenate them both: + _snprintf(rtn_str, rtn_len, "%s;%s", registry_str, env_str); + } else { + // We must have only found the desired registry value: + _snprintf(rtn_str, rtn_len, "%s", registry_str); + } + + if (registry_str) { + free(registry_str); + } + + return(rtn_str); +} + +// Create a console window with a large scrollback size to which to send stdout. +// Returns true if console window was successfully created, false otherwise. +bool SetStdOutToNewConsole() +{ + // don't do anything if we already have a console + if (GetStdHandle(STD_OUTPUT_HANDLE)) + return false; + + // allocate a console for this app + AllocConsole(); + + // redirect unbuffered STDOUT to the console + HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); + FILE *fp = _fdopen( fileDescriptor, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + + // make the console window bigger + CONSOLE_SCREEN_BUFFER_INFO csbi; + SMALL_RECT r; + COORD bufferSize; + if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) + return false; + bufferSize.X = csbi.dwSize.X; + bufferSize.Y = 1000; + if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) + return false; + r.Left = r.Top = 0; + r.Right = csbi.dwSize.X-1; + r.Bottom = 60; + if (!SetConsoleWindowInfo(consoleHandle, true, &r)) + return false; + + // change the console window title + if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) + return false; + + return true; +} + +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR pCmdLine, + int nCmdShow) +{ + MSG msg; // message + bool done; // flag saying when app is complete + char *layers_enabled = get_registry_and_env(LAYER_NAMES_ENV, + LAYER_NAMES_REGISTRY_VALUE); + + if (layers_enabled != NULL) { + consoleCreated = SetStdOutToNewConsole(); + free(layers_enabled); + } + + demo_init(&demo, hInstance, pCmdLine); + demo_create_window(&demo); + + demo_prepare(&demo); + + done = false; //initialize loop condition variable + /* main message loop*/ + while(!done) + { + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + if (msg.message == WM_QUIT) //check for a quit message + { + done = true; //if found, quit app + } + else + { + /* Translate and dispatch to event queue*/ + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + demo_cleanup(&demo); + + if (consoleCreated) { + printf("\nPlease close this window when you are finished looking at " + "the console output.\n"); + fflush(stdout); + WAIT_FOR_CONSOLE_DESTROY; + } + + return (int) msg.wParam; +} +#else // _WIN32 +int main(const int argc, const char *argv[]) +{ + struct demo demo; + + demo_init(&demo, argc, argv); + demo_create_window(&demo); + + demo_prepare(&demo); + demo_run(&demo); + + demo_cleanup(&demo); + + return 0; +} +#endif // _WIN32 -- cgit v1.2.3 From dd87ec823847334730fe017c4efe2b3d9deac719 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Wed, 13 May 2015 16:25:37 -0600 Subject: Revert "demos: Add msaa-tri.c for msaa rendering example modified from tri.c" This reverts commit 0e83c4d651d5602a35b5c54eb59f2543310b5f31. --- demos/msaa-tri.c | 1948 ------------------------------------------------------ 1 file changed, 1948 deletions(-) delete mode 100644 demos/msaa-tri.c diff --git a/demos/msaa-tri.c b/demos/msaa-tri.c deleted file mode 100644 index a8e10c9b..00000000 --- a/demos/msaa-tri.c +++ /dev/null @@ -1,1948 +0,0 @@ -/* - * Vulkan - * - * Copyright (C) 2014-2015 LunarG, Inc. - * Copyright (c) 2015 Samsung Electronics, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -/* - * Draw a textured triangle with depth testing. This is written against Intel - * ICD. It does not do state transition nor object memory binding like it - * should. It also does no error checking. - */ -/* Modified to use MSAA - * - * Changes to tri.c - * (1) No color attachment views created for swap chain images - * (2) create an offscreen MSAA (samples = 4) image as color attachment - * (3) create msaa depth/stencil image - * (4) during draw time, attach msaa image and msaa depth/stencil buffer - * as color and depth/stencil attachment - * (5) once drawn to msaa color image, resolve it to swap chain image - */ -/* Contributed by Henry Song (henry.song@samsung.com) */ - -#ifndef VK_PROTOTYPES -#define VK_PROTOTYPES -#endif - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#pragma comment(linker, "/subsystem:windows") -#include -#include -#include -#define APP_NAME_STR_LEN 80 -#else // _WIN32 -#include -#endif // _WIN32 - -#include -#include -#include - -#include "icd-spv.h" - -#define DEMO_BUFFER_COUNT 2 -#define DEMO_TEXTURE_COUNT 1 -#define VERTEX_BUFFER_BIND_ID 0 -#define APP_SHORT_NAME "tri" -#define APP_LONG_NAME "The Vulkan Triangle Demo Program" - -#ifdef _WIN32 -bool consoleCreated = false; - -#define WAIT_FOR_CONSOLE_DESTROY \ - do { \ - if (consoleCreated) \ - Sleep(INFINITE); \ - } while (0) - -#define ERR_EXIT(err_msg, err_class) \ - do { \ - MessageBox(NULL, err_msg, err_class, MB_OK); \ - if (consoleCreated) { \ - printf("\nPlease close this window when you are finished " \ - "looking at the console output.\n"); \ - fflush(stdout); \ - } \ - WAIT_FOR_CONSOLE_DESTROY; \ - exit(1); \ - } while (0) - -// NOTE: If the following values (copied from "loader_platform.h") change, they -// need to change here as well: -#define LAYER_NAMES_ENV "VK_LAYER_NAMES" -#define LAYER_NAMES_REGISTRY_VALUE "VK_LAYER_NAMES" -#else // _WIN32 - #define WAIT_FOR_CONSOLE_DESTROY - -#define ERR_EXIT(err_msg, err_class) \ - do { \ - printf(err_msg); \ - fflush(stdout); \ - exit(1); \ - } while (0) -#endif // _WIN32 - -struct texture_object { - VkSampler sampler; - - VkImage image; - VkImageLayout imageLayout; - - uint32_t num_mem; - VkDeviceMemory *mem; - VkImageView view; - int32_t tex_width, tex_height; -}; - -struct demo { -#ifdef _WIN32 -#define APP_NAME_STR_LEN 80 - HINSTANCE connection; // hInstance - Windows Instance - char name[APP_NAME_STR_LEN]; // Name to put on the window/icon - HWND window; // hWnd - window handle -#else // _WIN32 - xcb_connection_t *connection; - xcb_screen_t *screen; - xcb_window_t window; - xcb_intern_atom_reply_t *atom_wm_delete_window; -#endif // _WIN32 - bool prepared; - bool use_staging_buffer; - - VkInstance inst; - VkPhysicalDevice gpu; - VkDevice device; - VkQueue queue; - VkPhysicalDeviceProperties *gpu_props; - VkPhysicalDeviceQueueProperties *queue_props; - uint32_t graphics_queue_node_index; - - int width, height; - VkFormat format; - - VkSwapChainWSI swap_chain; - struct { - VkImage image; - VkDeviceMemory mem; - } buffers[DEMO_BUFFER_COUNT]; - - struct { - VkFormat format; - - VkImage image; - uint32_t num_mem; - VkDeviceMemory *mem; - VkColorAttachmentView view; - } msaa_color; - - struct { - VkFormat format; - - VkImage image; - uint32_t num_mem; - VkDeviceMemory *mem; - VkDepthStencilView view; - } msaa_depth; - - struct texture_object textures[DEMO_TEXTURE_COUNT]; - - struct { - VkBuffer buf; - uint32_t num_mem; - VkDeviceMemory *mem; - - VkPipelineVertexInputCreateInfo vi; - VkVertexInputBindingDescription vi_bindings[1]; - VkVertexInputAttributeDescription vi_attrs[2]; - } vertices; - - VkCmdBuffer cmd; // Buffer for initialization commands - VkPipelineLayout pipeline_layout; - VkDescriptorSetLayout desc_layout; - VkPipeline pipeline; - - VkDynamicVpState viewport; - VkDynamicRsState raster; - VkDynamicCbState color_blend; - VkDynamicDsState depth_stencil; - - VkDescriptorPool desc_pool; - VkDescriptorSet desc_set; - - bool quit; - uint32_t current_buffer; -}; - -static void demo_flush_init_cmd(struct demo *demo) -{ - VkResult err; - - if (demo->cmd == VK_NULL_HANDLE) - return; - - err = vkEndCommandBuffer(demo->cmd); - assert(!err); - - const VkCmdBuffer cmd_bufs[] = { demo->cmd }; - - err = vkQueueSubmit(demo->queue, 1, cmd_bufs, VK_NULL_HANDLE); - assert(!err); - - err = vkQueueWaitIdle(demo->queue); - assert(!err); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_COMMAND_BUFFER, demo->cmd); - demo->cmd = VK_NULL_HANDLE; -} - -static void demo_add_mem_refs( - struct demo *demo, - int num_refs, VkDeviceMemory *mem) -{ - vkQueueAddMemReferences(demo->queue, num_refs, mem); -} - -static void demo_remove_mem_refs( - struct demo *demo, - int num_refs, VkDeviceMemory *mem) -{ - vkQueueRemoveMemReferences(demo->queue, num_refs, mem); -} - -static void demo_set_image_layout( - struct demo *demo, - VkImage image, - VkImageLayout old_image_layout, - VkImageLayout new_image_layout) -{ - VkResult err; - - if (demo->cmd == VK_NULL_HANDLE) { - const VkCmdBufferCreateInfo cmd = { - .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, - .pNext = NULL, - .queueNodeIndex = demo->graphics_queue_node_index, - .flags = 0, - }; - - err = vkCreateCommandBuffer(demo->device, &cmd, &demo->cmd); - assert(!err); - - VkCmdBufferBeginInfo cmd_buf_info = { - .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | - VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, - }; - err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info); - } - - VkImageMemoryBarrier image_memory_barrier = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = NULL, - .outputMask = 0, - .inputMask = 0, - .oldLayout = old_image_layout, - .newLayout = new_image_layout, - .image = image, - .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } - }; - - if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL) { - /* Make sure anything that was copying from this image has completed */ - image_memory_barrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT; - } - - if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - /* Make sure any Copy or CPU writes to image are flushed */ - image_memory_barrier.outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT | VK_MEMORY_OUTPUT_CPU_WRITE_BIT; - } - - VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier; - - VkPipeEvent set_events[] = { VK_PIPE_EVENT_TOP_OF_PIPE }; - - vkCmdPipelineBarrier(demo->cmd, VK_WAIT_EVENT_TOP_OF_PIPE, 1, set_events, 1, (const void **)&pmemory_barrier); -} - -static void demo_draw_build_cmd(struct demo *demo) -{ - const VkColorAttachmentBindInfo color_attachment = { - .view = demo->msaa_color.view, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }; - const VkDepthStencilBindInfo depth_stencil = { - .view = demo->msaa_depth.view, - .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - }; - const VkClearColor clear_color = { - .color.floatColor = { 0.2f, 0.2f, 0.2f, 1.0f }, - .useRawValue = false, - }; - const float clear_depth = 0.0f; - VkImageSubresourceRange clear_range; - VkCmdBufferBeginInfo cmd_buf_info = { - .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | - VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, - }; - VkResult err; - VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - VkAttachmentStoreOp store_op = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; - const VkFramebufferCreateInfo fb_info = { - .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .pNext = NULL, - .colorAttachmentCount = 1, - .pColorAttachments = (VkColorAttachmentBindInfo*) &color_attachment, - .pDepthStencilAttachment = (VkDepthStencilBindInfo*) &depth_stencil, - .sampleCount = 4, - .width = demo->width, - .height = demo->height, - .layers = 1, - }; - VkRenderPassCreateInfo rp_info; - VkRenderPassBegin rp_begin; - - memset(&rp_info, 0 , sizeof(rp_info)); - err = vkCreateFramebuffer(demo->device, &fb_info, &rp_begin.framebuffer); - assert(!err); - rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rp_info.renderArea.extent.width = demo->width; - rp_info.renderArea.extent.height = demo->height; - rp_info.colorAttachmentCount = fb_info.colorAttachmentCount; - rp_info.pColorFormats = &demo->format; - rp_info.pColorLayouts = &color_attachment.layout; - rp_info.pColorLoadOps = &load_op; - rp_info.pColorStoreOps = &store_op; - rp_info.pColorLoadClearValues = &clear_color; - rp_info.depthStencilFormat = VK_FORMAT_D16_UNORM; - rp_info.depthStencilLayout = depth_stencil.layout; - rp_info.depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - rp_info.depthLoadClearValue = clear_depth; - rp_info.depthStoreOp = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; - rp_info.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - rp_info.stencilLoadClearValue = 0; - rp_info.stencilStoreOp = VK_ATTACHMENT_STORE_OP_RESOLVE_MSAA; - err = vkCreateRenderPass(demo->device, &rp_info, &(rp_begin.renderPass)); - assert(!err); - - err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info); - assert(!err); - - - vkCmdBindPipeline(demo->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - demo->pipeline); - vkCmdBindDescriptorSets(demo->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, 1, & demo->desc_set, 0, NULL); - - vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_VIEWPORT, demo->viewport); - vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_RASTER, demo->raster); - vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_COLOR_BLEND, - demo->color_blend); - vkCmdBindDynamicStateObject(demo->cmd, VK_STATE_BIND_POINT_DEPTH_STENCIL, - demo->depth_stencil); - - VkDeviceSize offsets[1] = {0}; - vkCmdBindVertexBuffers(demo->cmd, VERTEX_BUFFER_BIND_ID, 1, &demo->vertices.buf, offsets); - - vkCmdBeginRenderPass(demo->cmd, &rp_begin); - clear_range.aspect = VK_IMAGE_ASPECT_COLOR; - clear_range.baseMipLevel = 0; - clear_range.mipLevels = 1; - clear_range.baseArraySlice = 0; - clear_range.arraySize = 1; - - vkCmdClearColorImage(demo->cmd, - demo->msaa_color.image, - VK_IMAGE_LAYOUT_CLEAR_OPTIMAL, - clear_color, 1, &clear_range); - - clear_range.aspect = VK_IMAGE_ASPECT_DEPTH; - vkCmdClearDepthStencil(demo->cmd, - demo->msaa_depth.image, VK_IMAGE_LAYOUT_CLEAR_OPTIMAL, - clear_depth, 0, 1, &clear_range); - - vkCmdDraw(demo->cmd, 0, 3, 0, 1); - vkCmdEndRenderPass(demo->cmd, rp_begin.renderPass); - - VkImageResolve resolve = { - .srcSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, - .srcOffset = { 0, 0, 0 }, - .destSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, - .destOffset = { 0, 0, 0 }, - .extent = { demo->width, demo->height, 1 } - }; - - demo_set_image_layout(demo, demo->msaa_color.image, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); - - vkCmdResolveImage(demo->cmd, demo->msaa_color.image, - VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, - demo->buffers[demo->current_buffer].image, - VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, &resolve); - - err = vkEndCommandBuffer(demo->cmd); - assert(!err); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_RENDER_PASS, rp_begin.renderPass); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_FRAMEBUFFER, rp_begin.framebuffer); -} - -static void demo_draw(struct demo *demo) -{ - const VkPresentInfoWSI present = { - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_WSI, - .pNext = NULL, - .image = demo->buffers[demo->current_buffer].image, - .flipInterval = 0, - }; - VkResult err; - - demo_draw_build_cmd(demo); - - err = vkQueueSubmit(demo->queue, 1, &demo->cmd, VK_NULL_HANDLE); - assert(!err); - - err = vkQueuePresentWSI(demo->queue, &present); - assert(!err); - - demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; - - err = vkQueueWaitIdle(demo->queue); - assert(err == VK_SUCCESS); -} - -static void demo_prepare_buffers(struct demo *demo) -{ - const VkSwapChainCreateInfoWSI swap_chain = { - .sType = VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI, - .pNext = NULL, - .pNativeWindowSystemHandle = demo->connection, - .pNativeWindowHandle = (void *) (intptr_t) demo->window, - .imageCount = DEMO_BUFFER_COUNT, - .imageFormat = demo->format, - .imageExtent = { - .width = demo->width, - .height = demo->height, - }, - .imageArraySize = 1, - .imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, - }; - VkSwapChainImageInfoWSI images[DEMO_BUFFER_COUNT]; - size_t images_size = sizeof(images); - VkResult err; - uint32_t i; - - err = vkCreateSwapChainWSI(demo->device, &swap_chain, &demo->swap_chain); - assert(!err); - - err = vkGetSwapChainInfoWSI(demo->swap_chain, - VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI, - &images_size, images); - assert(!err && images_size == sizeof(images)); - - for (i = 0; i < DEMO_BUFFER_COUNT; i++) { - demo->buffers[i].image = images[i].image; - demo->buffers[i].mem = images[i].memory; - - demo_add_mem_refs(demo, 1, &demo->buffers[i].mem); - demo_set_image_layout(demo, demo->buffers[i].image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); - } - - demo->current_buffer = 0; - - /* create MSAA image */ - const VkFormat msaa_format = VK_FORMAT_B8G8R8A8_UNORM; - - const VkImageCreateInfo msaa_image_create_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = NULL, - .imageType = VK_IMAGE_TYPE_2D, - .format = msaa_format, - .extent = { demo->width, demo->height, 1 }, - .mipLevels = 1, - .arraySize = 1, - .samples = 4, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - .flags = 0, - }; - VkMemoryAllocInfo msaa_mem_alloc = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, - .pNext = NULL, - .allocationSize = 0, - .memProps = 0, - .memPriority = VK_MEMORY_PRIORITY_NORMAL, - }; - - VkMemoryRequirements *msaa_mem_reqs; - size_t msaa_mem_reqs_size = sizeof(VkMemoryRequirements); - uint32_t msaa_num_allocations = 0; - size_t msaa_num_alloc_size = sizeof(msaa_num_allocations); - - err = vkCreateImage(demo->device, &msaa_image_create_info, - &demo->msaa_color.image); - assert(!err); - - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, - VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, - &msaa_num_alloc_size, &msaa_num_allocations); - assert(!err && msaa_num_alloc_size == sizeof(msaa_num_allocations)); - msaa_mem_reqs = malloc(msaa_num_allocations * sizeof(VkMemoryRequirements)); - demo->msaa_color.mem = malloc(msaa_num_allocations * sizeof(VkDeviceMemory)); - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, - VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, - &msaa_mem_reqs_size, msaa_mem_reqs); - assert(!err && msaa_mem_reqs_size == msaa_num_allocations * sizeof(VkMemoryRequirements)); - for (uint32_t j = 0; j < msaa_num_allocations; j ++) { - msaa_mem_alloc.allocationSize = msaa_mem_reqs[j].size; - - /* allocate memory */ - err = vkAllocMemory(demo->device, &msaa_mem_alloc, - &(demo->msaa_color.mem[j])); - assert(!err); - - /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, - VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, - j, demo->msaa_color.mem[j], 0); - assert(!err); - } - free(msaa_mem_reqs); - msaa_mem_reqs = NULL; - - demo->msaa_color.num_mem = msaa_num_allocations; - - demo_add_mem_refs(demo, 1, demo->msaa_color.mem); - demo_set_image_layout(demo, demo->msaa_color.image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - VkColorAttachmentViewCreateInfo msaa_color_attachment_view = { - .sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, - .pNext = NULL, - .format = demo->format, - .mipLevel = 0, - .baseArraySlice = 0, - .arraySize = 1, - }; - - msaa_color_attachment_view.image = demo->msaa_color.image; - - err = vkCreateColorAttachmentView(demo->device, - &msaa_color_attachment_view, &demo->msaa_color.view); - assert(!err); -} - -static void demo_prepare_depth(struct demo *demo) -{ - const VkFormat depth_format = VK_FORMAT_D16_UNORM; - const VkImageCreateInfo image = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = NULL, - .imageType = VK_IMAGE_TYPE_2D, - .format = depth_format, - .extent = { demo->width, demo->height, 1 }, - .mipLevels = 1, - .arraySize = 1, - .samples = 4, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_BIT, - .flags = 0, - }; - VkMemoryAllocInfo mem_alloc = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, - .pNext = NULL, - .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_DEVICE_ONLY, - .memPriority = VK_MEMORY_PRIORITY_NORMAL, - }; - VkDepthStencilViewCreateInfo view = { - .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, - .pNext = NULL, - .image = VK_NULL_HANDLE, - .mipLevel = 0, - .baseArraySlice = 0, - .arraySize = 1, - .flags = 0, - }; - - VkMemoryRequirements *mem_reqs; - size_t mem_reqs_size = sizeof(VkMemoryRequirements); - VkResult err; - uint32_t num_allocations = 0; - size_t num_alloc_size = sizeof(num_allocations); - - demo->msaa_depth.format = depth_format; - - /* create image */ - err = vkCreateImage(demo->device, &image, - &demo->msaa_depth.image); - assert(!err); - - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, - VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, - &num_alloc_size, &num_allocations); - assert(!err && num_alloc_size == sizeof(num_allocations)); - mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); - demo->msaa_depth.mem = malloc(num_allocations * sizeof(VkDeviceMemory)); - demo->msaa_depth.num_mem = num_allocations; - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, - VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, - &mem_reqs_size, mem_reqs); - assert(!err && mem_reqs_size == num_allocations * sizeof(VkMemoryRequirements)); - for (uint32_t i = 0; i < num_allocations; i ++) { - mem_alloc.allocationSize = mem_reqs[i].size; - - /* allocate memory */ - err = vkAllocMemory(demo->device, &mem_alloc, - &(demo->msaa_depth.mem[i])); - assert(!err); - - /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, - VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, - i, demo->msaa_depth.mem[i], 0); - assert(!err); - } - - demo_set_image_layout(demo, demo->msaa_depth.image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - - demo_add_mem_refs(demo, demo->msaa_depth.num_mem, demo->msaa_depth.mem); - - /* create image view */ - view.image = demo->msaa_depth.image; - err = vkCreateDepthStencilView(demo->device, &view, - &demo->msaa_depth.view); - assert(!err); -} - -static void demo_prepare_texture_image(struct demo *demo, - const uint32_t *tex_colors, - struct texture_object *tex_obj, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkFlags mem_props) -{ - const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; - const int32_t tex_width = 2; - const int32_t tex_height = 2; - VkResult err; - - tex_obj->tex_width = tex_width; - tex_obj->tex_height = tex_height; - - const VkImageCreateInfo image_create_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = NULL, - .imageType = VK_IMAGE_TYPE_2D, - .format = tex_format, - .extent = { tex_width, tex_height, 1 }, - .mipLevels = 1, - .arraySize = 1, - .samples = 1, - .tiling = tiling, - .usage = usage, - .flags = 0, - }; - VkMemoryAllocInfo mem_alloc = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, - .pNext = NULL, - .allocationSize = 0, - .memProps = mem_props, - .memPriority = VK_MEMORY_PRIORITY_NORMAL, - }; - - VkMemoryRequirements *mem_reqs; - size_t mem_reqs_size = sizeof(VkMemoryRequirements); - uint32_t num_allocations = 0; - size_t num_alloc_size = sizeof(num_allocations); - - err = vkCreateImage(demo->device, &image_create_info, - &tex_obj->image); - assert(!err); - - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, tex_obj->image, - VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, - &num_alloc_size, &num_allocations); - assert(!err && num_alloc_size == sizeof(num_allocations)); - mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); - tex_obj->mem = malloc(num_allocations * sizeof(VkDeviceMemory)); - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_IMAGE, tex_obj->image, - VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, - &mem_reqs_size, mem_reqs); - assert(!err && mem_reqs_size == num_allocations * sizeof(VkMemoryRequirements)); - for (uint32_t j = 0; j < num_allocations; j ++) { - mem_alloc.allocationSize = mem_reqs[j].size; - - /* allocate memory */ - err = vkAllocMemory(demo->device, &mem_alloc, - &(tex_obj->mem[j])); - assert(!err); - - /* bind memory */ - err = vkQueueBindObjectMemory(demo->queue, - VK_OBJECT_TYPE_IMAGE, tex_obj->image, - j, tex_obj->mem[j], 0); - assert(!err); - } - free(mem_reqs); - mem_reqs = NULL; - - tex_obj->num_mem = num_allocations; - - if (mem_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - const VkImageSubresource subres = { - .aspect = VK_IMAGE_ASPECT_COLOR, - .mipLevel = 0, - .arraySlice = 0, - }; - VkSubresourceLayout layout; - size_t layout_size = sizeof(VkSubresourceLayout); - void *data; - int32_t x, y; - - err = vkGetImageSubresourceInfo(demo->device, tex_obj->image, &subres, - VK_SUBRESOURCE_INFO_TYPE_LAYOUT, - &layout_size, &layout); - assert(!err && layout_size == sizeof(layout)); - /* Linear texture must be within a single memory object */ - assert(num_allocations == 1); - - err = vkMapMemory(demo->device, tex_obj->mem[0], 0, 0, 0, &data); - assert(!err); - - for (y = 0; y < tex_height; y++) { - uint32_t *row = (uint32_t *) ((char *) data + layout.rowPitch * y); - for (x = 0; x < tex_width; x++) - row[x] = tex_colors[(x & 1) ^ (y & 1)]; - } - - err = vkUnmapMemory(demo->device, tex_obj->mem[0]); - assert(!err); - } - - tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - demo_set_image_layout(demo, tex_obj->image, - VK_IMAGE_LAYOUT_UNDEFINED, - tex_obj->imageLayout); - /* setting the image layout does not reference the actual memory so no need to add a mem ref */ -} - -static void demo_destroy_texture_image(struct demo *demo, struct texture_object *tex_obj) -{ - /* clean up staging resources */ - for (uint32_t j = 0; j < tex_obj->num_mem; j ++) { - vkQueueBindObjectMemory(demo->queue, - VK_OBJECT_TYPE_IMAGE, tex_obj->image, j, VK_NULL_HANDLE, 0); - vkFreeMemory(demo->device, tex_obj->mem[j]); - } - - free(tex_obj->mem); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image); -} - -static void demo_prepare_textures(struct demo *demo) -{ - const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; - VkFormatProperties props; - size_t size = sizeof(props); - const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = { - { 0xffff0000, 0xff00ff00 }, - }; - VkResult err; - uint32_t i; - - err = vkGetFormatInfo(demo->device, tex_format, - VK_FORMAT_INFO_TYPE_PROPERTIES, - &size, &props); - assert(!err); - - for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { - if ((props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && !demo->use_staging_buffer) { - /* Device can texture using linear textures */ - demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], - VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); - } else if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT){ - /* Must use staging buffer to copy linear texture to optimized */ - struct texture_object staging_texture; - - memset(&staging_texture, 0, sizeof(staging_texture)); - demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, - VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); - - demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], - VK_IMAGE_TILING_OPTIMAL, - (VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), - VK_MEMORY_PROPERTY_DEVICE_ONLY); - - demo_set_image_layout(demo, staging_texture.image, - staging_texture.imageLayout, - VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL); - - demo_set_image_layout(demo, demo->textures[i].image, - demo->textures[i].imageLayout, - VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL); - - VkImageCopy copy_region = { - .srcSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, - .srcOffset = { 0, 0, 0 }, - .destSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 }, - .destOffset = { 0, 0, 0 }, - .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 }, - }; - vkCmdCopyImage(demo->cmd, - staging_texture.image, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, - demo->textures[i].image, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, - 1, ©_region); - - demo_add_mem_refs(demo, staging_texture.num_mem, staging_texture.mem); - demo_add_mem_refs(demo, demo->textures[i].num_mem, demo->textures[i].mem); - - demo_set_image_layout(demo, demo->textures[i].image, - VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, - demo->textures[i].imageLayout); - - demo_flush_init_cmd(demo); - - demo_remove_mem_refs(demo, staging_texture.num_mem, staging_texture.mem); - demo_destroy_texture_image(demo, &staging_texture); - } else { - /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */ - assert(!"No support for B8G8R8A8_UNORM as texture image format"); - } - - const VkSamplerCreateInfo sampler = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = NULL, - .magFilter = VK_TEX_FILTER_NEAREST, - .minFilter = VK_TEX_FILTER_NEAREST, - .mipMode = VK_TEX_MIPMAP_MODE_BASE, - .addressU = VK_TEX_ADDRESS_WRAP, - .addressV = VK_TEX_ADDRESS_WRAP, - .addressW = VK_TEX_ADDRESS_WRAP, - .mipLodBias = 0.0f, - .maxAnisotropy = 1, - .compareOp = VK_COMPARE_OP_NEVER, - .minLod = 0.0f, - .maxLod = 0.0f, - .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE, - }; - VkImageViewCreateInfo view = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = NULL, - .image = VK_NULL_HANDLE, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = tex_format, - .channels = { VK_CHANNEL_SWIZZLE_R, - VK_CHANNEL_SWIZZLE_G, - VK_CHANNEL_SWIZZLE_B, - VK_CHANNEL_SWIZZLE_A, }, - .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 }, - .minLod = 0.0f, - }; - - /* create sampler */ - err = vkCreateSampler(demo->device, &sampler, - &demo->textures[i].sampler); - assert(!err); - - /* create image view */ - view.image = demo->textures[i].image; - err = vkCreateImageView(demo->device, &view, - &demo->textures[i].view); - assert(!err); - } -} - -static void demo_prepare_vertices(struct demo *demo) -{ - const float vb[3][5] = { - /* position texcoord */ - { -1.0f, -1.0f, -0.6f, 0.0f, 0.0f }, - { 1.0f, -1.0f, -0.5f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.5f, 1.0f }, - }; - const VkBufferCreateInfo buf_info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = NULL, - .size = sizeof(vb), - .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - .flags = 0, - }; - VkMemoryAllocInfo mem_alloc = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, - .pNext = NULL, - .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - .memPriority = VK_MEMORY_PRIORITY_NORMAL, - }; - VkMemoryRequirements *mem_reqs; - size_t mem_reqs_size = sizeof(VkMemoryRequirements); - uint32_t num_allocations = 0; - size_t num_alloc_size = sizeof(num_allocations); - VkResult err; - void *data; - - memset(&demo->vertices, 0, sizeof(demo->vertices)); - - err = vkCreateBuffer(demo->device, &buf_info, &demo->vertices.buf); - assert(!err); - - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, - VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT, - &num_alloc_size, &num_allocations); - assert(!err && num_alloc_size == sizeof(num_allocations)); - mem_reqs = malloc(num_allocations * sizeof(VkMemoryRequirements)); - demo->vertices.mem = malloc(num_allocations * sizeof(VkDeviceMemory)); - demo->vertices.num_mem = num_allocations; - err = vkGetObjectInfo(demo->device, - VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, - VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS, - &mem_reqs_size, mem_reqs); - assert(!err && mem_reqs_size == sizeof(*mem_reqs)); - for (uint32_t i = 0; i < num_allocations; i ++) { - mem_alloc.allocationSize = mem_reqs[i].size; - - err = vkAllocMemory(demo->device, &mem_alloc, &demo->vertices.mem[i]); - assert(!err); - - err = vkMapMemory(demo->device, demo->vertices.mem[i], 0, 0, 0, &data); - assert(!err); - - memcpy(data, vb, sizeof(vb)); - - err = vkUnmapMemory(demo->device, demo->vertices.mem[i]); - assert(!err); - - err = vkQueueBindObjectMemory(demo->queue, - VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, - i, demo->vertices.mem[i], 0); - assert(!err); - } - - demo_add_mem_refs(demo, demo->vertices.num_mem, demo->vertices.mem); - - demo->vertices.vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO; - demo->vertices.vi.pNext = NULL; - demo->vertices.vi.bindingCount = 1; - demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; - demo->vertices.vi.attributeCount = 2; - demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs; - - demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID; - demo->vertices.vi_bindings[0].strideInBytes = sizeof(vb[0]); - demo->vertices.vi_bindings[0].stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX; - - demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID; - demo->vertices.vi_attrs[0].location = 0; - demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT; - demo->vertices.vi_attrs[0].offsetInBytes = 0; - - demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID; - demo->vertices.vi_attrs[1].location = 1; - demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT; - demo->vertices.vi_attrs[1].offsetInBytes = sizeof(float) * 3; -} - -static void demo_prepare_descriptor_layout(struct demo *demo) -{ - const VkDescriptorSetLayoutBinding layout_binding = { - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .count = DEMO_TEXTURE_COUNT, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = NULL, - }; - const VkDescriptorSetLayoutCreateInfo descriptor_layout = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = NULL, - .count = 1, - .pBinding = &layout_binding, - }; - VkResult err; - - err = vkCreateDescriptorSetLayout(demo->device, - &descriptor_layout, &demo->desc_layout); - assert(!err); - - const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = NULL, - .descriptorSetCount = 1, - .pSetLayouts = &demo->desc_layout, - }; - - err = vkCreatePipelineLayout(demo->device, - &pPipelineLayoutCreateInfo, - &demo->pipeline_layout); - assert(!err); -} - -static VkShader demo_prepare_shader(struct demo *demo, - VkShaderStage stage, - const void *code, - size_t size) -{ - VkShaderCreateInfo createInfo; - VkShader shader; - VkResult err; - - createInfo.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO; - createInfo.pNext = NULL; - - // Create fake SPV structure to feed GLSL - // to the driver "under the covers" - createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; - createInfo.pCode = malloc(createInfo.codeSize); - createInfo.flags = 0; - - /* try version 0 first: VkShaderStage followed by GLSL */ - ((uint32_t *) createInfo.pCode)[0] = ICD_SPV_MAGIC; - ((uint32_t *) createInfo.pCode)[1] = 0; - ((uint32_t *) createInfo.pCode)[2] = stage; - memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); - - err = vkCreateShader(demo->device, &createInfo, &shader); - if (err) { - free((void *) createInfo.pCode); - return VK_NULL_HANDLE; - } - - return shader; -} - -static VkShader demo_prepare_vs(struct demo *demo) -{ - static const char *vertShaderText = - "#version 140\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout (location = 0) in vec4 pos;\n" - "layout (location = 1) in vec2 attr;\n" - "out vec2 texcoord;\n" - "void main() {\n" - " texcoord = attr;\n" - " gl_Position = pos;\n" - "}\n"; - - return demo_prepare_shader(demo, VK_SHADER_STAGE_VERTEX, - (const void *) vertShaderText, - strlen(vertShaderText)); -} - -static VkShader demo_prepare_fs(struct demo *demo) -{ - static const char *fragShaderText = - "#version 140\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout (binding = 0) uniform sampler2D tex;\n" - "layout (location = 0) in vec2 texcoord;\n" - "void main() {\n" - " gl_FragColor = texture(tex, texcoord);\n" - "}\n"; - - return demo_prepare_shader(demo, VK_SHADER_STAGE_FRAGMENT, - (const void *) fragShaderText, - strlen(fragShaderText)); -} - -static void demo_prepare_pipeline(struct demo *demo) -{ - VkGraphicsPipelineCreateInfo pipeline; - VkPipelineVertexInputCreateInfo vi; - VkPipelineIaStateCreateInfo ia; - VkPipelineRsStateCreateInfo rs; - VkPipelineCbStateCreateInfo cb; - VkPipelineDsStateCreateInfo ds; - VkPipelineShaderStageCreateInfo vs; - VkPipelineShaderStageCreateInfo fs; - VkPipelineVpStateCreateInfo vp; - VkPipelineMsStateCreateInfo ms; - VkResult err; - - memset(&pipeline, 0, sizeof(pipeline)); - pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline.layout = demo->pipeline_layout; - - vi = demo->vertices.vi; - - memset(&ia, 0, sizeof(ia)); - ia.sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO; - ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - - memset(&rs, 0, sizeof(rs)); - rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO; - rs.fillMode = VK_FILL_MODE_SOLID; - rs.cullMode = VK_CULL_MODE_NONE; - rs.frontFace = VK_FRONT_FACE_CCW; - - memset(&cb, 0, sizeof(cb)); - cb.sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO; - VkPipelineCbAttachmentState att_state[1]; - memset(att_state, 0, sizeof(att_state)); - att_state[0].format = demo->format; - att_state[0].channelWriteMask = 0xf; - att_state[0].blendEnable = VK_FALSE; - cb.attachmentCount = 1; - cb.pAttachments = att_state; - - - memset(&vp, 0, sizeof(vp)); - vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO; - vp.viewportCount = 1; - vp.clipOrigin = VK_COORDINATE_ORIGIN_UPPER_LEFT; - - memset(&ds, 0, sizeof(ds)); - ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO; - ds.format = demo->msaa_depth.format; - ds.depthTestEnable = VK_TRUE; - ds.depthWriteEnable = VK_TRUE; - ds.depthCompareOp = VK_COMPARE_OP_LESS_EQUAL; - ds.depthBoundsEnable = VK_FALSE; - ds.back.stencilFailOp = VK_STENCIL_OP_KEEP; - ds.back.stencilPassOp = VK_STENCIL_OP_KEEP; - ds.back.stencilCompareOp = VK_COMPARE_OP_ALWAYS; - ds.stencilTestEnable = VK_FALSE; - ds.front = ds.back; - - memset(&vs, 0, sizeof(vs)); - vs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vs.shader.stage = VK_SHADER_STAGE_VERTEX; - vs.shader.shader = demo_prepare_vs(demo); - vs.shader.linkConstBufferCount = 0; - - memset(&fs, 0, sizeof(fs)); - fs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fs.shader.stage = VK_SHADER_STAGE_FRAGMENT; - fs.shader.shader = demo_prepare_fs(demo); - - memset(&ms, 0, sizeof(ms)); - ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; - ms.sampleMask = 0xffff; - ms.multisampleEnable = VK_TRUE; - ms.samples = 4; - - pipeline.pNext = (const void *) &vi; - vi.pNext = (void *) &ia; - ia.pNext = (const void *) &rs; - rs.pNext = (const void *) &cb; - cb.pNext = (const void *) &ms; - ms.pNext = (const void *) &vp; - vp.pNext = (const void *) &ds; - ds.pNext = (const void *) &vs; - vs.pNext = (const void *) &fs; - - err = vkCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); - assert(!err); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, vs.shader.shader); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, fs.shader.shader); -} - -static void demo_prepare_dynamic_states(struct demo *demo) -{ - VkDynamicVpStateCreateInfo viewport_create; - VkDynamicRsStateCreateInfo raster; - VkDynamicCbStateCreateInfo color_blend; - VkDynamicDsStateCreateInfo depth_stencil; - VkResult err; - - memset(&viewport_create, 0, sizeof(viewport_create)); - viewport_create.sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO; - viewport_create.viewportAndScissorCount = 1; - VkViewport viewport; - memset(&viewport, 0, sizeof(viewport)); - viewport.height = (float) demo->height; - viewport.width = (float) demo->width; - viewport.minDepth = (float) 0.0f; - viewport.maxDepth = (float) 1.0f; - viewport_create.pViewports = &viewport; - VkRect scissor; - memset(&scissor, 0, sizeof(scissor)); - scissor.extent.width = demo->width; - scissor.extent.height = demo->height; - scissor.offset.x = 0; - scissor.offset.y = 0; - viewport_create.pScissors = &scissor; - - memset(&raster, 0, sizeof(raster)); - raster.sType = VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO; - raster.pointSize = 1.0; - raster.lineWidth = 1.0; - - memset(&color_blend, 0, sizeof(color_blend)); - color_blend.sType = VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO; - color_blend.blendConst[0] = 1.0f; - color_blend.blendConst[1] = 1.0f; - color_blend.blendConst[2] = 1.0f; - color_blend.blendConst[3] = 1.0f; - - memset(&depth_stencil, 0, sizeof(depth_stencil)); - depth_stencil.sType = VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO; - depth_stencil.minDepth = 0.0f; - depth_stencil.maxDepth = 1.0f; - depth_stencil.stencilBackRef = 0; - depth_stencil.stencilFrontRef = 0; - depth_stencil.stencilReadMask = 0xff; - depth_stencil.stencilWriteMask = 0xff; - - err = vkCreateDynamicViewportState(demo->device, &viewport_create, &demo->viewport); - assert(!err); - - err = vkCreateDynamicRasterState(demo->device, &raster, &demo->raster); - assert(!err); - - err = vkCreateDynamicColorBlendState(demo->device, - &color_blend, &demo->color_blend); - assert(!err); - - err = vkCreateDynamicDepthStencilState(demo->device, - &depth_stencil, &demo->depth_stencil); - assert(!err); -} - -static void demo_prepare_descriptor_pool(struct demo *demo) -{ - const VkDescriptorTypeCount type_count = { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .count = DEMO_TEXTURE_COUNT, - }; - const VkDescriptorPoolCreateInfo descriptor_pool = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .pNext = NULL, - .count = 1, - .pTypeCount = &type_count, - }; - VkResult err; - - err = vkCreateDescriptorPool(demo->device, - VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, - &descriptor_pool, &demo->desc_pool); - assert(!err); -} - -static void demo_prepare_descriptor_set(struct demo *demo) -{ - VkImageViewAttachInfo view_info[DEMO_TEXTURE_COUNT]; - VkSamplerImageViewInfo combined_info[DEMO_TEXTURE_COUNT]; - VkUpdateSamplerTextures update; - const void *update_array[1] = { &update }; - VkResult err; - uint32_t count; - uint32_t i; - - for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { - view_info[i].sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO; - view_info[i].pNext = NULL; - view_info[i].view = demo->textures[i].view, - view_info[i].layout = VK_IMAGE_LAYOUT_GENERAL; - - combined_info[i].sampler = demo->textures[i].sampler; - combined_info[i].pImageView = &view_info[i]; - } - - memset(&update, 0, sizeof(update)); - update.sType = VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES; - update.count = DEMO_TEXTURE_COUNT; - update.pSamplerImageViews = combined_info; - - err = vkAllocDescriptorSets(demo->device, demo->desc_pool, - VK_DESCRIPTOR_SET_USAGE_STATIC, - 1, &demo->desc_layout, - &demo->desc_set, &count); - assert(!err && count == 1); - - vkBeginDescriptorPoolUpdate(demo->device, - VK_DESCRIPTOR_UPDATE_MODE_FASTEST); - - vkClearDescriptorSets(demo->device, demo->desc_pool, 1, &demo->desc_set); - vkUpdateDescriptors(demo->device, demo->desc_set, 1, update_array); - - vkEndDescriptorPoolUpdate(demo->device, demo->cmd); -} - -static void demo_prepare(struct demo *demo) -{ - const VkCmdBufferCreateInfo cmd = { - .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, - .pNext = NULL, - .queueNodeIndex = demo->graphics_queue_node_index, - .flags = 0, - }; - VkResult err; - - demo_prepare_buffers(demo); - demo_prepare_depth(demo); - demo_prepare_textures(demo); - demo_prepare_vertices(demo); - demo_prepare_descriptor_layout(demo); - demo_prepare_pipeline(demo); - demo_prepare_dynamic_states(demo); - - err = vkCreateCommandBuffer(demo->device, &cmd, &demo->cmd); - assert(!err); - - demo_prepare_descriptor_pool(demo); - demo_prepare_descriptor_set(demo); - demo->prepared = true; -} - -#ifdef _WIN32 -static void demo_run(struct demo *demo) -{ - if (!demo->prepared) - return; - demo_draw(demo); -} - -// On MS-Windows, make this a global, so it's available to WndProc() -struct demo demo; - -// MS-Windows event handling function: -LRESULT CALLBACK WndProc(HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - char tmp_str[] = APP_LONG_NAME; - - switch(uMsg) - { - case WM_CREATE: - return 0; - case WM_CLOSE: - demo.prepared = false; - DestroyWindow(hWnd); - PostQuitMessage(0); - return 0; - case WM_PAINT: - demo_run(&demo); - return 0; - default: - break; - } - return (DefWindowProc(hWnd, uMsg, wParam, lParam)); -} - -static void demo_create_window(struct demo *demo) -{ - WNDCLASSEX win_class; - - // Initialize the window class structure: - win_class.cbSize = sizeof(WNDCLASSEX); - win_class.style = CS_HREDRAW | CS_VREDRAW; - win_class.lpfnWndProc = WndProc; - win_class.cbClsExtra = 0; - win_class.cbWndExtra = 0; - win_class.hInstance = demo->connection; // hInstance - win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); - win_class.hCursor = LoadCursor(NULL, IDC_ARROW); - win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - win_class.lpszMenuName = NULL; - win_class.lpszClassName = demo->name; - win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); - // Register window class: - if (!RegisterClassEx(&win_class)) { - // It didn't work, so try to give a useful error: - printf("Unexpected error trying to start the application!\n"); - fflush(stdout); - WAIT_FOR_CONSOLE_DESTROY; - exit(1); - } - // Create window with the registered class: - demo->window = CreateWindowEx(0, - demo->name, // class name - demo->name, // app name - WS_OVERLAPPEDWINDOW | // window style - WS_VISIBLE | - WS_SYSMENU, - 100,100, // x/y coords - demo->width, // width - demo->height, // height - NULL, // handle to parent - NULL, // handle to menu - demo->connection, // hInstance - NULL); // no extra parameters - if (!demo->window) { - // It didn't work, so try to give a useful error: - printf("Cannot create a window in which to draw!\n"); - fflush(stdout); - WAIT_FOR_CONSOLE_DESTROY; - exit(1); - } -} -#else // _WIN32 - -static void demo_handle_event(struct demo *demo, - const xcb_generic_event_t *event) -{ - switch (event->response_type & 0x7f) { - case XCB_EXPOSE: - demo_draw(demo); - break; - case XCB_CLIENT_MESSAGE: - if((*(xcb_client_message_event_t*)event).data.data32[0] == - (*demo->atom_wm_delete_window).atom) { - demo->quit = true; - } - break; - case XCB_KEY_RELEASE: - { - const xcb_key_release_event_t *key = - (const xcb_key_release_event_t *) event; - - if (key->detail == 0x9) - demo->quit = true; - } - break; - case XCB_DESTROY_NOTIFY: - demo->quit = true; - break; - default: - break; - } -} - -static void demo_run(struct demo *demo) -{ - xcb_flush(demo->connection); - - while (!demo->quit) { - xcb_generic_event_t *event; - - event = xcb_wait_for_event(demo->connection); - if (event) { - demo_handle_event(demo, event); - free(event); - } - } -} - -static void demo_create_window(struct demo *demo) -{ - uint32_t value_mask, value_list[32]; - - demo->window = xcb_generate_id(demo->connection); - - value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - value_list[0] = demo->screen->black_pixel; - value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY; - - xcb_create_window(demo->connection, - XCB_COPY_FROM_PARENT, - demo->window, demo->screen->root, - 0, 0, demo->width, demo->height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - demo->screen->root_visual, - value_mask, value_list); - - /* Magic code that will send notification when window is destroyed */ - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, - "WM_PROTOCOLS"); - xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0); - - xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); - demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); - - xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, - demo->window, (*reply).atom, 4, 32, 1, - &(*demo->atom_wm_delete_window).atom); - free(reply); - - xcb_map_window(demo->connection, demo->window); -} -#endif // _WIN32 - -static void demo_init_vk(struct demo *demo) -{ - VkResult err; - // Extensions to enable - const char *ext_names[] = { - "VK_WSI_LunarG", - }; - size_t extSize = sizeof(uint32_t); - uint32_t extCount = 0; - err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount); - assert(!err); - - VkExtensionProperties extProp; - extSize = sizeof(VkExtensionProperties); - bool32_t extFound = 0; - for (uint32_t i = 0; i < extCount; i++) { - err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &extSize, &extProp); - if (!strcmp(ext_names[0], extProp.extName)) - extFound = 1; - } - if (!extFound) { - ERR_EXIT("vkGetGlobalExtensionInfo failed to find the " - "\"VK_WSI_LunarG\" extension.\n\nDo you have a compatible " - "Vulkan installable client driver (ICD) installed?\nPlease " - "look at the Getting Started guide for additional " - "information.\n", - "vkCreateInstance Failure"); - } - const VkApplicationInfo app = { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pNext = NULL, - .pAppName = APP_SHORT_NAME, - .appVersion = 0, - .pEngineName = APP_SHORT_NAME, - .engineVersion = 0, - .apiVersion = VK_API_VERSION, - }; - const VkInstanceCreateInfo inst_info = { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pNext = NULL, - .pAppInfo = &app, - .pAllocCb = NULL, - .extensionCount = 1, - .ppEnabledExtensionNames = ext_names, - }; - const VkDeviceQueueCreateInfo queue = { - .queueNodeIndex = 0, - .queueCount = 1, - }; - const VkDeviceCreateInfo device = { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = NULL, - .queueRecordCount = 1, - .pRequestedQueues = &queue, - .extensionCount = 1, - .ppEnabledExtensionNames = ext_names, - .flags = VK_DEVICE_CREATE_VALIDATION_BIT, - }; - uint32_t gpu_count; - uint32_t i; - size_t data_size; - uint32_t queue_count; - - err = vkCreateInstance(&inst_info, &demo->inst); - if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { - ERR_EXIT("Cannot find a compatible Vulkan installable client driver " - "(ICD).\n\nPlease look at the Getting Started guide for " - "additional information.\n", - "vkCreateInstance Failure"); - } else if (err) { - ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan " - "installable client driver (ICD) installed?\nPlease look at " - "the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); - } - - gpu_count = 1; - err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, &demo->gpu); - assert(!err && gpu_count == 1); - - err = vkCreateDevice(demo->gpu, &device, &demo->device); - assert(!err); - - err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, - &data_size, NULL); - assert(!err); - - demo->gpu_props = (VkPhysicalDeviceProperties *) malloc(data_size); - err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, - &data_size, demo->gpu_props); - assert(!err); - - err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES, - &data_size, NULL); - assert(!err); - - demo->queue_props = (VkPhysicalDeviceQueueProperties *) malloc(data_size); - err = vkGetPhysicalDeviceInfo(demo->gpu, VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES, - &data_size, demo->queue_props); - assert(!err); - queue_count = (uint32_t) (data_size / sizeof(VkPhysicalDeviceQueueProperties)); - assert(queue_count >= 1); - - for (i = 0; i < queue_count; i++) { - if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) - break; - if (demo->queue_props[i].queueFlags & VK_QUEUE_MEMMGR_BIT) - break; - } - assert(i < queue_count); - demo->graphics_queue_node_index = i; - - err = vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, - 0, &demo->queue); - assert(!err); -} - -static void demo_init_connection(struct demo *demo) -{ -#ifndef _WIN32 - const xcb_setup_t *setup; - xcb_screen_iterator_t iter; - int scr; - - demo->connection = xcb_connect(NULL, &scr); - if (demo->connection == NULL) { - printf("Cannot find a compatible Vulkan installable client driver " - "(ICD).\nExiting ...\n"); - fflush(stdout); - exit(1); - } - - setup = xcb_get_setup(demo->connection); - iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) - xcb_screen_next(&iter); - - demo->screen = iter.data; -#endif // _WIN32 -} - -#ifdef _WIN32 -static void demo_init(struct demo *demo, HINSTANCE hInstance, LPSTR pCmdLine) -#else // _WIN32 -static void demo_init(struct demo *demo, const int argc, const char *argv[]) -#endif // _WIN32 -{ - bool argv_error = false; - - memset(demo, 0, sizeof(*demo)); - -#ifdef _WIN32 - demo->connection = hInstance; - strncpy(demo->name, APP_SHORT_NAME, APP_NAME_STR_LEN); - - if (strncmp(pCmdLine, "--use_staging", strlen("--use_staging")) == 0) - demo->use_staging_buffer = true; - else if (strlen(pCmdLine) != 0) { - fprintf(stderr, "Do not recognize argument \"%s\".\n", pCmdLine); - argv_error = true; - } -#else // _WIN32 - for (int i = 0; i < argc; i++) { - if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0) - demo->use_staging_buffer = true; - } -#endif // _WIN32 - if (argv_error) { - fprintf(stderr, "Usage:\n %s [--use_staging]\n", APP_SHORT_NAME); - fflush(stderr); - WAIT_FOR_CONSOLE_DESTROY; - exit(1); - } - - demo_init_connection(demo); - demo_init_vk(demo); - - demo->width = 300; - demo->height = 300; - demo->format = VK_FORMAT_B8G8R8A8_UNORM; -} - -static void demo_cleanup(struct demo *demo) -{ - uint32_t i, j; - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_SET, demo->desc_set); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_POOL, demo->desc_pool); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_COMMAND_BUFFER, demo->cmd); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_VP_STATE, demo->viewport); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_RS_STATE, demo->raster); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_CB_STATE, demo->color_blend); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DYNAMIC_DS_STATE, demo->depth_stencil); - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_PIPELINE, demo->pipeline); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, demo->pipeline_layout); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, demo->desc_layout); - - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, 0, VK_NULL_HANDLE, 0); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf); - demo_remove_mem_refs(demo, demo->vertices.num_mem, demo->vertices.mem); - for (j = 0; j < demo->vertices.num_mem; j++) - vkFreeMemory(demo->device, demo->vertices.mem[j]); - - for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { - vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE_VIEW, demo->textures[i].view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image, 0, VK_NULL_HANDLE, 0); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->textures[i].image); - demo_remove_mem_refs(demo, demo->textures[i].num_mem, demo->textures[i].mem); - for (j = 0; j < demo->textures[i].num_mem; j++) - vkFreeMemory(demo->device, demo->textures[i].mem[j]); - free(demo->textures[i].mem); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SAMPLER, demo->textures[i].sampler); - } - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW, demo->msaa_color.view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image, 0, VK_NULL_HANDLE, 0); - demo_remove_mem_refs(demo, demo->msaa_color.num_mem, demo->msaa_color.mem); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->msaa_color.image); - for (j = 0; j < demo->msaa_color.num_mem; j++) { - vkFreeMemory(demo->device, demo->msaa_color.mem[j]); - } - - vkDestroyObject(demo->device, VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW, demo->msaa_depth.view); - vkQueueBindObjectMemory(demo->queue, VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image, 0, VK_NULL_HANDLE, 0); - demo_remove_mem_refs(demo, demo->msaa_depth.num_mem, demo->msaa_depth.mem); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_IMAGE, demo->msaa_depth.image); - for (j = 0; j < demo->msaa_depth.num_mem; j++) { - vkFreeMemory(demo->device, demo->msaa_depth.mem[j]); - } - - for (i = 0; i < DEMO_BUFFER_COUNT; i++) { - demo_remove_mem_refs(demo, 1, &demo->buffers[i].mem); - } - vkDestroySwapChainWSI(demo->swap_chain); - - vkDestroyDevice(demo->device); - vkDestroyInstance(demo->inst); - -#ifndef _WIN32 - xcb_destroy_window(demo->connection, demo->window); - xcb_disconnect(demo->connection); -#endif // _WIN32 -} - -#ifdef _WIN32 -// The following function was copied from the Vulkan loader: -char *get_registry_string(const HKEY hive, - const LPCTSTR sub_key, - const char *value) -{ - DWORD access_flags = KEY_QUERY_VALUE; - DWORD value_type; - HKEY key; - VkResult rtn_value; - char *rtn_str = NULL; - size_t rtn_len = 0; - size_t allocated_len = 0; - - rtn_value = RegOpenKeyEx(hive, sub_key, 0, access_flags, &key); - if (rtn_value != ERROR_SUCCESS) { - // We didn't find the key. Try the 32-bit hive (where we've seen the - // key end up on some people's systems): - access_flags |= KEY_WOW64_32KEY; - rtn_value = RegOpenKeyEx(hive, sub_key, 0, access_flags, &key); - if (rtn_value != ERROR_SUCCESS) { - // We still couldn't find the key, so give up: - return NULL; - } - } - - rtn_value = RegQueryValueEx(key, value, NULL, &value_type, - (PVOID) rtn_str, (LPDWORD) &rtn_len); - if (rtn_value == ERROR_SUCCESS) { - // If we get to here, we found the key, and need to allocate memory - // large enough for rtn_str, and query again: - allocated_len = rtn_len + 4; - rtn_str = malloc(allocated_len); - rtn_value = RegQueryValueEx(key, value, NULL, &value_type, - (PVOID) rtn_str, (LPDWORD) &rtn_len); - if (rtn_value == ERROR_SUCCESS) { - // We added 4 extra bytes to rtn_str, so that we can ensure that - // the string is NULL-terminated (albeit, in a brute-force manner): - rtn_str[allocated_len-1] = '\0'; - } else { - // This should never occur, but in case it does, clean up: - free(rtn_str); - rtn_str = NULL; - } - } // else - shouldn't happen, but if it does, return rtn_str, which is NULL - - // Close the registry key that was opened: - RegCloseKey(key); - - return rtn_str; -} - - -// The following function was copied from the Vulkan loader: -static char *get_registry_and_env(const char *env_var, - const char *registry_value) -{ - char *env_str = getenv(env_var); - size_t env_len = (env_str == NULL) ? 0 : strlen(env_str); - char *registry_str = NULL; - DWORD registry_len = 0; - char *rtn_str = NULL; - size_t rtn_len; - - registry_str = get_registry_string(HKEY_LOCAL_MACHINE, - "Software\\Vulkan", - registry_value); - registry_len = (registry_str) ? (DWORD) strlen(registry_str) : 0; - - rtn_len = env_len + registry_len + 1; - if (rtn_len <= 2) { - // We found neither the desired registry value, nor the environment - // variable; return NULL: - return NULL; - } else { - // We found something, and so we need to allocate memory for the string - // to return: - rtn_str = malloc(rtn_len); - } - - if (registry_len == 0) { - // We didn't find the desired registry value, and so we must have found - // only the environment variable: - _snprintf(rtn_str, rtn_len, "%s", env_str); - } else if (env_str != NULL) { - // We found both the desired registry value and the environment - // variable, so concatenate them both: - _snprintf(rtn_str, rtn_len, "%s;%s", registry_str, env_str); - } else { - // We must have only found the desired registry value: - _snprintf(rtn_str, rtn_len, "%s", registry_str); - } - - if (registry_str) { - free(registry_str); - } - - return(rtn_str); -} - -// Create a console window with a large scrollback size to which to send stdout. -// Returns true if console window was successfully created, false otherwise. -bool SetStdOutToNewConsole() -{ - // don't do anything if we already have a console - if (GetStdHandle(STD_OUTPUT_HANDLE)) - return false; - - // allocate a console for this app - AllocConsole(); - - // redirect unbuffered STDOUT to the console - HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); - FILE *fp = _fdopen( fileDescriptor, "w" ); - *stdout = *fp; - setvbuf( stdout, NULL, _IONBF, 0 ); - - // make the console window bigger - CONSOLE_SCREEN_BUFFER_INFO csbi; - SMALL_RECT r; - COORD bufferSize; - if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) - return false; - bufferSize.X = csbi.dwSize.X; - bufferSize.Y = 1000; - if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) - return false; - r.Left = r.Top = 0; - r.Right = csbi.dwSize.X-1; - r.Bottom = 60; - if (!SetConsoleWindowInfo(consoleHandle, true, &r)) - return false; - - // change the console window title - if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) - return false; - - return true; -} - -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR pCmdLine, - int nCmdShow) -{ - MSG msg; // message - bool done; // flag saying when app is complete - char *layers_enabled = get_registry_and_env(LAYER_NAMES_ENV, - LAYER_NAMES_REGISTRY_VALUE); - - if (layers_enabled != NULL) { - consoleCreated = SetStdOutToNewConsole(); - free(layers_enabled); - } - - demo_init(&demo, hInstance, pCmdLine); - demo_create_window(&demo); - - demo_prepare(&demo); - - done = false; //initialize loop condition variable - /* main message loop*/ - while(!done) - { - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - if (msg.message == WM_QUIT) //check for a quit message - { - done = true; //if found, quit app - } - else - { - /* Translate and dispatch to event queue*/ - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - demo_cleanup(&demo); - - if (consoleCreated) { - printf("\nPlease close this window when you are finished looking at " - "the console output.\n"); - fflush(stdout); - WAIT_FOR_CONSOLE_DESTROY; - } - - return (int) msg.wParam; -} -#else // _WIN32 -int main(const int argc, const char *argv[]) -{ - struct demo demo; - - demo_init(&demo, argc, argv); - demo_create_window(&demo); - - demo_prepare(&demo); - demo_run(&demo); - - demo_cleanup(&demo); - - return 0; -} -#endif // _WIN32 -- cgit v1.2.3