diff --git a/CMakeLists.txt b/CMakeLists.txt index 079a8f222c..e6f573c77f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,9 @@ option(SIMULATOR "Set to ON when targeting an x86 simulator of an ARM platform" # :: Options option(USE_FFMPEG "Build with FFMPEG support" ${USE_FFMPEG}) option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG}) +option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_LIBZIP}) option(USE_WAYLAND_WSI "Set to ON to require Wayland support for Vulkan" ${USE_WAYLAND_WSI}) +option(USE_ADDRESS_SANITIZER "Use Clang memory sanitizer" ${USE_ADDRESS_SANITIZER}) if(UNIX AND NOT (APPLE OR ANDROID) AND VULKAN) add_definitions(-DVK_USE_PLATFORM_XLIB_KHR) @@ -214,6 +216,13 @@ if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-uninitialized") endif() + if(USE_ADDRESS_SANITIZER) + message("Address sanitizer enabled (DEBUG only)") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -fsanitize=address") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address") + add_definitions(-DUSE_ADDRESS_SANITIZER) + endif() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -D_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -D_NDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -D_NDEBUG") @@ -538,7 +547,7 @@ endif() find_package(LibZip) -if(LIBZIP_FOUND) +if(LIBZIP_FOUND AND USE_SYSTEM_LIBZIP) add_definitions(-DSHARED_LIBZIP) else() add_library(libzip STATIC @@ -724,6 +733,8 @@ elseif(USING_QT_UI) ${QT_UI_GEN} Qt/QtMain.cpp Qt/QtMain.h + Qt/QtHost.cpp + Qt/QtHost.h Qt/mainwindow.cpp Qt/mainwindow.h Qt/Debugger/ctrldisasmview.cpp @@ -768,7 +779,9 @@ elseif(TARGET SDL2::SDL2) set(nativeExtra ${nativeExtra} SDL/SDLJoystick.h SDL/SDLJoystick.cpp - SDL/SDLMain.cpp) + SDL/SDLMain.cpp + SDL/SDLGLGraphicsContext.cpp + SDL/SDLVulkanGraphicsContext.cpp) set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) if(APPLE) set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm) @@ -830,7 +843,14 @@ if(ANDROID) set(nativeExtra ${nativeExtra} ${NativeAppSource}) endif() -set(THIN3D_PLATFORMS ext/native/thin3d/thin3d_gl.cpp) +set(THIN3D_PLATFORMS ext/native/thin3d/thin3d_gl.cpp + ext/native/thin3d/GLRenderManager.cpp + ext/native/thin3d/GLRenderManager.h + ext/native/thin3d/GLQueueRunner.cpp + ext/native/thin3d/GLQueueRunner.h + ext/native/thin3d/DataFormatGL.cpp + ext/native/thin3d/DataFormatGL.h) + set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} ext/native/thin3d/thin3d_vulkan.cpp ext/native/thin3d/VulkanRenderManager.cpp @@ -887,8 +907,6 @@ add_library(native STATIC ext/native/file/vfs.h ext/native/file/zip_read.cpp ext/native/file/zip_read.h - ext/native/gfx/GLStateCache.cpp - ext/native/gfx/GLStateCache.h ext/native/gfx/gl_common.h ext/native/gfx/gl_debug_log.cpp ext/native/gfx/gl_debug_log.h @@ -964,6 +982,7 @@ add_library(native STATIC ext/native/profiler/profiler.h ext/native/thin3d/thin3d.cpp ext/native/thin3d/thin3d.h + ext/native/thin3d/thin3d_create.h ${THIN3D_PLATFORMS} ext/native/thread/executor.cpp ext/native/thread/executor.h diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index abf9747601..3a18a308a2 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -327,9 +327,7 @@ void ARM64XEmitter::FlushIcacheSection(u8* start, u8* end) // Header file says this is equivalent to: sys_icache_invalidate(start, end - start); sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start); #elif PPSSPP_PLATFORM(WINDOWS) -#if !PPSSPP_PLATFORM(UWP) // Not available on UWP, which is very bad! FlushInstructionCache(GetCurrentProcess(), start, end - start); -#endif #elif PPSSPP_ARCH(ARM64) // Code from Dolphin, contributed by the Mono project. diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 1321bf28be..8626cdc434 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -633,9 +633,7 @@ void ARMXEmitter::FlushIcacheSection(u8 *start, u8 *end) // Header file says this is equivalent to: sys_icache_invalidate(start, end - start); sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start); #elif PPSSPP_PLATFORM(WINDOWS) -#if !PPSSPP_PLATFORM(UWP) // Not available on UWP, which is very bad! FlushInstructionCache(GetCurrentProcess(), start, end - start); -#endif #elif PPSSPP_ARCH(ARM) #if defined(__clang__) || defined(__ANDROID__) diff --git a/Common/CommonWindows.h b/Common/CommonWindows.h index 255cd441db..bacd41cb5f 100644 --- a/Common/CommonWindows.h +++ b/Common/CommonWindows.h @@ -14,4 +14,5 @@ #undef min #undef max -#endif \ No newline at end of file +#undef DrawText +#endif diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index 247163251b..1a9629f35b 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -241,10 +241,9 @@ bool CreateDir(const std::string &path) bool CreateFullPath(const std::string &fullPath) { int panicCounter = 100; - DEBUG_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); + VERBOSE_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); - if (File::Exists(fullPath)) - { + if (File::Exists(fullPath)) { DEBUG_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); return true; } diff --git a/Common/GraphicsContext.h b/Common/GraphicsContext.h index c8495b04be..5dfec7f6d9 100644 --- a/Common/GraphicsContext.h +++ b/Common/GraphicsContext.h @@ -10,6 +10,9 @@ class GraphicsContext { public: virtual ~GraphicsContext() {} + virtual bool InitFromRenderThread(std::string *errorMessage) { return true; } + virtual void ShutdownFromRenderThread() {} + virtual void Shutdown() = 0; virtual void SwapInterval(int interval) = 0; @@ -25,6 +28,12 @@ public: // Needs casting to the appropriate type, unfortunately. Should find a better solution.. virtual void *GetAPIContext() { return nullptr; } + // Called from the render thread from threaded backends. + virtual void ThreadStart() {} + virtual bool ThreadFrame() { return true; } + virtual void ThreadEnd() {} + virtual void StopThread() {} + virtual Draw::DrawContext *GetDrawContext() = 0; }; diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 18151d0b34..d550d5aaab 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -102,7 +102,7 @@ void MemArena::ReleaseView(void* view, size_t size) { u8* MemArena::Find4GBBase() { // Now, create views in high memory where there's plenty of space. -#if PPSSPP_ARCH(64BIT) +#if PPSSPP_ARCH(64BIT) && !defined(USE_ADDRESS_SANITIZER) // Very precarious - mmap cannot return an error when trying to map already used pages. // This makes the Windows approach above unusable on Linux, so we will simply pray... return reinterpret_cast(0x2300000000ULL); diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 6f3cfb5d55..77fa7ed392 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -547,7 +547,7 @@ VkResult VulkanContext::CreateDevice() { return VK_ERROR_INITIALIZATION_FAILED; } - VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; + VkDeviceQueueCreateInfo queue_info{ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; float queue_priorities[1] = { 1.0f }; queue_info.queueCount = 1; queue_info.pQueuePriorities = queue_priorities; @@ -563,7 +563,7 @@ VkResult VulkanContext::CreateDevice() { deviceExtensionsLookup_.DEDICATED_ALLOCATION = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - VkDeviceCreateInfo device_info { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; + VkDeviceCreateInfo device_info{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; device_info.queueCreateInfoCount = 1; device_info.pQueueCreateInfos = &queue_info; device_info.enabledLayerCount = (uint32_t)device_layer_names_.size(); @@ -579,6 +579,7 @@ VkResult VulkanContext::CreateDevice() { VulkanLoadDeviceFunctions(device_); } ILOG("Device created.\n"); + VulkanSetAvailable(true); return res; } @@ -922,29 +923,21 @@ VkFence VulkanContext::CreateFence(bool presignalled) { return fence; } -void VulkanContext::DestroyDevice() { - ILOG("VulkanContext::DestroyDevice (performing deletes)"); - // If there happen to be any pending deletes, now is a good time. +void VulkanContext::PerformPendingDeletes() { for (int i = 0; i < ARRAY_SIZE(frame_); i++) { frame_[i].deleteList.PerformDeletes(device_); } Delete().PerformDeletes(device_); +} + +void VulkanContext::DestroyDevice() { + ILOG("VulkanContext::DestroyDevice (performing deletes)"); + PerformPendingDeletes(); vkDestroyDevice(device_, nullptr); device_ = nullptr; } -VkPipelineCache VulkanContext::CreatePipelineCache() { - VkPipelineCache cache; - VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; - pc.pInitialData = nullptr; - pc.initialDataSize = 0; - pc.flags = 0; - VkResult res = vkCreatePipelineCache(device_, &pc, nullptr, &cache); - assert(VK_SUCCESS == res); - return cache; -} - bool VulkanContext::CreateShaderModule(const std::vector &spirv, VkShaderModule *shaderModule) { VkShaderModuleCreateInfo sm{ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; sm.pCode = spirv.data(); @@ -962,6 +955,24 @@ void TransitionImageLayout2(VkCommandBuffer cmd, VkImage image, int baseMip, int VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask) { +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { + // Hack to disable transaction elimination on ARM Mali. + if (oldImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || oldImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + oldImageLayout = VK_IMAGE_LAYOUT_GENERAL; + if (newImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || newImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + newImageLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + if (aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) { + // Hack to disable transaction elimination on ARM Mali. + if (oldImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || oldImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + oldImageLayout = VK_IMAGE_LAYOUT_GENERAL; + if (newImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + newImageLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif VkImageMemoryBarrier image_memory_barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; image_memory_barrier.srcAccessMask = srcAccessMask; image_memory_barrier.dstAccessMask = dstAccessMask; @@ -1090,22 +1101,22 @@ const char *VulkanResultToString(VkResult res) { } void VulkanDeleteList::Take(VulkanDeleteList &del) { - assert(cmdPools_.size() == 0); - assert(descPools_.size() == 0); - assert(modules_.size() == 0); - assert(buffers_.size() == 0); - assert(bufferViews_.size() == 0); - assert(images_.size() == 0); - assert(imageViews_.size() == 0); - assert(deviceMemory_.size() == 0); - assert(samplers_.size() == 0); - assert(pipelines_.size() == 0); - assert(pipelineCaches_.size() == 0); - assert(renderPasses_.size() == 0); - assert(framebuffers_.size() == 0); - assert(pipelineLayouts_.size() == 0); - assert(descSetLayouts_.size() == 0); - assert(callbacks_.size() == 0); + assert(cmdPools_.empty()); + assert(descPools_.empty()); + assert(modules_.empty()); + assert(buffers_.empty()); + assert(bufferViews_.empty()); + assert(images_.empty()); + assert(imageViews_.empty()); + assert(deviceMemory_.empty()); + assert(samplers_.empty()); + assert(pipelines_.empty()); + assert(pipelineCaches_.empty()); + assert(renderPasses_.empty()); + assert(framebuffers_.empty()); + assert(pipelineLayouts_.empty()); + assert(descSetLayouts_.empty()); + assert(callbacks_.empty()); cmdPools_ = std::move(del.cmdPools_); descPools_ = std::move(del.descPools_); modules_ = std::move(del.modules_); diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 6b441d1ffa..6466f7b390 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -8,9 +8,6 @@ #include "base/logging.h" #include "Common/Vulkan/VulkanLoader.h" -// Amount of time, in nanoseconds, to wait for a command buffer to complete -#define FENCE_TIMEOUT 10000000000 - enum { VULKAN_FLAG_VALIDATE = 1, VULKAN_FLAG_PRESENT_MAILBOX = 2, @@ -109,6 +106,12 @@ struct VulkanDeviceExtensions { bool DEDICATED_ALLOCATION; }; +// Useful for debugging on ARM Mali. This eliminates transaction elimination +// which can cause artifacts if you get barriers wrong (or if there are driver bugs). +// Cost is reduced performance on some GPU architectures. +// #define VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR +// #define VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + // VulkanContext manages the device and swapchain, and deferred deletion of objects. class VulkanContext { public: @@ -129,15 +132,14 @@ public: bool EnableDeviceExtension(const char *extension); VkResult CreateDevice(); - const std::string &InitError() { return init_error_; } + const std::string &InitError() const { return init_error_; } - VkDevice GetDevice() { return device_; } - VkInstance GetInstance() { return instance_; } + VkDevice GetDevice() const { return device_; } + VkInstance GetInstance() const { return instance_; } + uint32_t GetFlags() const { return flags_; } VulkanDeleteList &Delete() { return globalDeleteList_; } - VkPipelineCache CreatePipelineCache(); - // The parameters are whatever the chosen window system wants. void InitSurface(WindowSystem winsys, void *data1, void *data2, int width = -1, int height = -1); void ReinitSurface(int width = -1, int height = -1); @@ -148,9 +150,9 @@ public: // Also destroys the surface. void DestroyObjects(); - void DestroyDevice(); + void PerformPendingDeletes(); void WaitUntilQueueIdle(); // Utility functions for shorter code diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 143ad16332..4e8b841517 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -2,216 +2,18 @@ #include "Common/Vulkan/VulkanMemory.h" #include "Common/Log.h" -VkResult VulkanTexture::Create(int w, int h, VkFormat format) { - tex_width = w; - tex_height = h; - format_ = format; - - VkFormatProperties formatProps; - vkGetPhysicalDeviceFormatProperties(vulkan_->GetPhysicalDevice(), format, &formatProps); - return VK_SUCCESS; -} - -void VulkanTexture::CreateMappableImage() { - // If we already have a mappableImage, forget it. - if (mappableImage) { - vulkan_->Delete().QueueDeleteImage(mappableImage); - } - if (mappableMemory) { - vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory); - } - - VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; - image_create_info.imageType = VK_IMAGE_TYPE_2D; - image_create_info.format = format_; - image_create_info.extent.width = tex_width; - image_create_info.extent.height = tex_height; - image_create_info.extent.depth = 1; - image_create_info.mipLevels = 1; - image_create_info.arrayLayers = 1; - image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; - image_create_info.tiling = VK_IMAGE_TILING_LINEAR; - image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - image_create_info.queueFamilyIndexCount = 0; - image_create_info.pQueueFamilyIndices = NULL; - image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - image_create_info.flags = 0; - image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - - VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - mem_alloc.allocationSize = 0; - mem_alloc.memoryTypeIndex = 0; - - // Create a mappable image. It will be the texture if linear images are ok to be textures - // or it will be the staging image if they are not. - VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &mappableImage); - assert(res == VK_SUCCESS); - - vkGetImageMemoryRequirements(vulkan_->GetDevice(), mappableImage, &mem_reqs); - assert(res == VK_SUCCESS); - - mem_alloc.allocationSize = mem_reqs.size; - - // Find the memory type that is host mappable. - bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &mem_alloc.memoryTypeIndex); - assert(pass); - - res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mappableMemory); - assert(res == VK_SUCCESS); - - res = vkBindImageMemory(vulkan_->GetDevice(), mappableImage, mappableMemory, 0); - assert(res == VK_SUCCESS); -} - -uint8_t *VulkanTexture::Lock(int level, int *rowPitch) { - CreateMappableImage(); - - VkImageSubresource subres = {}; - subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subres.mipLevel = 0; - subres.arrayLayer = 0; - - VkSubresourceLayout layout; - void *data; - - // Get the subresource layout so we know what the row pitch is - vkGetImageSubresourceLayout(vulkan_->GetDevice(), mappableImage, &subres, &layout); - VkResult res = vkMapMemory(vulkan_->GetDevice(), mappableMemory, layout.offset, layout.size, 0, &data); - assert(res == VK_SUCCESS); - - *rowPitch = (int)layout.rowPitch; - return (uint8_t *)data; -} - -void VulkanTexture::Unlock(VkCommandBuffer cmd) { - vkUnmapMemory(vulkan_->GetDevice(), mappableMemory); - - // if we already have an image, queue it for destruction and forget it. - Wipe(); - - { // Shrink the diff by not unindenting. If you make major changes, remove this. - VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; - image_create_info.imageType = VK_IMAGE_TYPE_2D; - image_create_info.format = format_; - image_create_info.extent.width = tex_width; - image_create_info.extent.height = tex_height; - image_create_info.extent.depth = 1; - image_create_info.mipLevels = 1; - image_create_info.arrayLayers = 1; - image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; - image_create_info.queueFamilyIndexCount = 0; - image_create_info.pQueueFamilyIndices = NULL; - image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - image_create_info.flags = 0; - // The mappable image cannot be our texture, so create an optimally tiled image and blit to it - image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; - image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image); - assert(res == VK_SUCCESS); - - vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs); - - VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - mem_alloc.memoryTypeIndex = 0; - mem_alloc.allocationSize = mem_reqs.size; - - if (allocator_) { - offset_ = allocator_->Allocate(mem_reqs, &mem); - } else { - offset_ = 0; - // Find memory type - don't specify any mapping requirements - bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex); - assert(pass); - res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem); - assert(res == VK_SUCCESS); - } - - res = vkBindImageMemory(vulkan_->GetDevice(), image, mem, offset_); - assert(res == VK_SUCCESS); - - // Since we're going to blit from the mappable image, set its layout to SOURCE_OPTIMAL - TransitionImageLayout2(cmd, mappableImage, 0, 1, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); - - TransitionImageLayout2(cmd, image, 0, 1, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, VK_ACCESS_TRANSFER_WRITE_BIT); - - VkImageCopy copy_region; - copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy_region.srcSubresource.mipLevel = 0; - copy_region.srcSubresource.baseArrayLayer = 0; - copy_region.srcSubresource.layerCount = 1; - copy_region.srcOffset.x = 0; - copy_region.srcOffset.y = 0; - copy_region.srcOffset.z = 0; - copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy_region.dstSubresource.mipLevel = 0; - copy_region.dstSubresource.baseArrayLayer = 0; - copy_region.dstSubresource.layerCount = 1; - copy_region.dstOffset.x = 0; - copy_region.dstOffset.y = 0; - copy_region.dstOffset.z = 0; - copy_region.extent.width = tex_width; - copy_region.extent.height = tex_height; - copy_region.extent.depth = 1; - - // Put the copy command into the command buffer - vkCmdCopyImage(cmd, - mappableImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ©_region); - - assert(res == VK_SUCCESS); - - // Set the layout for the texture image from DESTINATION_OPTIMAL to SHADER_READ_ONLY - TransitionImageLayout2(cmd, image, 0, 1, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT); - - // Then drop the temporary mappable image - although should not be necessary... - vulkan_->Delete().QueueDeleteImage(mappableImage); - vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory); - } - - VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; - view_info.image = image; - view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - view_info.format = format_; - view_info.components.r = VK_COMPONENT_SWIZZLE_R; - view_info.components.g = VK_COMPONENT_SWIZZLE_G; - view_info.components.b = VK_COMPONENT_SWIZZLE_B; - view_info.components.a = VK_COMPONENT_SWIZZLE_A; - view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - view_info.subresourceRange.baseMipLevel = 0; - view_info.subresourceRange.levelCount = 1; - view_info.subresourceRange.baseArrayLayer = 0; - view_info.subresourceRange.layerCount = 1; - VkResult res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view); - assert(res == VK_SUCCESS); -} - void VulkanTexture::Wipe() { - if (image) { - vulkan_->Delete().QueueDeleteImage(image); + if (image_) { + vulkan_->Delete().QueueDeleteImage(image_); } - if (view) { - vulkan_->Delete().QueueDeleteImageView(view); + if (view_) { + vulkan_->Delete().QueueDeleteImageView(view_); } - if (mem && !allocator_) { - vulkan_->Delete().QueueDeleteDeviceMemory(mem); - } else if (mem) { - allocator_->Free(mem, offset_); - mem = VK_NULL_HANDLE; + if (mem_ && !allocator_) { + vulkan_->Delete().QueueDeleteDeviceMemory(mem_); + } else if (mem_) { + allocator_->Free(mem_, offset_); + mem_ = VK_NULL_HANDLE; } } @@ -231,18 +33,18 @@ static bool IsDepthStencilFormat(VkFormat format) { bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) { Wipe(); - tex_width = w; - tex_height = h; + width_ = w; + height_ = h; numMips_ = numMips; format_ = format; VkImageAspectFlags aspect = IsDepthStencilFormat(format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; - VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; image_create_info.imageType = VK_IMAGE_TYPE_2D; image_create_info.format = format_; - image_create_info.extent.width = tex_width; - image_create_info.extent.height = tex_height; + image_create_info.extent.width = width_; + image_create_info.extent.height = height_; image_create_info.extent.depth = 1; image_create_info.mipLevels = numMips; image_create_info.arrayLayers = 1; @@ -256,41 +58,51 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; } - VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image); + // The graphics debugger always "needs" TRANSFER_SRC but in practice doesn't matter - + // unless validation is on. So let's only force it on when being validated, for now. + if (vulkan_->GetFlags() & VULKAN_FLAG_VALIDATE) { + image_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + + VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } - vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs); + VkMemoryRequirements mem_reqs{}; + vkGetImageMemoryRequirements(vulkan_->GetDevice(), image_, &mem_reqs); if (allocator_) { - offset_ = allocator_->Allocate(mem_reqs, &mem); + offset_ = allocator_->Allocate(mem_reqs, &mem_); if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) { return false; } } else { - VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; mem_alloc.memoryTypeIndex = 0; mem_alloc.allocationSize = mem_reqs.size; // Find memory type - don't specify any mapping requirements bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex); - assert(pass); + _assert_(pass); - res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem); + res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem_); if (res != VK_SUCCESS) { _assert_msg_(G3D, res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + vkDestroyImage(vulkan_->GetDevice(), image_, nullptr); + image_ = VK_NULL_HANDLE; return false; } offset_ = 0; } - res = vkBindImageMemory(vulkan_->GetDevice(), image, mem, offset_); + res = vkBindImageMemory(vulkan_->GetDevice(), image_, mem_, offset_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + // This leaks the image and memory. Should not really happen though... + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } @@ -298,22 +110,22 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, if (initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) { switch (initialLayout) { case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - TransitionImageLayout2(cmd, image, 0, numMips, VK_IMAGE_ASPECT_COLOR_BIT, + TransitionImageLayout2(cmd, image_, 0, numMips, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT); break; default: // If you planned to use UploadMip, you want VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. After the - // upload, you can transition. - assert(false); + // upload, you can transition using EndCreate. + _assert_(false); break; } } // Create the view while we're at it. - VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; - view_info.image = image; + VkImageViewCreateInfo view_info{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + view_info.image = image_; view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; view_info.format = format_; if (mapping) { @@ -330,16 +142,17 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, view_info.subresourceRange.baseArrayLayer = 0; view_info.subresourceRange.layerCount = 1; - res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view); + res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + // This leaks the image. + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } return true; } void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength) { - VkBufferImageCopy copy_region = {}; + VkBufferImageCopy copy_region{}; copy_region.bufferOffset = offset; copy_region.bufferRowLength = (uint32_t)rowLength; copy_region.bufferImageHeight = 0; // 2D @@ -351,7 +164,7 @@ void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mi copy_region.imageSubresource.baseArrayLayer = 0; copy_region.imageSubresource.layerCount = 1; - vkCmdCopyBufferToImage(cmd, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); + vkCmdCopyBufferToImage(cmd, buffer, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); } void VulkanTexture::GenerateMip(VkCommandBuffer cmd, int mip) { @@ -361,33 +174,33 @@ void VulkanTexture::GenerateMip(VkCommandBuffer cmd, int mip) { blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.srcSubresource.layerCount = 1; blit.srcSubresource.mipLevel = mip - 1; - blit.srcOffsets[1].x = tex_width >> (mip - 1); - blit.srcOffsets[1].y = tex_height >> (mip - 1); + blit.srcOffsets[1].x = width_ >> (mip - 1); + blit.srcOffsets[1].y = height_ >> (mip - 1); blit.srcOffsets[1].z = 1; blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.dstSubresource.layerCount = 1; blit.dstSubresource.mipLevel = mip; - blit.dstOffsets[1].x = tex_width >> mip; - blit.dstOffsets[1].y = tex_height >> mip; + blit.dstOffsets[1].x = width_ >> mip; + blit.dstOffsets[1].y = height_ >> mip; blit.dstOffsets[1].z = 1; - TransitionImageLayout2(cmd, image, mip - 1, 1, VK_IMAGE_ASPECT_COLOR_BIT, + TransitionImageLayout2(cmd, image_, mip - 1, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); // Low-quality mipmap generation, but works okay. - vkCmdBlitImage(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR); + vkCmdBlitImage(cmd, image_, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR); - TransitionImageLayout2(cmd, image, mip - 1, 1, VK_IMAGE_ASPECT_COLOR_BIT, + TransitionImageLayout2(cmd, image_, mip - 1, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); } void VulkanTexture::EndCreate(VkCommandBuffer cmd, bool vertexTexture) { - TransitionImageLayout2(cmd, image, 0, 1, + TransitionImageLayout2(cmd, image_, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, vertexTexture ? VK_PIPELINE_STAGE_VERTEX_SHADER_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, @@ -395,22 +208,16 @@ void VulkanTexture::EndCreate(VkCommandBuffer cmd, bool vertexTexture) { } void VulkanTexture::Destroy() { - if (view != VK_NULL_HANDLE) { - vulkan_->Delete().QueueDeleteImageView(view); + if (view_ != VK_NULL_HANDLE) { + vulkan_->Delete().QueueDeleteImageView(view_); } - if (image != VK_NULL_HANDLE) { - if (mappableImage == image) { - mappableImage = VK_NULL_HANDLE; - } - vulkan_->Delete().QueueDeleteImage(image); + if (image_ != VK_NULL_HANDLE) { + vulkan_->Delete().QueueDeleteImage(image_); } - if (mem != VK_NULL_HANDLE && !allocator_) { - if (mappableMemory == mem) { - mappableMemory = VK_NULL_HANDLE; - } - vulkan_->Delete().QueueDeleteDeviceMemory(mem); - } else if (mem != VK_NULL_HANDLE) { - allocator_->Free(mem, offset_); - mem = VK_NULL_HANDLE; + if (mem_ != VK_NULL_HANDLE && !allocator_) { + vulkan_->Delete().QueueDeleteDeviceMemory(mem_); + } else if (mem_ != VK_NULL_HANDLE) { + allocator_->Free(mem_, offset_); + mem_ = VK_NULL_HANDLE; } } diff --git a/Common/Vulkan/VulkanImage.h b/Common/Vulkan/VulkanImage.h index 2b8486c975..14c347078c 100644 --- a/Common/Vulkan/VulkanImage.h +++ b/Common/Vulkan/VulkanImage.h @@ -9,25 +9,12 @@ class VulkanDeviceAllocator; class VulkanTexture { public: VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator) - : vulkan_(vulkan), image(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), view(VK_NULL_HANDLE), - tex_width(0), tex_height(0), numMips_(1), format_(VK_FORMAT_UNDEFINED), - mappableImage(VK_NULL_HANDLE), mappableMemory(VK_NULL_HANDLE), - allocator_(allocator), offset_(0) { - memset(&mem_reqs, 0, sizeof(mem_reqs)); + : vulkan_(vulkan), allocator_(allocator) { } ~VulkanTexture() { Destroy(); } - // Simple usage - no cleverness, no mipmaps. - // Always call Create, Lock, Unlock. Unlock performs the upload if necessary. - // Can later Lock and Unlock again. This cannot change the format. Create cannot - // be called a second time without recreating the texture object until Destroy has - // been called. - VkResult Create(int w, int h, VkFormat format); - uint8_t *Lock(int level, int *rowPitch); - void Unlock(VkCommandBuffer cmd); - // Fast uploads from buffer. Mipmaps supported. // Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip. // When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. @@ -39,29 +26,27 @@ public: void Destroy(); // Used in image copies, etc. - VkImage GetImage() const { return image; } + VkImage GetImage() const { return image_; } // Used for sampling, generally. - VkImageView GetImageView() const { return view; } + VkImageView GetImageView() const { return view_; } - int32_t GetWidth() const { return tex_width; } - int32_t GetHeight() const { return tex_height; } + int32_t GetWidth() const { return width_; } + int32_t GetHeight() const { return height_; } int32_t GetNumMips() const { return numMips_; } VkFormat GetFormat() const { return format_; } private: - void CreateMappableImage(); void Wipe(); VulkanContext *vulkan_; - VkImage image; - VkDeviceMemory mem; - VkImageView view; - int32_t tex_width, tex_height, numMips_; - VkFormat format_; - VkImage mappableImage; - VkDeviceMemory mappableMemory; - VkMemoryRequirements mem_reqs; + VkImage image_ = VK_NULL_HANDLE; + VkImageView view_ = VK_NULL_HANDLE; + VkDeviceMemory mem_ = VK_NULL_HANDLE; + int32_t width_ = 0; + int32_t height_ = 0; + int32_t numMips_ = 1; + VkFormat format_ = VK_FORMAT_UNDEFINED; VulkanDeviceAllocator *allocator_; - size_t offset_; + size_t offset_ = 0; }; diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 72a3237f04..0d41785a28 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Vulkan/VulkanLoader.h" +#include #include "base/logging.h" #include "base/basictypes.h" @@ -113,16 +114,12 @@ PFN_vkDestroyCommandPool vkDestroyCommandPool; PFN_vkResetCommandPool vkResetCommandPool; PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; PFN_vkFreeCommandBuffers vkFreeCommandBuffers; -PFN_vkBeginCommandBuffer vkBeginCommandBuffer; -PFN_vkEndCommandBuffer vkEndCommandBuffer; -PFN_vkResetCommandBuffer vkResetCommandBuffer; + +// Used frequently PFN_vkCmdBindPipeline vkCmdBindPipeline; PFN_vkCmdSetViewport vkCmdSetViewport; PFN_vkCmdSetScissor vkCmdSetScissor; -PFN_vkCmdSetLineWidth vkCmdSetLineWidth; -PFN_vkCmdSetDepthBias vkCmdSetDepthBias; PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; -PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; PFN_vkCmdSetStencilReference vkCmdSetStencilReference; @@ -131,34 +128,43 @@ PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer; PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers; PFN_vkCmdDraw vkCmdDraw; PFN_vkCmdDrawIndexed vkCmdDrawIndexed; -PFN_vkCmdDrawIndirect vkCmdDrawIndirect; -PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; -PFN_vkCmdDispatch vkCmdDispatch; -PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; +PFN_vkCmdClearAttachments vkCmdClearAttachments; +PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; +PFN_vkCmdPushConstants vkCmdPushConstants; + +// Every frame to a few times per frame +PFN_vkBeginCommandBuffer vkBeginCommandBuffer; +PFN_vkEndCommandBuffer vkEndCommandBuffer; +PFN_vkResetCommandBuffer vkResetCommandBuffer; +PFN_vkCmdSetEvent vkCmdSetEvent; +PFN_vkCmdResetEvent vkCmdResetEvent; +PFN_vkCmdWaitEvents vkCmdWaitEvents; +PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; +PFN_vkCmdEndRenderPass vkCmdEndRenderPass; PFN_vkCmdCopyBuffer vkCmdCopyBuffer; PFN_vkCmdCopyImage vkCmdCopyImage; PFN_vkCmdBlitImage vkCmdBlitImage; PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer; + +PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; +PFN_vkCmdSetLineWidth vkCmdSetLineWidth; +PFN_vkCmdSetDepthBias vkCmdSetDepthBias; +PFN_vkCmdDrawIndirect vkCmdDrawIndirect; +PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; +PFN_vkCmdDispatch vkCmdDispatch; +PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer; PFN_vkCmdFillBuffer vkCmdFillBuffer; PFN_vkCmdClearColorImage vkCmdClearColorImage; PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage; -PFN_vkCmdClearAttachments vkCmdClearAttachments; PFN_vkCmdResolveImage vkCmdResolveImage; -PFN_vkCmdSetEvent vkCmdSetEvent; -PFN_vkCmdResetEvent vkCmdResetEvent; -PFN_vkCmdWaitEvents vkCmdWaitEvents; -PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; PFN_vkCmdBeginQuery vkCmdBeginQuery; PFN_vkCmdEndQuery vkCmdEndQuery; PFN_vkCmdResetQueryPool vkCmdResetQueryPool; PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp; PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults; -PFN_vkCmdPushConstants vkCmdPushConstants; -PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; PFN_vkCmdNextSubpass vkCmdNextSubpass; -PFN_vkCmdEndRenderPass vkCmdEndRenderPass; PFN_vkCmdExecuteCommands vkCmdExecuteCommands; #ifdef __ANDROID__ @@ -198,37 +204,142 @@ static HINSTANCE vulkanLibrary; static void *vulkanLibrary; #endif +bool g_vulkanAvailabilityChecked = false; +bool g_vulkanMayBeAvailable = false; + #define LOAD_INSTANCE_FUNC(instance, x) x = (PFN_ ## x)vkGetInstanceProcAddr(instance, #x); if (!x) {ILOG("Missing (instance): %s", #x);} #define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {ILOG("Missing (device): %s", #x);} #define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {ILOG("Missing (global): %s", #x);} +#define LOAD_GLOBAL_FUNC_LOCAL(lib, x) (PFN_ ## x)dlsym(lib, #x); + static const char *so_names[] = { "libvulkan.so", "libvulkan.so.1", }; +void VulkanSetAvailable(bool available) { + g_vulkanAvailabilityChecked = true; + g_vulkanMayBeAvailable = available; +} + bool VulkanMayBeAvailable() { - if (vulkanLibrary) - return true; - bool available = false; + if (g_vulkanAvailabilityChecked) + return g_vulkanMayBeAvailable; #ifndef _WIN32 + void *lib = nullptr; for (int i = 0; i < ARRAY_SIZE(so_names); i++) { - void *lib = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL); + lib = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL); if (lib) { - available = true; - dlclose(lib); break; } } #else // LoadLibrary etc HINSTANCE lib = LoadLibrary(L"vulkan-1.dll"); - available = lib != 0; - if (lib) { - FreeLibrary(lib); - } #endif - return available; + if (!lib) { + g_vulkanAvailabilityChecked = true; + g_vulkanMayBeAvailable = false; + return false; + } + + // Do a hyper minimal initialization and teardown to figure out if there's any chance + // that any sort of Vulkan will be usable. + PFN_vkCreateInstance localCreateInstance = LOAD_GLOBAL_FUNC_LOCAL(lib, vkCreateInstance); + PFN_vkEnumeratePhysicalDevices localEnumerate = LOAD_GLOBAL_FUNC_LOCAL(lib, vkEnumeratePhysicalDevices); + PFN_vkDestroyInstance localDestroyInstance = LOAD_GLOBAL_FUNC_LOCAL(lib, vkDestroyInstance); + PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties = LOAD_GLOBAL_FUNC_LOCAL(lib, vkGetPhysicalDeviceProperties); + + // Need to predeclare all this because of the gotos... + VkInstanceCreateInfo ci{ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; + VkApplicationInfo info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; + std::vector devices; + bool anyGood = false; + const char *instanceExtensions[1]{}; + VkInstance instance = VK_NULL_HANDLE; + VkResult res; + uint32_t physicalDeviceCount = 0; + + if (!localCreateInstance || !localEnumerate || !localDestroyInstance || !localGetPhysicalDeviceProperties) + goto bail; + +#ifdef _WIN32 + instanceExtensions[0] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; + ci.enabledExtensionCount = 1; +#elif defined(__ANDROID__) + instanceExtensions[0] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; + ci.enabledExtensionCount = 1; +#endif + + ci.ppEnabledExtensionNames = instanceExtensions; + ci.enabledLayerCount = 0; + info.apiVersion = VK_API_VERSION_1_0; + info.applicationVersion = 1; + info.engineVersion = 1; + info.pApplicationName = "VulkanChecker"; + info.pEngineName = "VulkanChecker"; + ci.pApplicationInfo = &info; + ci.flags = 0; + res = localCreateInstance(&ci, nullptr, &instance); + if (res != VK_SUCCESS) { + instance = nullptr; + ELOG("Failed to create vulkan instance."); + goto bail; + } + ILOG("Vulkan test instance created successfully."); + res = localEnumerate(instance, &physicalDeviceCount, nullptr); + if (res != VK_SUCCESS) { + ELOG("Failed to count physical devices."); + goto bail; + } + if (physicalDeviceCount == 0) { + ELOG("No physical Vulkan devices."); + goto bail; + } + devices.resize(physicalDeviceCount); + res = localEnumerate(instance, &physicalDeviceCount, devices.data()); + if (res != VK_SUCCESS) { + ELOG("Failed to enumerate physical devices."); + goto bail; + } + anyGood = false; + for (auto device : devices) { + VkPhysicalDeviceProperties props; + localGetPhysicalDeviceProperties(device, &props); + switch (props.deviceType) { + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + anyGood = true; + break; + } + // TODO: Should also check queuefamilyproperties for a GRAPHICS queue family? Oh well. + } + + if (!anyGood) { + WLOG("Found Vulkan API, but no good Vulkan device!"); + g_vulkanMayBeAvailable = false; + } else { + ILOG("Found working Vulkan API!"); + g_vulkanMayBeAvailable = true; + } + +bail: + g_vulkanAvailabilityChecked = true; + if (instance) { + localDestroyInstance(instance, nullptr); + } + if (lib) { +#ifndef _WIN32 + dlclose(lib); +#else + FreeLibrary(lib); +#endif + } else { + ELOG("Vulkan with working device not detected."); + } + return g_vulkanMayBeAvailable; } bool VulkanLoad() { diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index 636bff82c7..d51d833da5 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -201,6 +201,7 @@ extern PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT; // Way to do a quick check before even attempting to load. bool VulkanMayBeAvailable(); +void VulkanSetAvailable(bool available); bool VulkanLoad(); void VulkanLoadInstanceFunctions(VkInstance instance); diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 0950bc8596..4107089463 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -36,7 +36,7 @@ VulkanPushBuffer::~VulkanPushBuffer() { bool VulkanPushBuffer::AddBuffer() { BufInfo info; - VkBufferCreateInfo b = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + VkBufferCreateInfo b{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; b.size = size_; b.flags = 0; b.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; @@ -56,7 +56,7 @@ bool VulkanPushBuffer::AddBuffer() { // TODO: We really should use memoryTypeIndex here.. // Okay, that's the buffer. Now let's allocate some memory for it. - VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; // TODO: Should check here that memoryTypeIndex_ matches reqs.memoryTypeBits. alloc.memoryTypeIndex = memoryTypeIndex_; alloc.allocationSize = reqs.size; @@ -75,9 +75,8 @@ bool VulkanPushBuffer::AddBuffer() { return false; } - buf_ = buffers_.size(); - buffers_.resize(buf_ + 1); - buffers_[buf_] = info; + buffers_.push_back(info); + buf_ = buffers_.size() - 1; return true; } @@ -136,17 +135,17 @@ size_t VulkanPushBuffer::GetTotalSize() const { } void VulkanPushBuffer::Map() { - assert(!writePtr_); + _dbg_assert_(G3D, !writePtr_); VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); - assert(writePtr_); + _dbg_assert_(G3D, writePtr_); assert(VK_SUCCESS == res); } void VulkanPushBuffer::Unmap() { - assert(writePtr_); + _dbg_assert_(G3D, writePtr_ != 0); /* // Should not need this since we use coherent memory. - VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; + VkMappedMemoryRange range{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; range.offset = 0; range.size = offset_; range.memory = buffers_[buf_].deviceMemory; @@ -284,9 +283,9 @@ bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t b int VulkanDeviceAllocator::ComputeUsagePercent() const { int blockSum = 0; int blocksUsed = 0; - for (int i = 0; i < slabs_.size(); i++) { + for (size_t i = 0; i < slabs_.size(); i++) { blockSum += (int)slabs_[i].usage.size(); - for (int j = 0; j < slabs_[i].usage.size(); j++) { + for (size_t j = 0; j < slabs_[i].usage.size(); j++) { blocksUsed += slabs_[i].usage[j] != 0 ? 1 : 0; } } @@ -360,17 +359,14 @@ void VulkanDeviceAllocator::ExecuteFree(FreeInfo *userdata) { slab.allocSizes.erase(it); } else { // Ack, a double free? - _assert_msg_(G3D, false, "Double free? Block missing at offset %d", userdata->offset); + _assert_msg_(G3D, false, "Double free? Block missing at offset %d", (int)userdata->offset); } found = true; break; } // Wrong deviceMemory even? Maybe it was already decimated, but that means a double-free. - if (!found) { - Crash(); - } - + _assert_msg_(G3D, found, "ExecuteFree: Block not found (offset %d)", (int)offset); delete userdata; } @@ -381,7 +377,7 @@ bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes) { minSlabSize_ <<= 1; } - VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; alloc.allocationSize = minSlabSize_; alloc.memoryTypeIndex = memoryTypeIndex_; diff --git a/Core/Config.cpp b/Core/Config.cpp index 1546cb7dd9..bf8eb9ee7f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -506,7 +506,6 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode, true, true), ConfigSetting("SoftwareRenderer", &g_Config.bSoftwareRendering, false, true, true), ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true, true, true), - ReportedConfigSetting("SoftwareSkinning", &g_Config.bSoftwareSkinning, true, true, true), ReportedConfigSetting("TextureFiltering", &g_Config.iTexFiltering, 1, true, true), ReportedConfigSetting("BufferFiltering", &g_Config.iBufFilter, 1, true, true), ReportedConfigSetting("InternalResolution", &g_Config.iInternalResolution, &DefaultInternalResolution, true, true), @@ -723,8 +722,8 @@ static ConfigSetting controlSettings[] = { ConfigSetting("UseMouse", &g_Config.bMouseControl, false, true, true), ConfigSetting("MapMouse", &g_Config.bMapMouse, false, true, true), ConfigSetting("ConfineMap", &g_Config.bMouseConfine, false, true, true), - ConfigSetting("MouseSensitivity", &g_Config.fMouseSensitivity, 0.1, true, true), - ConfigSetting("MouseSmoothing", &g_Config.fMouseSmoothing, 0.9, true, true), + ConfigSetting("MouseSensitivity", &g_Config.fMouseSensitivity, 0.1f, true, true), + ConfigSetting("MouseSmoothing", &g_Config.fMouseSmoothing, 0.9f, true, true), ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 0d0a54ac9b..a486ff3400 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -160,7 +160,6 @@ public: int iGPUBackend; bool bSoftwareRendering; bool bHardwareTransform; // only used in the GLES backend - bool bSoftwareSkinning; // may speed up some games int iRenderingMode; // 0 = non-buffered rendering 1 = buffered rendering int iTexFiltering; // 1 = off , 2 = nearest , 3 = linear , 4 = linear(CG) diff --git a/Core/Core.cpp b/Core/Core.cpp index c93cc683c6..d549d79c4f 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -37,6 +37,7 @@ #include "Common/GraphicsContext.h" #ifdef _WIN32 +#include "Common/CommonWindows.h" #include "Windows/InputDevice.h" #endif @@ -176,7 +177,7 @@ bool UpdateScreenScale(int width, int height) { dp_yres = new_dp_yres; pixel_xres = width; pixel_yres = height; - INFO_LOG(SYSTEM, "pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); + DEBUG_LOG(SYSTEM, "pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); NativeResized(); return true; } @@ -189,14 +190,11 @@ void UpdateRunLoop() { return; } NativeUpdate(); - - if (GetUIState() != UISTATE_EXIT) { - NativeRender(graphicsContext); - } + NativeRender(graphicsContext); } void KeepScreenAwake() { -#ifdef _WIN32 +#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); #endif } @@ -268,6 +266,7 @@ reswitch: if (GetUIState() != UISTATE_INGAME) { CoreStateProcessed(); if (GetUIState() == UISTATE_EXIT) { + UpdateRunLoop(); return; } Core_RunLoop(ctx); diff --git a/Core/Core.h b/Core/Core.h index 98262f7beb..9adbd6356e 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -24,11 +24,15 @@ class GraphicsContext; // called from emu thread void UpdateRunLoop(); + void Core_Run(GraphicsContext *ctx); void Core_Stop(); void Core_ErrorPause(); // For platforms that don't call Core_Run void Core_SetGraphicsContext(GraphicsContext *ctx); + +void Core_RunRenderThreadFrame(); + // called from gui void Core_EnableStepping(bool step); void Core_DoSingleStep(); diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 0b14aa764a..71e6070399 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -30,10 +30,11 @@ void hleCheat(u64 userdata, int cyclesLate); static inline std::string TrimString(const std::string &s) { auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { - return std::isspace(c); + // isspace() expects 0 - 255, so convert any sign-extended value. + return std::isspace(c & 0xFF); }); auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c){ - return std::isspace(c); + return std::isspace(c & 0xFF); }).base(); return wsback > wsfront ? std::string(wsfront, wsback) : std::string(); } @@ -351,7 +352,7 @@ std::vector CWCheatEngine::GetCodesList() { // It also goes through other "_" lines, but they all have to meet this requirement anyway // so we don't have to specify any syntax checks here that are made by cheat engine. if (line.length() >= 5 && line[0] == '_') { - for (int i = 4; i < line.length(); i++) { + for (size_t i = 4; i < line.length(); i++) { if (line[i] != ' ') { validCheatLine = true; break; diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index c9dc744843..5b80b23e79 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -395,8 +395,8 @@ void PSPSaveDialog::DisplaySaveDataInfo1() } else { char title[512]; char time[512]; - char saveTitle[512]; - char saveDetail[512]; + char saveTitle[1024]; + char saveDetail[1024]; char am_pm[] = "AM"; char hour_time[10] ; @@ -421,27 +421,27 @@ void PSPSaveDialog::DisplaySaveDataInfo1() snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); } - snprintf(title, 512, "%s", param.GetFileInfo(currentSelectedSave).title); + snprintf(title, sizeof(title), "%s", param.GetFileInfo(currentSelectedSave).title); int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday; int month = param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1; int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900; s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024; switch (g_Config.iDateFormat) { case 1: - snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); + snprintf(time, sizeof(time), "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); break; case 2: - snprintf(time, 512, "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK); + snprintf(time, sizeof(time), "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK); break; case 3: - snprintf(time, 512, "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK); + snprintf(time, sizeof(time), "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK); break; default: - snprintf(time, 512, "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); + snprintf(time, sizeof(time), "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); } - snprintf(saveTitle, 512, "%s", param.GetFileInfo(currentSelectedSave).saveTitle); - snprintf(saveDetail, 512, "%s", param.GetFileInfo(currentSelectedSave).saveDetail); - + snprintf(saveTitle, sizeof(saveTitle), "%s", param.GetFileInfo(currentSelectedSave).saveTitle); + snprintf(saveDetail, sizeof(saveDetail), "%s", param.GetFileInfo(currentSelectedSave).saveDetail); + PPGeDrawRect(180, 136, 480, 137, CalcFadedColor(0xFFFFFFFF)); std::string titleTxt = title; std::string timeTxt = time; diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index b68e7775b8..68f7531e2d 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -29,7 +29,7 @@ const char *ElfReader::GetSectionName(int section) const { return nullptr; int nameOffset = sections[section].sh_name; - if (nameOffset < 0 || nameOffset >= size_) { + if (nameOffset < 0 || (size_t)nameOffset >= size_) { ERROR_LOG(LOADER, "ELF: Bad name offset %d in section %d (max = %d)", nameOffset, section, (int)size_); return nullptr; } diff --git a/Core/ELF/PBPReader.cpp b/Core/ELF/PBPReader.cpp index 1eb4f70556..76fdbb36e4 100644 --- a/Core/ELF/PBPReader.cpp +++ b/Core/ELF/PBPReader.cpp @@ -45,7 +45,7 @@ PBPReader::PBPReader(FileLoader *fileLoader) : file_(nullptr), header_(), isELF_ return; } - DEBUG_LOG(LOADER, "Loading PBP, version = %08x", header_.version); + VERBOSE_LOG(LOADER, "Loading PBP, version = %08x", header_.version); file_ = fileLoader; } diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index b72b69ff30..27b4113aa3 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017- PPSSPP Project. +// Copyright (c) 2017- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -50,9 +50,9 @@ void BlobFileSystem::CloseFile(u32 handle) { size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { auto entry = entries_.find(handle); if (entry != entries_.end()) { - size_t readSize = fileLoader_->ReadAt(entry->second, size, pointer); + s64 readSize = (s64)fileLoader_->ReadAt(entry->second, (size_t)size, pointer); entry->second += readSize; - return readSize; + return (size_t)readSize; } return 0; } diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 6e53be5110..f4db57f7ab 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -186,7 +186,7 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil #endif std::string fullName = GetLocalPath(basePath,fileName); - DEBUG_LOG(FILESYS,"Actually opening %s", fullName.c_str()); + VERBOSE_LOG(FILESYS,"Actually opening %s", fullName.c_str()); // On the PSP, truncating doesn't lose data. If you seek later, you'll recover it. // This is abnormal, so we deviate from the PSP's behavior and truncate on write/close. @@ -1002,7 +1002,7 @@ u32 VFSFileSystem::OpenFile(std::string filename, FileAccess access, const char std::string fullName = GetLocalPath(filename); const char *fullNameC = fullName.c_str(); - DEBUG_LOG(FILESYS,"VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str()); + VERBOSE_LOG(FILESYS,"VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str()); size_t size; u8 *data = VFSReadFile(fullNameC, &size); diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 0b2bacbec8..dfa757ecf0 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -863,7 +863,9 @@ void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelFormat, int sync) framebuf = fbstate; gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.stride, framebuf.fmt); // IMMEDIATE means that the buffer is fine. We can just flip immediately. - if (!flippedThisFrame) + // Doing it in non-buffered though creates problems (black screen) on occasion though + // so let's not. + if (!flippedThisFrame && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) __DisplayFlip(0); } else { // Delay the write until vblank diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 47a9ae7d84..82da25de65 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1268,7 +1268,8 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd scan = g_Config.bFuncReplacements; #endif - bool gotSymbols = scan && reader.LoadSymbols(); + // If the ELF has debug symbols, don't add entries to the symbol table. + bool insertSymbols = scan && !reader.LoadSymbols(); std::vector codeSections = reader.GetCodeSections(); for (SectionID id : codeSections) { u32 start = reader.GetSectionAddr(id); @@ -1280,8 +1281,9 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd if (end > module->textEnd) module->textEnd = end; - if (scan) - MIPSAnalyst::ScanForFunctions(start, end, !gotSymbols); + if (scan) { + insertSymbols = MIPSAnalyst::ScanForFunctions(start, end, insertSymbols); + } } // Some games don't have any sections at all. @@ -1290,14 +1292,18 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAdd u32 scanEnd = module->textEnd; // Skip the exports and imports sections, they're not code. if (scanEnd >= std::min(modinfo->libent, modinfo->libstub)) { - MIPSAnalyst::ScanForFunctions(scanStart, std::min(modinfo->libent, modinfo->libstub) - 4, !gotSymbols); + insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, std::min(modinfo->libent, modinfo->libstub) - 4, insertSymbols); scanStart = std::min(modinfo->libentend, modinfo->libstubend); } if (scanEnd >= std::max(modinfo->libent, modinfo->libstub)) { - MIPSAnalyst::ScanForFunctions(scanStart, std::max(modinfo->libent, modinfo->libstub) - 4, !gotSymbols); + insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, std::max(modinfo->libent, modinfo->libstub) - 4, insertSymbols); scanStart = std::max(modinfo->libentend, modinfo->libstubend); } - MIPSAnalyst::ScanForFunctions(scanStart, scanEnd, !gotSymbols); + insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, scanEnd, insertSymbols); + } + + if (scan) { + MIPSAnalyst::FinalizeScan(insertSymbols); } } @@ -1577,6 +1583,7 @@ void __KernelLoadReset() { HLEShutdown(); Replacement_Init(); HLEInit(); + assert(gpu); gpu->Reinitialize(); } @@ -1587,6 +1594,8 @@ void __KernelLoadReset() { bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) { SceKernelLoadExecParam param; + PSP_SetLoading("Loading game..."); + if (paramPtr) Memory::ReadStruct(paramPtr, ¶m); else @@ -1625,6 +1634,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str pspFileSystem.ReadFile(handle, temp, (size_t)info.size); + PSP_SetLoading("Loading modules..."); Module *module = __KernelLoadModule(temp, (size_t)info.size, 0, error_string); if (!module || module->isFake) { @@ -1665,6 +1675,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str if (module->nm.module_start_thread_stacksize != 0) option.stacksize = module->nm.module_start_thread_stacksize; + PSP_SetLoading("Starting modules..."); if (paramPtr) __KernelStartModule(module, param.args, (const char*)param_argp, &option); else @@ -1681,6 +1692,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_string) { __KernelLoadReset(); + PSP_SetLoading("Generating code..."); mipsr4k.pc = PSP_GetUserMemoryBase(); diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index ca617d5b90..ee636a89fe 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -78,6 +78,7 @@ StereoResampler::StereoResampler() StereoResampler::~StereoResampler() { delete[] m_buffer; + m_buffer = nullptr; } void StereoResampler::UpdateBufferSize() { diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 050cef8025..5ded4af630 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -179,20 +179,10 @@ void ArmJit::CompileDelaySlot(int flags) _MSR(true, false, R8); // Restore flags register } - void ArmJit::Compile(u32 em_address) { PROFILE_THIS_SCOPE("jitc"); -#if PPSSPP_PLATFORM(UWP) // INFO_LOG(JIT, "Compiling at %08x", em_address); - // Unfortunately Microsoft forgot to expose FlushInstructionCache to UWP applications... even though they expose - // the ability to generate code :( This works great on x86 but on ARM we're out of luck. - // This seems to be enough to flush the instruction cache: - // If this OutputDebugStringUTF8 is not called, we crash. - // But it only helps if the debugger is attached :( If not, we still crash. - // So really, the JIT is broken on Windows UWP ARM. - OutputDebugStringUTF8("JITHACK"); -#endif if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) { ClearCache(); diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 98d07490ab..9a31123fef 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -878,13 +878,16 @@ namespace MIPSAnalyst { for (auto iter = functions.begin(), end = functions.end(); iter != end; iter++) { AnalyzedFunction &f = *iter; + if (Memory::IsValidRange(f.start, f.end - f.start + 4)) { + continue; + } // This is unfortunate. In case of emuhacks or relocs, we have to make a copy. buffer.resize((f.end - f.start + 4) / 4); size_t pos = 0; for (u32 addr = f.start; addr <= f.end; addr += 4) { u32 validbits = 0xFFFFFFFF; - MIPSOpcode instr = Memory::Read_Instruction(addr, true); + MIPSOpcode instr = Memory::ReadUnchecked_Instruction(addr, true); if (MIPS_IS_EMUHACK(instr)) { f.hasHash = false; goto skip; @@ -1015,7 +1018,7 @@ skip: return furthestJumpbackAddr; } - void ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols) { + bool ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols) { std::lock_guard guard(functions_lock); AnalyzedFunction currentFunction = {startAddr}; @@ -1164,6 +1167,10 @@ skip: } } + return insertSymbols; + } + + void FinalizeScan(bool insertSymbols) { HashFunctions(); std::string hashMapFilename = GetSysDirectory(DIRECTORY_SYSTEM) + "knownfuncs.ini"; diff --git a/Core/MIPS/MIPSAnalyst.h b/Core/MIPS/MIPSAnalyst.h index 9d6683c48a..746fa26f90 100644 --- a/Core/MIPS/MIPSAnalyst.h +++ b/Core/MIPS/MIPSAnalyst.h @@ -105,7 +105,9 @@ namespace MIPSAnalyst // If we have loaded symbols from the elf, we'll register functions as they are touched // so that we don't just dump them all in the cache. void RegisterFunction(u32 startAddr, u32 size, const char *name); - void ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols); + // Returns new insertSymbols value for FinalizeScan(). + bool ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols); + void FinalizeScan(bool insertSymbols); void ForgetFunctions(u32 startAddr, u32 endAddr); void PrecompileFunctions(); void PrecompileFunction(u32 startAddr, u32 length); diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 784cba75ca..174b211400 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -1360,8 +1360,8 @@ namespace MIPSInt { for (int i = 0; i < n; i++) { - d[i] = 0.0f; - for (int k = 0; k < n; k++) + d[i] = s[i*4] * t[0]; + for (int k = 1; k < n; k++) { d[i] += s[i*4+k] * t[k]; } @@ -1371,7 +1371,8 @@ namespace MIPSInt { Reporting::ReportMessage("Trying to interpret instruction that can't be interpreted (BADVTFM)"); _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted (BADVTFM)"); - memset(d, 0, sizeof(d)); + for (int i = 0; i < n; i++) + d[i] = 0.0; } WriteVector(d, sz, vd); PC += 4; diff --git a/Core/MemMap.h b/Core/MemMap.h index a681df9d11..5c41f1e683 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -83,8 +83,8 @@ extern u32 g_MemorySize; extern u32 g_PSPModel; // UWP has such limited memory management that we need to mask -// even in 64-bit mode. -#if PPSSPP_ARCH(32BIT) || PPSSPP_PLATFORM(UWP) +// even in 64-bit mode. Also, when using the sanitizer, we need to mask as well. +#if PPSSPP_ARCH(32BIT) || PPSSPP_PLATFORM(UWP) || USE_ADDRESS_SANITIZER #define MASKED_PSP_MEMORY #endif diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 1a910edb05..7567d0b29c 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -16,8 +16,10 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "file/file_util.h" #include "util/text/utf8.h" +#include "thread/threadutil.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" @@ -253,6 +255,8 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { INFO_LOG(LOADER,"Loading %s...", bootpath.c_str()); std::thread th([bootpath] { + setCurrentThreadName("ExecLoader"); + PSP_SetLoading("Loading executable..."); // TODO: We can't use the initial error_string pointer. bool success = __KernelLoadExec(bootpath.c_str(), 0, &PSP_CoreParameter().errorString); if (success && coreState == CORE_POWERUP) { diff --git a/Core/System.cpp b/Core/System.cpp index cc41c39313..cc559308c4 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -81,12 +81,9 @@ ParamSFOData g_paramSFO; static GlobalUIState globalUIState; static CoreParameter coreParameter; static FileLoader *loadedFile; -static std::thread *cpuThread = nullptr; -static std::thread::id cpuThreadID; -static std::mutex cpuThreadLock; -static std::condition_variable cpuThreadCond; -static std::condition_variable cpuThreadReplyCond; -static u64 cpuThreadUntil; +static std::mutex loadingReasonLock; +static std::string loadingReason; + bool audioInitialized; bool coreCollectDebugStats = false; @@ -142,45 +139,6 @@ void Audio_Shutdown() { } } -bool IsOnSeparateCPUThread() { - if (cpuThread != nullptr) { - return cpuThreadID == std::this_thread::get_id(); - } else { - return false; - } -} - -void CPU_SetStateNoLock(CPUThreadState to) { - cpuThreadState = to; - cpuThreadCond.notify_one(); - cpuThreadReplyCond.notify_one(); -} - -void CPU_SetState(CPUThreadState to) { - std::lock_guard guard(cpuThreadLock); - CPU_SetStateNoLock(to); -} - -bool CPU_NextState(CPUThreadState from, CPUThreadState to) { - std::lock_guard guard(cpuThreadLock); - if (cpuThreadState == from) { - CPU_SetStateNoLock(to); - return true; - } else { - return false; - } -} - -bool CPU_NextStateNot(CPUThreadState from, CPUThreadState to) { - std::lock_guard guard(cpuThreadLock); - if (cpuThreadState != from) { - CPU_SetStateNoLock(to); - return true; - } else { - return false; - } -} - bool CPU_IsReady() { if (coreState == CORE_POWERUP) return false; @@ -195,13 +153,6 @@ bool CPU_HasPendingAction() { return cpuThreadState != CPU_THREAD_RUNNING; } -void CPU_WaitStatus(std::condition_variable &cond, bool (*pred)()) { - std::unique_lock guard(cpuThreadLock); - while (!pred()) { - cond.wait(guard); - } -} - void CPU_Shutdown(); void CPU_Init() { @@ -278,7 +229,6 @@ void CPU_Init() { if (!LoadFile(&loadedFile, &coreParameter.errorString)) { CPU_Shutdown(); coreParameter.fileToStart = ""; - CPU_SetState(CPU_THREAD_NOT_RUNNING); return; } @@ -321,52 +271,6 @@ void UpdateLoadedFile(FileLoader *fileLoader) { loadedFile = fileLoader; } -void CPU_RunLoop() { - setCurrentThreadName("CPU"); - - if (CPU_NextState(CPU_THREAD_PENDING, CPU_THREAD_STARTING)) { - CPU_Init(); - CPU_NextState(CPU_THREAD_STARTING, CPU_THREAD_RUNNING); - } else if (!CPU_NextState(CPU_THREAD_RESUME, CPU_THREAD_RUNNING)) { - ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); - return; - } - - while (cpuThreadState != CPU_THREAD_SHUTDOWN) - { - CPU_WaitStatus(cpuThreadCond, &CPU_HasPendingAction); - switch (cpuThreadState) { - case CPU_THREAD_EXECUTE: - mipsr4k.RunLoopUntil(cpuThreadUntil); - CPU_NextState(CPU_THREAD_EXECUTE, CPU_THREAD_RUNNING); - break; - - // These are fine, just keep looping. - case CPU_THREAD_RUNNING: - case CPU_THREAD_SHUTDOWN: - break; - - case CPU_THREAD_QUIT: - // Just leave the thread, CPU is switching off thread. - CPU_SetState(CPU_THREAD_NOT_RUNNING); - return; - - default: - ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState); - // Begin shutdown, otherwise we'd just spin on this bad state. - CPU_SetState(CPU_THREAD_SHUTDOWN); - break; - } - } - - if (coreState != CORE_ERROR) { - coreState = CORE_POWERDOWN; - } - - CPU_Shutdown(); - CPU_SetState(CPU_THREAD_NOT_RUNNING); -} - void Core_UpdateState(CoreState newState) { if ((coreState == CORE_RUNNING || coreState == CORE_NEXTFRAME) && newState != CORE_RUNNING) coreStatePending = true; @@ -384,11 +288,6 @@ void Core_UpdateDebugStats(bool collectStats) { gpuStats.ResetFrame(); } -void System_Wake() { - // Ping the threads so they check coreState. - CPU_NextStateNot(CPU_THREAD_NOT_RUNNING, CPU_THREAD_SHUTDOWN); -} - // Ugly! static bool pspIsInited = false; static bool pspIsIniting = false; @@ -414,18 +313,9 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { } coreParameter.errorString = ""; pspIsIniting = true; + PSP_SetLoading("Loading game..."); - // Keeping this around because we might need it in the future. - const bool separateCPUThread = false; - if (separateCPUThread) { - Core_ListenShutdown(System_Wake); - CPU_SetState(CPU_THREAD_PENDING); - cpuThread = new std::thread(&CPU_RunLoop); - cpuThreadID = cpuThread->get_id(); - cpuThread->detach(); - } else { - CPU_Init(); - } + CPU_Init(); *error_string = coreParameter.errorString; bool success = coreParameter.fileToStart != ""; @@ -447,6 +337,7 @@ bool PSP_InitUpdate(std::string *error_string) { bool success = coreParameter.fileToStart != ""; *error_string = coreParameter.errorString; if (success && gpu == nullptr) { + PSP_SetLoading("Starting graphics..."); success = GPU_Init(coreParameter.graphicsContext, coreParameter.thin3d); if (!success) { PSP_Shutdown(); @@ -461,11 +352,6 @@ bool PSP_InitUpdate(std::string *error_string) { bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { PSP_InitStart(coreParam, error_string); - // For a potential resurrection of separate CPU thread later. - if (false) { - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); - } - while (!PSP_InitUpdate(error_string)) sleep_ms(10); return pspIsInited; @@ -496,15 +382,7 @@ void PSP_Shutdown() { if (coreState == CORE_RUNNING) Core_UpdateState(CORE_ERROR); Core_NotifyShutdown(); - if (cpuThread != nullptr) { - CPU_NextStateNot(CPU_THREAD_NOT_RUNNING, CPU_THREAD_SHUTDOWN); - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown); - delete cpuThread; - cpuThread = 0; - cpuThreadID = std::thread::id(); - } else { - CPU_Shutdown(); - } + CPU_Shutdown(); GPU_Shutdown(); g_paramSFO.Clear(); host->SetWindowTitle(0); @@ -534,45 +412,7 @@ void PSP_RunLoopUntil(u64 globalticks) { return; } - // We no longer allow a separate CPU thread but if we add a render queue - // to GL we're gonna need it. - bool useCPUThread = false; - if (useCPUThread && cpuThread == nullptr) { - // Need to start the cpu thread. - Core_ListenShutdown(System_Wake); - CPU_SetState(CPU_THREAD_RESUME); - cpuThread = new std::thread(&CPU_RunLoop); - cpuThreadID = cpuThread->get_id(); - cpuThread->detach(); - // Probably needs to tell the gpu that it will need to queue up its output - // on another thread. - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); - } else if (!useCPUThread && cpuThread != nullptr) { - CPU_SetState(CPU_THREAD_QUIT); - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown); - delete cpuThread; - cpuThread = nullptr; - cpuThreadID = std::thread::id(); - } - - if (cpuThread != nullptr) { - cpuThreadUntil = globalticks; - if (CPU_NextState(CPU_THREAD_RUNNING, CPU_THREAD_EXECUTE)) { - // The CPU doesn't actually respect cpuThreadUntil well, especially when skipping frames. - // TODO: Something smarter? Or force CPU to bail periodically? - while (!CPU_IsReady()) { - // Have the GPU do stuff here. - if (coreState != CORE_RUNNING) { - CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); - } - } - } else { - ERROR_LOG(CPU, "Unable to execute CPU run loop, unexpected state: %d", cpuThreadState); - } - } else { - mipsr4k.RunLoopUntil(globalticks); - } - + mipsr4k.RunLoopUntil(globalticks); gpu->CleanupBeforeUI(); } @@ -580,6 +420,16 @@ void PSP_RunLoopFor(int cycles) { PSP_RunLoopUntil(CoreTiming::GetTicks() + cycles); } +void PSP_SetLoading(const std::string &reason) { + std::lock_guard guard(loadingReasonLock); + loadingReason = reason; +} + +std::string PSP_GetLoading() { + std::lock_guard guard(loadingReasonLock); + return loadingReason; +} + CoreParameter &PSP_CoreParameter() { return coreParameter; } diff --git a/Core/System.h b/Core/System.h index 9cc4cfdc89..a2a3ed5c48 100644 --- a/Core/System.h +++ b/Core/System.h @@ -73,13 +73,14 @@ void PSP_EndHostFrame(); void PSP_RunLoopUntil(u64 globalticks); void PSP_RunLoopFor(int cycles); +void PSP_SetLoading(const std::string &reason); +std::string PSP_GetLoading(); + // Call before PSP_BeginHostFrame() in order to not miss any GPU stats. void Core_UpdateDebugStats(bool collectStats); void Audio_Init(); void Audio_Shutdown(); - -bool IsOnSeparateCPUThread(); bool IsAudioInitialised(); void UpdateLoadedFile(FileLoader *fileLoader); diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 4ea75b7d16..663c782dfd 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -50,18 +50,6 @@ DrawEngineCommon::~DrawEngineCommon() { }); } -void DrawEngineCommon::SetupVertexDecoder(u32 vertType) { - // As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it - // into the top of the verttype where there are unused bits. - const u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24); - - // If vtype has changed, setup the vertex decoder. - if (vertTypeID != lastVType_) { - dec_ = GetVertexDecoder(vertTypeID); - lastVType_ = vertTypeID; - } -} - VertexDecoder *DrawEngineCommon::GetVertexDecoder(u32 vtype) { VertexDecoder *dec = decoderMap_.Get(vtype); if (dec) @@ -105,7 +93,7 @@ int DrawEngineCommon::ComputeNumVertsToDecode() const { void DrawEngineCommon::DecodeVerts(u8 *dest) { const UVScale origUV = gstate_c.uv; for (; decodeCounter_ < numDrawCalls; decodeCounter_++) { - gstate_c.uv = uvScale[decodeCounter_]; + gstate_c.uv = drawCalls[decodeCounter_].uvScale; DecodeVertsStep(dest, decodeCounter_, decodedVerts_); // NOTE! DecodeVertsStep can modify decodeCounter_! } gstate_c.uv = origUV; @@ -330,11 +318,12 @@ bool DrawEngineCommon::GetCurrentSimpleVertices(int count, std::vectorDecodeVerts(bufPtr, inPtr, lowerBound, upperBound); - // OK, morphing eliminated but bones still remain to be taken care of. - // Let's do a partial software transform where we only do skinning. - VertexReader reader(bufPtr, dec->GetDecVtxFmt(), vertType); SimpleVertex *sverts = (SimpleVertex *)outPtr; @@ -408,56 +393,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, (u8)gstate.getMaterialAmbientA(), }; - // Let's have two separate loops, one for non skinning and one for skinning. - if (!g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE) { - int numBoneWeights = vertTypeGetNumBoneWeights(vertType); - for (int i = lowerBound; i <= upperBound; i++) { - reader.Goto(i - lowerBound); - SimpleVertex &sv = sverts[i]; - if (vertType & GE_VTYPE_TC_MASK) { - reader.ReadUV(sv.uv); - } - - if (vertType & GE_VTYPE_COL_MASK) { - reader.ReadColor0_8888(sv.color); - } else { - memcpy(sv.color, defaultColor, 4); - } - - float nrm[3], pos[3]; - float bnrm[3], bpos[3]; - - if (vertType & GE_VTYPE_NRM_MASK) { - // Normals are generated during tessellation anyway, not sure if any need to supply - reader.ReadNrm(nrm); - } else { - nrm[0] = 0; - nrm[1] = 0; - nrm[2] = 1.0f; - } - reader.ReadPos(pos); - - // Apply skinning transform directly - float weights[8]; - reader.ReadWeights(weights); - // Skinning - Vec3Packedf psum(0, 0, 0); - Vec3Packedf nsum(0, 0, 0); - for (int w = 0; w < numBoneWeights; w++) { - if (weights[w] != 0.0f) { - Vec3ByMatrix43(bpos, pos, gstate.boneMatrix + w * 12); - Vec3Packedf tpos(bpos); - psum += tpos * weights[w]; - - Norm3ByMatrix43(bnrm, nrm, gstate.boneMatrix + w * 12); - Vec3Packedf tnorm(bnrm); - nsum += tnorm * weights[w]; - } - } - sv.pos = psum; - sv.nrm = nsum; - } - } else { + { for (int i = lowerBound; i <= upperBound; i++) { reader.Goto(i - lowerBound); SimpleVertex &sv = sverts[i]; @@ -665,6 +601,70 @@ ReliableHashType DrawEngineCommon::ComputeHash() { } } - fullhash += DoReliableHash(&uvScale[0], sizeof(uvScale[0]) * numDrawCalls, 0x0123e658); + fullhash += DoReliableHash(&drawCalls[0].uvScale, sizeof(drawCalls[0].uvScale) * numDrawCalls, 0x0123e658); return fullhash; } + +// vertTypeID is the vertex type but with the UVGen mode smashed into the top bits. +void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) { + if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) { + DispatchFlush(); + } + + // TODO: Is this the right thing to do? + if (prim == GE_PRIM_KEEP_PREVIOUS) { + prim = prevPrim_ != GE_PRIM_INVALID ? prevPrim_ : GE_PRIM_POINTS; + } else { + prevPrim_ = prim; + } + + // If vtype has changed, setup the vertex decoder. + if (vertTypeID != lastVType_) { + dec_ = GetVertexDecoder(vertTypeID); + lastVType_ = vertTypeID; + } + + *bytesRead = vertexCount * dec_->VertexSize(); + if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) + return; + + if (g_Config.bVertexCache) { + u32 dhash = dcid_; + dhash = __rotl(dhash ^ (u32)(uintptr_t)verts, 13); + dhash = __rotl(dhash ^ (u32)(uintptr_t)inds, 13); + dhash = __rotl(dhash ^ (u32)vertTypeID, 13); + dhash = __rotl(dhash ^ (u32)vertexCount, 13); + dcid_ = dhash ^ (u32)prim; + } + + DeferredDrawCall &dc = drawCalls[numDrawCalls]; + dc.verts = verts; + dc.inds = inds; + dc.indexType = (vertTypeID & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; + dc.prim = prim; + dc.vertexCount = vertexCount; + dc.uvScale = gstate_c.uv; + + if (inds) { + GetIndexBounds(inds, vertexCount, vertTypeID, &dc.indexLowerBound, &dc.indexUpperBound); + } else { + dc.indexLowerBound = 0; + dc.indexUpperBound = vertexCount - 1; + } + + numDrawCalls++; + vertexCountInDrawCalls_ += vertexCount; + + if (vertTypeID & GE_VTYPE_WEIGHT_MASK) { + DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); + decodeCounter_++; + } + + if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { + // Rendertarget == texture? + if (!g_Config.bDisableSlowFramebufEffects) { + gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); + DispatchFlush(); + } + } +} diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 961e5dad5e..d3c64d2227 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -44,6 +44,12 @@ typedef u64 ReliableHashType; typedef u32 ReliableHashType; #endif +inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) { + // As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it + // into the top of the verttype where there are unused bits. + return (vertType & 0xFFFFFF) | (uvGenMode << 24); +} + class DrawEngineCommon { public: DrawEngineCommon(); @@ -56,10 +62,17 @@ public: // Flush is normally non-virtual but here's a virtual way to call it, used by the shared spline code, which is expensive anyway. // Not really sure if these wrappers are worth it... virtual void DispatchFlush() = 0; - // Same for SubmitPrim - virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) = 0; + + // This would seem to be unnecessary now, but is still required for splines/beziers to work in the software backend since SubmitPrim + // is different. Should probably refactor that. + // Note that vertTypeID should be computed using GetVertTypeID(). + virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) { + SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, bytesRead); + } bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead); + + void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead); void SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); @@ -68,11 +81,14 @@ public: virtual void Resized(); - void SetupVertexDecoder(u32 vertType); - bool IsCodePtrVertexDecoder(const u8 *ptr) const { return decJitCache_->IsInSpace(ptr); } + int GetNumDrawCalls() const { + return numDrawCalls; + } + + VertexDecoder *GetVertexDecoder(u32 vtype); protected: virtual void ClearTrackedVertexArrays() {} @@ -92,8 +108,6 @@ protected: bool ApplyShaderBlending(); - VertexDecoder *GetVertexDecoder(u32 vtype); - inline int IndexSize(u32 vtype) const { const u32 indexType = (vtype & GE_VTYPE_IDX_MASK); if (indexType == GE_VTYPE_IDX_16BIT) { @@ -119,23 +133,22 @@ protected: TransformedVertex *transformed = nullptr; TransformedVertex *transformedExpanded = nullptr; - // Defer all vertex decoding to a "Flush" (except when software skinning) + // Defer all vertex decoding to a "Flush" (except when skinning) struct DeferredDrawCall { void *verts; void *inds; - u32 vertType; u8 indexType; s8 prim; - u32 vertexCount; + u16 vertexCount; u16 indexLowerBound; u16 indexUpperBound; + UVScale uvScale; }; enum { MAX_DEFERRED_DRAW_CALLS = 128 }; DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS]; int numDrawCalls = 0; int vertexCountInDrawCalls_ = 0; - UVScale uvScale[MAX_DEFERRED_DRAW_CALLS]; int decimationCounter_ = 0; int decodeCounter_ = 0; @@ -170,6 +183,7 @@ protected: colStride = 4; } virtual void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) = 0; + virtual void EndFrame() {} }; TessellationDataTransfer *tessDataTransfer; }; diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 20093b8c64..05cfed1a31 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -210,8 +210,6 @@ void FramebufferManagerCommon::SetNumExtraFBOs(int num) { extraFBOs_.push_back(fbo); } currentRenderVfb_ = 0; - if (num != 0) - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); } // Heuristics to figure out the size of FBO to create. @@ -610,6 +608,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // performance-crushing framebuffer reloads from RAM, but we'll have to live with that. if (vfb->last_frame_render != gpuStats.numFlips) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + // GLES resets the blend state on clears. + gstate_c.Dirty(DIRTY_BLEND_STATE); } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); } @@ -692,7 +692,6 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) { FlushBeforeCopy(); if (useBufferedRendering_ && vfb->fbo) { - DisableState(); GEBufferFormat fmt = vfb->format; if (vfb->last_frame_render + 1 < gpuStats.numFlips && isDisplayBuf) { // If we're not rendering to it, format may be wrong. Use displayFormat_ instead. @@ -720,8 +719,6 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int float u0 = 0.0f, u1 = 1.0f; float v0 = 0.0f, v1 = 1.0f; - MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height, u1, v1); - if (useBufferedRendering_ && vfb && vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); @@ -735,7 +732,8 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int SetViewport2D(x, y, w, h); draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); } - DisableState(); + + MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height, u1, v1); DrawTextureFlags flags = (vfb || g_Config.iBufFilter == SCALE_LINEAR) ? DRAWTEX_LINEAR : DRAWTEX_NEAREST; Bind2DShader(); @@ -777,8 +775,6 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu float v0 = 0.0f, v1 = 1.0f; MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272, u1, v1); - DisableState(); - struct CardboardSettings cardboardSettings; GetCardboardSettings(&cardboardSettings); @@ -853,6 +849,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { if (useBufferedRendering_) { draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); } + gstate_c.Dirty(DIRTY_BLEND_STATE); return; } @@ -922,6 +919,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { SetViewport2D(0, 0, pixelWidth_, pixelHeight_); draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); DrawFramebufferToOutput(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true); + gstate_c.Dirty(DIRTY_BLEND_STATE); return; } } else { @@ -931,6 +929,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); } + gstate_c.Dirty(DIRTY_BLEND_STATE); return; } } @@ -950,7 +949,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { if (vfb->fbo) { DEBUG_LOG(FRAMEBUF, "Displaying FBO %08x", vfb->fb_address); - DisableState(); int uvRotation = useBufferedRendering_ ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; @@ -995,7 +993,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { int fbo_w, fbo_h; draw_->GetFramebufferDimensions(extraFBOs_[0], &fbo_w, &fbo_h); SetViewport2D(0, 0, fbo_w, fbo_h); - draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); + draw_->SetScissorRect(0, 0, fbo_w, fbo_h); shaderManager_->DirtyLastShader(); // dirty lastShader_ PostShaderUniforms uniforms{}; CalculatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, renderWidth_, renderHeight_, &uniforms); @@ -1003,8 +1001,8 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { DrawTextureFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST; DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, flags); + draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); - SetViewport2D(0, 0, pixelWidth_, pixelHeight_); // Use the extra FBO, with applied post-processing shader, as a texture. // fbo_bind_as_texture(extraFBOs_[0], FB_COLOR_BIT, 0); @@ -1033,13 +1031,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags); } - - /* - if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { - draw_->BindFramebufferAsRenderTarget(extraFBOs_[0], { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); - GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; - glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); - }*/ } else { draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0); @@ -1072,6 +1063,9 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { else if (useBufferedRendering_) { WARN_LOG(FRAMEBUF, "Current VFB lacks an FBO: %08x", vfb->fb_address); } + + // This may get called mid-draw if the game uses an immediate flip. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE); } void FramebufferManagerCommon::DecimateFBOs() { @@ -1193,6 +1187,8 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); if (vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + // GLES resets the blend state on clears. + gstate_c.Dirty(DIRTY_BLEND_STATE); if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) { BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0); } @@ -1203,6 +1199,8 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + // GLES resets the blend state on clears. + gstate_c.Dirty(DIRTY_BLEND_STATE); } if (!vfb->fbo) { @@ -1356,9 +1354,10 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst const u32 byteOffset = dstBasePtr - vfb_address; const u32 byteStride = dstStride * bpp; const u32 yOffset = byteOffset / byteStride; + // Some games use mismatching bitdepths. But make sure the stride matches. // If it doesn't, generally this means we detected the framebuffer with too large a height. - bool match = yOffset < dstYOffset; + bool match = yOffset < dstYOffset && (int)yOffset <= (int)vfb->height - dstHeight; if (match && vfb_byteStride != byteStride) { // Grand Knights History copies with a mismatching stride but a full line at a time. // Makes it hard to detect the wrong transfers in e.g. God of War. @@ -1388,7 +1387,7 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst const u32 byteOffset = srcBasePtr - vfb_address; const u32 byteStride = srcStride * bpp; const u32 yOffset = byteOffset / byteStride; - bool match = yOffset < srcYOffset; + bool match = yOffset < srcYOffset && (int)yOffset <= (int)vfb->height - srcHeight; if (match && vfb_byteStride != byteStride) { if (width != srcStride || (byteStride * height != vfb_byteStride && byteStride * height != vfb_byteWidth)) { match = false; @@ -1938,9 +1937,8 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB buffer.Allocate(w, h, GE_FORMAT_8888, flipY, true); bool retval = draw_->CopyFramebufferToMemorySync(bound, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w); gpuStats.numReadbacks++; - // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. - // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); + // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // We may have blitted to a temp FBO. RebindFramebuffer(); return retval; @@ -1974,6 +1972,8 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 } // No need to free on failure, that's the caller's job (it likely will reuse a buffer.) bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w); + // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. RebindFramebuffer(); return retval; @@ -2044,6 +2044,10 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int DEBUG_LOG(G3D, "Reading framebuffer to mem, fb_address = %08x", fb_address); draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride); + + // A new command buffer will begin after CopyFrameBufferToMemorySync, so we need to trigger + // updates of any dynamic command buffer state by dirtying some stuff. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); gpuStats.numReadbacks++; } diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 78005a1126..b6febf7fa3 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -150,6 +150,7 @@ enum DrawTextureFlags { DRAWTEX_NEAREST = 0, DRAWTEX_LINEAR = 1, DRAWTEX_KEEP_TEX = 2, + DRAWTEX_KEEP_STENCIL_ALPHA = 4, }; inline Draw::DataFormat GEFormatToThin3D(int geFormat) { @@ -206,7 +207,7 @@ public: return vfb; } } - virtual void RebindFramebuffer(); + void RebindFramebuffer(); std::vector GetFramebufferList(); void CopyDisplayToOutput(); @@ -222,9 +223,9 @@ public: bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); - virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h); + void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h); - virtual void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); + void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader); void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); @@ -312,7 +313,6 @@ protected: bool UpdateSize(); void SetNumExtraFBOs(int num); - virtual void DisableState() = 0; void FlushBeforeCopy(); virtual void DecimateFBOs(); // keeping it virtual to let D3D do a little extra diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index fa69f91f08..586101a611 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -577,17 +577,11 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo // This is a bit of a hack as the render buffer isn't always that size // We always scissor on non-buffered so that clears don't spill outside the frame. - if (useBufferedRendering && scissorX1 == 0 && scissorY1 == 0 - && scissorX2 >= (int)gstate_c.curRTWidth - && scissorY2 >= (int)gstate_c.curRTHeight) { - out.scissorEnable = false; - } else { - out.scissorEnable = true; - out.scissorX = renderX + displayOffsetX + scissorX1 * renderWidthFactor; - out.scissorY = renderY + displayOffsetY + scissorY1 * renderHeightFactor; - out.scissorW = (scissorX2 - scissorX1) * renderWidthFactor; - out.scissorH = (scissorY2 - scissorY1) * renderHeightFactor; - } + out.scissorEnable = true; + out.scissorX = renderX + displayOffsetX + scissorX1 * renderWidthFactor; + out.scissorY = renderY + displayOffsetY + scissorY1 * renderHeightFactor; + out.scissorW = (scissorX2 - scissorX1) * renderWidthFactor; + out.scissorH = (scissorY2 - scissorY1) * renderHeightFactor; int curRTWidth = gstate_c.curRTWidth; int curRTHeight = gstate_c.curRTHeight; diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index e82badf2df..0022945689 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -78,14 +78,8 @@ enum : uint64_t { DIRTY_WORLDMATRIX = 1ULL << 21, DIRTY_VIEWMATRIX = 1ULL << 22, DIRTY_TEXMATRIX = 1ULL << 23, - DIRTY_BONEMATRIX0 = 1ULL << 24, // NOTE: These must be under 32 - DIRTY_BONEMATRIX1 = 1ULL << 25, - DIRTY_BONEMATRIX2 = 1ULL << 26, - DIRTY_BONEMATRIX3 = 1ULL << 27, - DIRTY_BONEMATRIX4 = 1ULL << 28, - DIRTY_BONEMATRIX5 = 1ULL << 29, - DIRTY_BONEMATRIX6 = 1ULL << 30, - DIRTY_BONEMATRIX7 = 1ULL << 31, + + // 8 free bits here where bones used to be! // These are for hardware tessellation DIRTY_BEZIERSPLINE = 1ULL << 32, @@ -93,8 +87,6 @@ enum : uint64_t { // space for 7 more uniforms. - DIRTY_BONE_UNIFORMS = 0xFF000000ULL, - DIRTY_ALL_UNIFORMS = 0x3FFFFFFFFULL, DIRTY_ALL_LIGHTS = DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3, diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 3a8f0de37e..7fcc34fd14 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -33,7 +33,6 @@ std::string VertexShaderDesc(const ShaderID &id) { int ls1 = id.Bits(VS_BIT_LS1, 2); if (uvgMode) desc << uvgModes[uvgMode]; - if (id.Bit(VS_BIT_ENABLE_BONES)) desc << "Bones:" << (id.Bits(VS_BIT_BONES, 3) + 1) << " "; // Lights if (id.Bit(VS_BIT_LIGHTING_ENABLE)) { desc << "Light: "; @@ -46,7 +45,6 @@ std::string VertexShaderDesc(const ShaderID &id) { } } if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc << "MatUp:" << id.Bits(VS_BIT_MATERIAL_UPDATE, 3) << " "; - if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " "; if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat "; if (id.Bit(VS_BIT_BEZIER)) desc << "Bezier "; @@ -103,16 +101,6 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) id.SetBits(VS_BIT_LS1, 2, gstate.getUVLS1()); } - // Bones. - bool enableBones = vertTypeIsSkinningEnabled(vertType); - id.SetBit(VS_BIT_ENABLE_BONES, enableBones); - if (enableBones) { - id.SetBits(VS_BIT_BONES, 3, TranslateNumBones(vertTypeGetNumBoneWeights(vertType)) - 1); - // 2 bits. We should probably send in the weight scalefactor as a uniform instead, - // or simply preconvert all weights to floats. - id.SetBits(VS_BIT_WEIGHT_FMTSCALE, 2, (vertType & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT); - } - // Okay, d[1] coming up. ============== if (gstate.isLightingEnabled() || doShadeMapping) { // doShadeMapping is stored as UVGenMode, so this is enough for isLightingEnabled. diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index afc7c51313..7606010b7e 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -7,7 +7,6 @@ // TODO: There will be additional bits, indicating that groups of these will be // sent to the shader and processed there. This will cut down the number of shaders ("ubershader approach") -// This is probably only really worth doing for lighting and bones. enum { VS_BIT_LMODE = 0, VS_BIT_IS_THROUGH = 1, @@ -29,10 +28,7 @@ enum { VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS0 VS_BIT_LS0 = 18, // 2 VS_BIT_LS1 = 20, // 2 - VS_BIT_BONES = 22, // 3 should be enough, not 8 - // 25 - 29 are free. - VS_BIT_ENABLE_BONES = 30, - // 31 is free. + // 22 - 31 are free. VS_BIT_LIGHT0_COMP = 32, // 2 bits VS_BIT_LIGHT0_TYPE = 34, // 2 bits VS_BIT_LIGHT1_COMP = 36, // 2 bits @@ -48,8 +44,7 @@ enum { VS_BIT_LIGHT2_ENABLE = 54, VS_BIT_LIGHT3_ENABLE = 55, VS_BIT_LIGHTING_ENABLE = 56, - VS_BIT_WEIGHT_FMTSCALE = 57, // only two bits - // 59 - 61 are free. + // 57 - 61 are free. VS_BIT_FLATSHADE = 62, // 1 bit VS_BIT_BEZIER = 63, // 1 bit // No more free diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 78a1dfeb9a..30d94cc737 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -262,19 +262,11 @@ void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms) { } ExpandFloat24x3ToFloat4(ub->ldir[i], &gstate.ldir[i * 3]); ExpandFloat24x3ToFloat4(ub->latt[i], &gstate.latt[i * 3]); - CopyFloat1To4(ub->lightAngle[i], getFloat24(gstate.lcutoff[i])); - CopyFloat1To4(ub->lightSpotCoef[i], getFloat24(gstate.lconv[i])); + float lightAngle_spotCoef[2] = { getFloat24(gstate.lcutoff[i]), getFloat24(gstate.lconv[i]) }; + CopyFloat2To4(ub->lightAngle_SpotCoef[i], lightAngle_spotCoef); Uint8x3ToFloat4(ub->lightAmbient[i], gstate.lcolor[i * 3]); Uint8x3ToFloat4(ub->lightDiffuse[i], gstate.lcolor[i * 3 + 1]); Uint8x3ToFloat4(ub->lightSpecular[i], gstate.lcolor[i * 3 + 2]); } } } - -void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms) { - for (int i = 0; i < 8; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To3x4Transposed(ub->bones[i], gstate.boneMatrix + 12 * i); - } - } -} diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index 8cd22953b9..726b1a5762 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -98,7 +98,8 @@ R"( float4x4 u_proj; float2 u_texclampoff; )"; -// 576 bytes. Can we get down to 512? +// 512 bytes. Would like to shrink more. Some colors only have 8-bit precision and we expand +// them to float unnecessarily, could just as well expand in the shader. struct UB_VS_Lights { float ambientColor[4]; float materialDiffuse[4]; @@ -107,8 +108,7 @@ struct UB_VS_Lights { float lpos[4][4]; float ldir[4][4]; float latt[4][4]; - float lightAngle[4][4]; // TODO: Merge with lightSpotCoef, use .xy - float lightSpotCoef[4][4]; + float lightAngle_SpotCoef[4][4]; // TODO: Merge with lightSpotCoef, use .xy float lightAmbient[4][4]; float lightDiffuse[4][4]; float lightSpecular[4][4]; @@ -122,8 +122,7 @@ R"( vec4 u_ambient; vec3 pos[4]; vec3 dir[4]; vec3 att[4]; - float angle[4]; - float spotCoef[4]; + vec2 angle_spotCoef[4]; vec3 ambient[4]; vec3 diffuse[4]; vec3 specular[4]; @@ -147,14 +146,10 @@ R"( float4 u_ambient; float3 u_lightatt1; float3 u_lightatt2; float3 u_lightatt3; - float4 u_lightangle0; - float4 u_lightangle1; - float4 u_lightangle2; - float4 u_lightangle3; - float4 u_lightspotCoef0; - float4 u_lightspotCoef1; - float4 u_lightspotCoef2; - float4 u_lightspotCoef3; + float4 u_lightangle_spotCoef0; + float4 u_lightangle_spotCoef1; + float4 u_lightangle_spotCoef2; + float4 u_lightangle_spotCoef3; float3 u_lightambient0; float3 u_lightambient1; float3 u_lightambient2; @@ -169,24 +164,8 @@ R"( float4 u_ambient; float3 u_lightspecular3; )"; -// With some cleverness, we could get away with uploading just half this when only the four or five first -// bones are being used. This is 512b, 256b would be great. -struct UB_VS_Bones { - float bones[8][12]; -}; - -static const char *ub_vs_bonesStr = -R"( mat3x4 m[8]; -)"; - -// HLSL code is shared so these names are changed to match those in DX9. -static const char *cb_vs_bonesStr = -R"( float4x3 u_bone[8]; -)"; - void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport); void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms); -void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms); // Shared helper functions void ComputeGuardband(float gb[4], float zmin); diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index a29c987c11..5ebf13570c 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -144,8 +144,6 @@ void SoftwareTransform( vscale /= gstate_c.curTextureHeight; } - bool skinningEnabled = vertTypeIsSkinningEnabled(vertType); - const int w = gstate.getTextureWidth(0); const int h = gstate.getTextureHeight(0); float widthFactor = (float) w / (float) gstate_c.curTextureWidth; @@ -213,48 +211,14 @@ void SoftwareTransform( Vec3f worldnormal(0, 0, 1); reader.ReadPos(pos); - if (!skinningEnabled) { - Vec3ByMatrix43(out, pos, gstate.worldMatrix); - if (reader.hasNormal()) { - reader.ReadNrm(normal.AsArray()); - if (gstate.areNormalsReversed()) { - normal = -normal; - } - Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); - worldnormal = worldnormal.Normalized(); - } - } else { - float weights[8]; - reader.ReadWeights(weights); - if (reader.hasNormal()) - reader.ReadNrm(normal.AsArray()); - - // Skinning - Vec3f psum(0, 0, 0); - Vec3f nsum(0, 0, 0); - for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) { - if (weights[i] != 0.0f) { - Vec3ByMatrix43(out, pos, gstate.boneMatrix+i*12); - Vec3f tpos(out); - psum += tpos * weights[i]; - if (reader.hasNormal()) { - Vec3f norm; - Norm3ByMatrix43(norm.AsArray(), normal.AsArray(), gstate.boneMatrix+i*12); - nsum += norm * weights[i]; - } - } - } - - // Yes, we really must multiply by the world matrix too. - Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix); - if (reader.hasNormal()) { - normal = nsum; - if (gstate.areNormalsReversed()) { - normal = -normal; - } - Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); - worldnormal = worldnormal.Normalized(); + Vec3ByMatrix43(out, pos, gstate.worldMatrix); + if (reader.hasNormal()) { + reader.ReadNrm(normal.AsArray()); + if (gstate.areNormalsReversed()) { + normal = -normal; } + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.Normalized(); } // Perform lighting here if enabled. don't need to check through, it's checked above. diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 8e428b695e..41eb4aec93 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -949,8 +949,10 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi gstate_c.uv.vOff = 0.0f; } + uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode()); + int generatedBytesRead; - DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeWithIndex16, &generatedBytesRead); + DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeID, &generatedBytesRead); DispatchFlush(); @@ -1091,8 +1093,9 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi gstate_c.uv.vOff = 0; } + uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode()); int generatedBytesRead; - DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeWithIndex16, &generatedBytesRead); + DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeID, &generatedBytesRead); DispatchFlush(); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 2d607abf62..05527790ac 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -47,6 +47,10 @@ #define TEXTURE_KILL_AGE_LOWMEM 60 // Not used in lowmem mode. #define TEXTURE_SECOND_KILL_AGE 100 +// Used when there are multiple CLUT variants of a texture. +#define TEXTURE_KILL_AGE_CLUT 6 + +#define TEXTURE_CLUT_VARIANTS_MIN 6 // Try to be prime to other decimation intervals. #define TEXCACHE_DECIMATION_INTERVAL 13 @@ -384,7 +388,7 @@ void TextureCacheCommon::SetTexture(bool force) { // Exponential backoff up to 512 frames. Textures are often reused. if (entry->numFrames > 32) { // Also, try to add some "randomness" to avoid rehashing several textures the same frame. - entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (entry->textureName & 15); + entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (((intptr_t)(entry->textureName) >> 12) & 15); } else { entry->framesUntilNextFullHash = entry->numFrames; } @@ -455,6 +459,24 @@ void TextureCacheCommon::SetTexture(bool force) { entry->status = TexCacheEntry::STATUS_UNRELIABLE; } + if (hasClut && clutRenderAddress_ == 0xFFFFFFFF) { + const u64 cachekeyMin = (u64)(texaddr & 0x3FFFFFFF) << 32; + const u64 cachekeyMax = cachekeyMin + (1ULL << 32); + + int found = 0; + for (auto it = cache_.lower_bound(cachekeyMin), end = cache_.upper_bound(cachekeyMax); it != end; ++it) { + found++; + } + + if (found >= TEXTURE_CLUT_VARIANTS_MIN) { + for (auto it = cache_.lower_bound(cachekeyMin), end = cache_.upper_bound(cachekeyMax); it != end; ++it) { + it->second->status |= TexCacheEntry::STATUS_CLUT_VARIANTS; + } + + entry->status |= TexCacheEntry::STATUS_CLUT_VARIANTS; + } + } + nextNeedsChange_ = false; } @@ -506,8 +528,10 @@ void TextureCacheCommon::Decimate() { const u32 had = cacheSizeEstimate_; ForgetLastTexture(); - int killAge = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE; + int killAgeBase = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE; for (TexCache::iterator iter = cache_.begin(); iter != cache_.end(); ) { + bool hasClut = (iter->second->status & TexCacheEntry::STATUS_CLUT_VARIANTS) != 0; + int killAge = hasClut ? TEXTURE_KILL_AGE_CLUT : killAgeBase; if (iter->second->lastFrame + killAge < gpuStats.numFlips) { DeleteTexture(iter++); } else { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 1c13df9c75..970f1d8ea9 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -87,6 +87,8 @@ struct SamplerCacheKey { } }; +class GLRTexture; + // TODO: Shrink this struct. There is some fluff. struct TexCacheEntry { ~TexCacheEntry() { @@ -106,8 +108,7 @@ struct TexCacheEntry { STATUS_ALPHA_FULL = 0x00, // Has no alpha channel, or always full alpha. STATUS_ALPHA_MASK = 0x04, - // 0x08 free. - + STATUS_CLUT_VARIANTS = 0x08, // Has multiple CLUT variants. STATUS_CHANGE_FREQUENT = 0x10, // Changes often (less than 6 frames in between.) STATUS_CLUT_RECHECK = 0x20, // Another texture with same addr had a hashfail. STATUS_DEPALETTIZE = 0x40, // Needs to go through a depalettize pass. @@ -132,7 +133,7 @@ struct TexCacheEntry { u16 dim; u16 bufw; union { - u32 textureName; + GLRTexture *textureName; void *texturePtr; CachedTextureVulkan *vkTex; }; @@ -146,16 +147,8 @@ struct TexCacheEntry { u32 framesUntilNextFullHash; u32 fullhash; u32 cluthash; - float lodBias; u16 maxSeenV; - // Cache the current filter settings so we can avoid setting it again. - // (OpenGL ES 2.0 madness where filter settings are attached to each texture. Unused in other backends). - u8 magFilt; - u8 minFilt; - bool sClamp; - bool tClamp; - TexStatus GetHashStatus() { return TexStatus(status & STATUS_MASK); } diff --git a/GPU/Common/VertexDecoderArm.cpp b/GPU/Common/VertexDecoderArm.cpp index 1f7d65a833..c7cddcb4de 100644 --- a/GPU/Common/VertexDecoderArm.cpp +++ b/GPU/Common/VertexDecoderArm.cpp @@ -111,9 +111,6 @@ static const ARMReg srcNEON = Q2; static const ARMReg accNEON = Q3; static const JitLookup jitLookup[] = { - {&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8}, - {&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16}, - {&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat}, {&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin}, {&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin}, {&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin}, @@ -232,7 +229,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int // Add code to convert matrices to 4x4. // Later we might want to do this when the matrices are loaded instead. int boneCount = 0; - if (NEONSkinning && dec.weighttype && g_Config.bSoftwareSkinning && dec.morphcount == 1) { + if (NEONSkinning && dec.weighttype) { // Copying from R3 to R4 MOVP2R(R3, gstate.boneMatrix); MOVP2R(R4, bones); @@ -326,55 +323,6 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int return (JittedVertexDecoder)start; } -void VertexDecoderJitCache::Jit_WeightsU8() { - // Basic implementation - a byte at a time. TODO: Optimize - int j; - for (j = 0; j < dec_->nweights; j++) { - LDRB(tempReg1, srcReg, dec_->weightoff + j); - STRB(tempReg1, dstReg, dec_->decFmt.w0off + j); - } - if (j & 3) { - // Create a zero register. Might want to make a fixed one. - EOR(scratchReg, scratchReg, scratchReg); - } - while (j & 3) { - STRB(scratchReg, dstReg, dec_->decFmt.w0off + j); - j++; - } -} - -void VertexDecoderJitCache::Jit_WeightsU16() { - // Basic implementation - a short at a time. TODO: Optimize - int j; - for (j = 0; j < dec_->nweights; j++) { - LDRH(tempReg1, srcReg, dec_->weightoff + j * 2); - STRH(tempReg1, dstReg, dec_->decFmt.w0off + j * 2); - } - if (j & 3) { - // Create a zero register. Might want to make a fixed one. - EOR(scratchReg, scratchReg, scratchReg); - } - while (j & 3) { - STRH(scratchReg, dstReg, dec_->decFmt.w0off + j * 2); - j++; - } -} - -void VertexDecoderJitCache::Jit_WeightsFloat() { - int j; - for (j = 0; j < dec_->nweights; j++) { - LDR(tempReg1, srcReg, dec_->weightoff + j * 4); - STR(tempReg1, dstReg, dec_->decFmt.w0off + j * 4); - } - if (j & 3) { - EOR(tempReg1, tempReg1, tempReg1); - } - while (j & 3) { // Zero additional weights rounding up to 4. - STR(tempReg1, dstReg, dec_->decFmt.w0off + j * 4); - j++; - } -} - static const ARMReg weightRegs[8] = { S8, S9, S10, S11, S12, S13, S14, S15 }; static const ARMReg neonWeightRegsD[4] = { D4, D5, D6, D7 }; static const ARMReg neonWeightRegsQ[2] = { Q2, Q3 }; diff --git a/GPU/Common/VertexDecoderArm64.cpp b/GPU/Common/VertexDecoderArm64.cpp index aab6b4ca36..3c87a6b677 100644 --- a/GPU/Common/VertexDecoderArm64.cpp +++ b/GPU/Common/VertexDecoderArm64.cpp @@ -85,9 +85,6 @@ static const ARM64Reg neonWeightRegsQ[2] = { Q3, Q2 }; // reverse order to prev // Q16+ are free-for-all for matrices. In 16 registers, we can fit 4 4x4 matrices. static const JitLookup jitLookup[] = { - {&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8}, - {&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16}, - {&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat}, {&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin}, {&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin}, {&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin}, @@ -196,7 +193,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int // Add code to convert matrices to 4x4. // Later we might want to do this when the matrices are loaded instead. int boneCount = 0; - if (dec.weighttype && g_Config.bSoftwareSkinning && dec.morphcount == 1) { + if (dec.weighttype) { // Copying from R3 to R4 MOVP2R(X3, gstate.boneMatrix); MOVP2R(X4, bones); @@ -356,44 +353,6 @@ void VertexDecoderJitCache::Jit_ApplyWeights() { } } -void VertexDecoderJitCache::Jit_WeightsU8() { - // Basic implementation - a byte at a time. TODO: Optimize - int j; - for (j = 0; j < dec_->nweights; j++) { - LDRB(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j); - STRB(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j); - } - while (j & 3) { - STRB(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j); - j++; - } -} - -void VertexDecoderJitCache::Jit_WeightsU16() { - // Basic implementation - a short at a time. TODO: Optimize - int j; - for (j = 0; j < dec_->nweights; j++) { - LDRH(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j * 2); - STRH(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j * 2); - } - while (j & 3) { - STRH(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j * 2); - j++; - } -} - -void VertexDecoderJitCache::Jit_WeightsFloat() { - int j; - for (j = 0; j < dec_->nweights; j++) { - LDR(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j * 4); - STR(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j * 4); - } - while (j & 3) { // Zero additional weights rounding up to 4. - STR(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j * 4); - j++; - } -} - void VertexDecoderJitCache::Jit_WeightsU8Skin() { // Weight is first so srcReg is correct. switch (dec_->nweights) { diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index dccd4dccf9..bf0793fe86 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -41,7 +41,7 @@ static const u8 nrmsize[4] = { 0, 3, 6, 12 }, nrmalign[4] = { 0, 1, 2, 4 }; static const u8 possize[4] = { 3, 3, 6, 12 }, posalign[4] = { 1, 1, 2, 4 }; static const u8 wtsize[4] = { 0, 1, 2, 4 }, wtalign[4] = { 0, 1, 2, 4 }; -// When software skinning. This array is only used when non-jitted - when jitted, the matrix +// This array is only used when non-jitted - when jitted, the matrix // is kept in registers. alignas(16) static float skinMatrix[12]; @@ -49,13 +49,6 @@ inline int align(int n, int align) { return (n + (align - 1)) & ~(align - 1); } -int TranslateNumBones(int bones) { - if (!bones) return 0; - if (bones < 4) return 4; - // if (bones < 8) return 8; I get drawing problems in FF:CC with this! - return bones; -} - int DecFmtSize(u8 fmt) { switch (fmt) { case DEC_NONE: return 0; @@ -79,7 +72,22 @@ int DecFmtSize(u8 fmt) { } void DecVtxFormat::ComputeID() { - id = w0fmt | (w1fmt << 4) | (uvfmt << 8) | (c0fmt << 12) | (c1fmt << 16) | (nrmfmt << 20) | (posfmt << 24); + id = uvfmt | (c0fmt << 4) | (c1fmt << 8) | (nrmfmt << 12) | (posfmt << 16); +} + +void DecVtxFormat::InitializeFromID(uint32_t id) { + this->id = id; + uvfmt = (id & 0xF); + c0fmt = ((id >> 4) & 0xF); + c1fmt = ((id >> 8) & 0xF); + nrmfmt = ((id >> 12) & 0xF); + posfmt = ((id >> 16) & 0xF); + uvoff = 0; + c0off = uvoff + DecFmtSize(uvfmt); + c1off = c0off + DecFmtSize(c0fmt); + nrmoff = c1off + DecFmtSize(c1fmt); + posoff = nrmoff + DecFmtSize(nrmfmt); + stride = posoff + DecFmtSize(posfmt); } void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBound, u16 *indexUpperBound) { @@ -158,113 +166,37 @@ void PrintDecodedVertex(VertexReader &vtx) { VertexDecoder::VertexDecoder() : decoded_(nullptr), ptr_(nullptr), jitted_(0), jittedSize_(0) { } -void VertexDecoder::Step_WeightsU8() const -{ - u8 *wt = (u8 *)(decoded_ + decFmt.w0off); - const u8 *wdata = (const u8*)(ptr_); - int j; - for (j = 0; j < nweights; j++) - wt[j] = wdata[j]; - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0; -} - -void VertexDecoder::Step_WeightsU16() const -{ - u16 *wt = (u16 *)(decoded_ + decFmt.w0off); - const u16 *wdata = (const u16*)(ptr_); - int j; - for (j = 0; j < nweights; j++) - wt[j] = wdata[j]; - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0; -} - -void VertexDecoder::Step_WeightsU8ToFloat() const -{ - float *wt = (float *)(decoded_ + decFmt.w0off); - const u8 *wdata = (const u8*)(ptr_); - int j; - for (j = 0; j < nweights; j++) { - wt[j] = (float)wdata[j] * (1.0f / 128.0f); +void VertexDecoder::ComputeSkinMatrix(const float weights[8]) const { + memset(skinMatrix, 0, sizeof(skinMatrix)); + for (int j = 0; j < nweights; j++) { + const float *bone = &gstate.boneMatrix[j * 12]; + if (weights[j] != 0.0f) { + for (int i = 0; i < 12; i++) { + skinMatrix[i] += weights[j] * bone[i]; + } + } } - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0; } -void VertexDecoder::Step_WeightsU16ToFloat() const -{ - float *wt = (float *)(decoded_ + decFmt.w0off); +void VertexDecoder::Step_WeightsU8Skin() const { + const u8 *wdata = (const u8*)(ptr_); + float weights[8]; + for (int j = 0; j < nweights; j++) + weights[j] = wdata[j] * (1.0f / 128.0f); + ComputeSkinMatrix(weights); +} + +void VertexDecoder::Step_WeightsU16Skin() const { const u16 *wdata = (const u16*)(ptr_); - int j; - for (j = 0; j < nweights; j++) { - wt[j] = (float)wdata[j] * (1.0f / 32768.0f); - } - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0; + float weights[8]; + for (int j = 0; j < nweights; j++) + weights[j] = wdata[j] * (1.0f / 32768.0f); + ComputeSkinMatrix(weights); } -// Float weights should be uncommon, we can live with having to multiply these by 2.0 -// to avoid special checks in the vertex shader generator. -// (PSP uses 0.0-2.0 fixed point numbers for weights) -void VertexDecoder::Step_WeightsFloat() const -{ - float *wt = (float *)(decoded_ + decFmt.w0off); +void VertexDecoder::Step_WeightsFloatSkin() const { const float *wdata = (const float*)(ptr_); - int j; - for (j = 0; j < nweights; j++) { - wt[j] = wdata[j]; - } - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0.0f; -} - -void VertexDecoder::Step_WeightsU8Skin() const -{ - memset(skinMatrix, 0, sizeof(skinMatrix)); - const u8 *wdata = (const u8*)(ptr_); - for (int j = 0; j < nweights; j++) { - const float *bone = &gstate.boneMatrix[j * 12]; - if (wdata[j] != 0) { - float weight = wdata[j] * (1.0f / 128.0f); - for (int i = 0; i < 12; i++) { - skinMatrix[i] += weight * bone[i]; - } - } - } -} - -void VertexDecoder::Step_WeightsU16Skin() const -{ - memset(skinMatrix, 0, sizeof(skinMatrix)); - const u16 *wdata = (const u16*)(ptr_); - for (int j = 0; j < nweights; j++) { - const float *bone = &gstate.boneMatrix[j * 12]; - if (wdata[j] != 0) { - float weight = wdata[j] * (1.0f / 32768.0f); - for (int i = 0; i < 12; i++) { - skinMatrix[i] += weight * bone[i]; - } - } - } -} - -// Float weights should be uncommon, we can live with having to multiply these by 2.0 -// to avoid special checks in the vertex shader generator. -// (PSP uses 0.0-2.0 fixed point numbers for weights) -void VertexDecoder::Step_WeightsFloatSkin() const -{ - memset(skinMatrix, 0, sizeof(skinMatrix)); - const float *wdata = (const float*)(ptr_); - for (int j = 0; j < nweights; j++) { - const float *bone = &gstate.boneMatrix[j * 12]; - float weight = wdata[j]; - if (weight > 0.0) { - for (int i = 0; i < 12; i++) { - skinMatrix[i] += weight * bone[i]; - } - } - } + ComputeSkinMatrix(wdata); } void VertexDecoder::Step_TcU8ToFloat() const @@ -688,6 +620,42 @@ void VertexDecoder::Step_NormalFloatMorph() const } } +void VertexDecoder::Step_NormalS8MorphSkin() const { + float *normal = (float *)(decoded_ + decFmt.nrmoff); + float nrm[3]{}; + for (int n = 0; n < morphcount; n++) { + const s8 *bv = (const s8*)(ptr_ + onesize_ * n + nrmoff); + const float multiplier = gstate_c.morphWeights[n] * (1.0f / 128.0f); + for (int j = 0; j < 3; j++) + normal[j] += bv[j] * multiplier; + } + Norm3ByMatrix43(normal, nrm, skinMatrix); +} + +void VertexDecoder::Step_NormalS16MorphSkin() const { + float *normal = (float *)(decoded_ + decFmt.nrmoff); + float nrm[3]{}; + for (int n = 0; n < morphcount; n++) { + const s16 *sv = (const s16_le *)(ptr_ + onesize_ * n + nrmoff); + const float multiplier = gstate_c.morphWeights[n] * (1.0f / 32768.0f); + for (int j = 0; j < 3; j++) + nrm[j] += sv[j] * multiplier; + } + Norm3ByMatrix43(normal, nrm, skinMatrix); +} + +void VertexDecoder::Step_NormalFloatMorphSkin() const { + float *normal = (float *)(decoded_ + decFmt.nrmoff); + float nrm[3]{}; + for (int n = 0; n < morphcount; n++) { + float multiplier = gstate_c.morphWeights[n]; + const float *fv = (const float*)(ptr_ + onesize_ * n + nrmoff); + for (int j = 0; j < 3; j++) + nrm[j] += fv[j] * multiplier; + } + Norm3ByMatrix43(normal, nrm, skinMatrix); +} + void VertexDecoder::Step_PosS8() const { float *pos = (float *)(decoded_ + decFmt.posoff); @@ -795,19 +763,43 @@ void VertexDecoder::Step_PosFloatMorph() const } } -static const StepFunction wtstep[4] = { - 0, - &VertexDecoder::Step_WeightsU8, - &VertexDecoder::Step_WeightsU16, - &VertexDecoder::Step_WeightsFloat, -}; +void VertexDecoder::Step_PosS8MorphSkin() const { + float *v = (float *)(decoded_ + decFmt.posoff); + float pos[3]{}; + for (int n = 0; n < morphcount; n++) { + const float multiplier = 1.0f / 128.0f; + const s8 *sv = (const s8*)(ptr_ + onesize_ * n + posoff); + for (int j = 0; j < 3; j++) + pos[j] += (float)sv[j] * (multiplier * gstate_c.morphWeights[n]); + } + Vec3ByMatrix43(v, pos, skinMatrix); +} -static const StepFunction wtstepToFloat[4] = { - 0, - &VertexDecoder::Step_WeightsU8ToFloat, - &VertexDecoder::Step_WeightsU16ToFloat, - &VertexDecoder::Step_WeightsFloat, -}; +void VertexDecoder::Step_PosS16MorphSkin() const { + float *v = (float *)(decoded_ + decFmt.posoff); + float pos[3]{}; + for (int n = 0; n < morphcount; n++) { + const float multiplier = 1.0f / 32768.0f; + const s16 *sv = (const s16*)(ptr_ + onesize_ * n + posoff); + for (int j = 0; j < 3; j++) + pos[j] += (float)sv[j] * (multiplier * gstate_c.morphWeights[n]); + } + Vec3ByMatrix43(v, pos, skinMatrix); +} + +void VertexDecoder::Step_PosFloatMorphSkin() const { + float *v = (float *)(decoded_ + decFmt.posoff); + float pos[3]{}; + for (int n = 0; n < morphcount; n++) { + const float *fv = (const float*)(ptr_ + onesize_ * n + posoff); + for (int j = 0; j < 3; j++) + pos[j] += fv[j] * gstate_c.morphWeights[n]; + } + Vec3ByMatrix43(v, pos, skinMatrix); +} + +// TODO: Morph weights correctly! This is missing. Not sure if any game actually +// use this functionality at all. static const StepFunction wtstep_skin[4] = { 0, @@ -936,6 +928,13 @@ static const StepFunction nrmstep_morph[4] = { &VertexDecoder::Step_NormalFloatMorph, }; +static const StepFunction nrmstep_morphskin[4] = { + 0, + &VertexDecoder::Step_NormalS8MorphSkin, + &VertexDecoder::Step_NormalS16MorphSkin, + &VertexDecoder::Step_NormalFloatMorphSkin, +}; + static const StepFunction posstep[4] = { &VertexDecoder::Step_PosS8, &VertexDecoder::Step_PosS8, @@ -957,6 +956,13 @@ static const StepFunction posstep_morph[4] = { &VertexDecoder::Step_PosFloatMorph, }; +static const StepFunction posstep_morph_skin[4] = { + &VertexDecoder::Step_PosS8MorphSkin, + &VertexDecoder::Step_PosS8MorphSkin, + &VertexDecoder::Step_PosS16MorphSkin, + &VertexDecoder::Step_PosFloatMorphSkin, +}; + static const StepFunction posstep_through[4] = { &VertexDecoder::Step_PosS8Through, &VertexDecoder::Step_PosS8Through, @@ -990,7 +996,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, DEBUG_LOG(G3D, "VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc, col, pos, nrm, weighttype, nweights, idx, morphcount); } - bool skinInDecode = weighttype != 0 && g_Config.bSoftwareSkinning && morphcount == 1; + bool skinning = weighttype != 0; if (weighttype) { // && nweights? weightoff = size; @@ -999,40 +1005,11 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, if (wtalign[weighttype] > biggest) biggest = wtalign[weighttype]; - if (skinInDecode) { - steps_[numSteps_++] = wtstep_skin[weighttype]; - // No visible output, passed in register/external memory to the "pos" step. - } else { - int fmtBase = DEC_FLOAT_1; - if (options.expandAllWeightsToFloat) { - steps_[numSteps_++] = wtstepToFloat[weighttype]; - fmtBase = DEC_FLOAT_1; - } else { - steps_[numSteps_++] = wtstep[weighttype]; - if (weighttype == GE_VTYPE_WEIGHT_8BIT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_U8_1; - } else if (weighttype == GE_VTYPE_WEIGHT_16BIT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_U16_1; - } else if (weighttype == GE_VTYPE_WEIGHT_FLOAT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_FLOAT_1; - } - } - - int numWeights = TranslateNumBones(nweights); - - if (numWeights <= 4) { - decFmt.w0off = decOff; - decFmt.w0fmt = fmtBase + numWeights - 1; - decOff += DecFmtSize(decFmt.w0fmt); - } else { - decFmt.w0off = decOff; - decFmt.w0fmt = fmtBase + 3; - decOff += DecFmtSize(decFmt.w0fmt); - decFmt.w1off = decOff; - decFmt.w1fmt = fmtBase + numWeights - 5; - decOff += DecFmtSize(decFmt.w1fmt); - } - } + // No visible output, computes a matrix that is passed through the skinMatrix variable + // to the "nrm" and "pos" steps. + // Technically we should support morphing the weights too, but I have a hard time + // imagining that any game would use that.. but you never know. + steps_[numSteps_++] = wtstep_skin[weighttype]; } if (tc) { @@ -1090,8 +1067,8 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, if (nrmalign[nrm] > biggest) biggest = nrmalign[nrm]; - if (skinInDecode) { - steps_[numSteps_++] = nrmstep_skin[nrm]; + if (skinning) { + steps_[numSteps_++] = morphcount == 1 ? nrmstep_skin[nrm] : nrmstep_morphskin[nrm]; // After skinning, we always have three floats. decFmt.nrmfmt = DEC_FLOAT_3; } else { @@ -1141,8 +1118,8 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, steps_[numSteps_++] = posstep_through[pos]; decFmt.posfmt = DEC_FLOAT_3; } else { - if (skinInDecode) { - steps_[numSteps_++] = posstep_skin[pos]; + if (skinning) { + steps_[numSteps_++] = morphcount == 1 ? posstep_skin[pos] : posstep_morph_skin[pos]; decFmt.posfmt = DEC_FLOAT_3; } else { steps_[numSteps_++] = morphcount == 1 ? posstep[pos] : posstep_morph[pos]; diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 2066defced..6acf5c48d8 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -67,17 +67,16 @@ enum { int DecFmtSize(u8 fmt); struct DecVtxFormat { - u8 w0fmt; u8 w0off; // first 4 weights - u8 w1fmt; u8 w1off; // second 4 weights u8 uvfmt; u8 uvoff; u8 c0fmt; u8 c0off; // First color u8 c1fmt; u8 c1off; u8 nrmfmt; u8 nrmoff; u8 posfmt; u8 posoff; - short stride; + u8 stride; uint32_t id; void ComputeID(); + void InitializeFromID(uint32_t id); }; void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBound, u16 *indexUpperBound); @@ -346,61 +345,6 @@ public: } } - void ReadWeights(float weights[8]) const { - const float *f = (const float *)(data_ + decFmt_.w0off); - const u8 *b = (const u8 *)(data_ + decFmt_.w0off); - const u16 *s = (const u16 *)(data_ + decFmt_.w0off); - switch (decFmt_.w0fmt) { - case DEC_FLOAT_1: - case DEC_FLOAT_2: - case DEC_FLOAT_3: - case DEC_FLOAT_4: - for (int i = 0; i <= decFmt_.w0fmt - DEC_FLOAT_1; i++) - weights[i] = f[i]; - break; - case DEC_U8_1: weights[0] = b[0] * (1.f / 128.f); break; - case DEC_U8_2: for (int i = 0; i < 2; i++) weights[i] = b[i] * (1.f / 128.f); break; - case DEC_U8_3: for (int i = 0; i < 3; i++) weights[i] = b[i] * (1.f / 128.f); break; - case DEC_U8_4: for (int i = 0; i < 4; i++) weights[i] = b[i] * (1.f / 128.f); break; - case DEC_U16_1: weights[0] = s[0] * (1.f / 32768.f); break; - case DEC_U16_2: for (int i = 0; i < 2; i++) weights[i] = s[i] * (1.f / 32768.f); break; - case DEC_U16_3: for (int i = 0; i < 3; i++) weights[i] = s[i] * (1.f / 32768.f); break; - case DEC_U16_4: for (int i = 0; i < 4; i++) weights[i] = s[i] * (1.f / 32768.f); break; - default: - ERROR_LOG_REPORT_ONCE(fmtw0, G3D, "Reader: Unsupported W0 Format %d", decFmt_.w0fmt); - memset(weights, 0, sizeof(float) * 8); - break; - } - - f = (const float *)(data_ + decFmt_.w1off); - b = (const u8 *)(data_ + decFmt_.w1off); - s = (const u16 *)(data_ + decFmt_.w1off); - switch (decFmt_.w1fmt) { - case 0: - // It's fine for there to be w0 weights but not w1. - break; - case DEC_FLOAT_1: - case DEC_FLOAT_2: - case DEC_FLOAT_3: - case DEC_FLOAT_4: - for (int i = 0; i <= decFmt_.w1fmt - DEC_FLOAT_1; i++) - weights[i+4] = f[i]; - break; - case DEC_U8_1: weights[4] = b[0] * (1.f / 128.f); break; - case DEC_U8_2: for (int i = 0; i < 2; i++) weights[i+4] = b[i] * (1.f / 128.f); break; - case DEC_U8_3: for (int i = 0; i < 3; i++) weights[i+4] = b[i] * (1.f / 128.f); break; - case DEC_U8_4: for (int i = 0; i < 4; i++) weights[i+4] = b[i] * (1.f / 128.f); break; - case DEC_U16_1: weights[4] = s[0] * (1.f / 32768.f); break; - case DEC_U16_2: for (int i = 0; i < 2; i++) weights[i+4] = s[i] * (1.f / 32768.f); break; - case DEC_U16_3: for (int i = 0; i < 3; i++) weights[i+4] = s[i] * (1.f / 32768.f); break; - case DEC_U16_4: for (int i = 0; i < 4; i++) weights[i+4] = s[i] * (1.f / 32768.f); break; - default: - ERROR_LOG_REPORT_ONCE(fmtw1, G3D, "Reader: Unsupported W1 Format %d", decFmt_.w1fmt); - memset(weights + 4, 0, sizeof(float) * 4); - break; - } - } - bool hasColor0() const { return decFmt_.c0fmt != 0; } bool hasColor1() const { return decFmt_.c1fmt != 0; } bool hasNormal() const { return decFmt_.nrmfmt != 0; } @@ -431,9 +375,6 @@ struct JitLookup { JitStepFunction jitFunc; }; -// Collapse to less skinning shaders to reduce shader switching, which is expensive. -int TranslateNumBones(int bones); - typedef void(*JittedVertexDecoder)(const u8 *src, u8 *dst, int count); struct VertexDecoderOptions { @@ -460,11 +401,7 @@ public: std::string GetString(DebugShaderStringType stringType); - void Step_WeightsU8() const; - void Step_WeightsU16() const; - void Step_WeightsU8ToFloat() const; - void Step_WeightsU16ToFloat() const; - void Step_WeightsFloat() const; + void ComputeSkinMatrix(const float weights[8]) const; void Step_WeightsU8Skin() const; void Step_WeightsU16Skin() const; @@ -517,6 +454,10 @@ public: void Step_NormalS16Morph() const; void Step_NormalFloatMorph() const; + void Step_NormalS8MorphSkin() const; + void Step_NormalS16MorphSkin() const; + void Step_NormalFloatMorphSkin() const; + void Step_PosS8() const; void Step_PosS16() const; void Step_PosFloat() const; @@ -529,6 +470,10 @@ public: void Step_PosS16Morph() const; void Step_PosFloatMorph() const; + void Step_PosS8MorphSkin() const; + void Step_PosS16MorphSkin() const; + void Step_PosFloatMorphSkin() const; + void Step_PosS8Through() const; void Step_PosS16Through() const; void Step_PosFloatThrough() const; @@ -608,12 +553,6 @@ public: JittedVertexDecoder Compile(const VertexDecoder &dec, int32_t *jittedSize); void Clear(); - void Jit_WeightsU8(); - void Jit_WeightsU16(); - void Jit_WeightsU8ToFloat(); - void Jit_WeightsU16ToFloat(); - void Jit_WeightsFloat(); - void Jit_WeightsU8Skin(); void Jit_WeightsU16Skin(); void Jit_WeightsFloatSkin(); diff --git a/GPU/Common/VertexDecoderX86.cpp b/GPU/Common/VertexDecoderX86.cpp index 5098b2a7d4..f18d24a93d 100644 --- a/GPU/Common/VertexDecoderX86.cpp +++ b/GPU/Common/VertexDecoderX86.cpp @@ -39,6 +39,13 @@ alignas(16) static const float by32768[4] = { 1.0f / 32768.0f, 1.0f / 32768.0f, 1.0f / 32768.0f, 1.0f / 32768.0f, }; +alignas(16) static const float by128_11[4] = { + 1.0f / 128.0f, 1.0f / 128.0f, 1.0f, 1.0f, +}; +alignas(16) static const float by32768_11[4] = { + 1.0f / 32768.0f, 1.0f / 32768.0f, 1.0f, 1.0f, +}; + alignas(16) static const u32 threeMasks[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 }; alignas(16) static const u32 aOne[4] = {0, 0, 0, 0x3F800000}; @@ -87,16 +94,10 @@ static const X64Reg fpScratchReg4 = XMM4; // on the interpreter if the compiler fails. static const JitLookup jitLookup[] = { - {&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8}, - {&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16}, - {&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat}, {&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin}, {&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin}, {&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin}, - {&VertexDecoder::Step_WeightsU8ToFloat, &VertexDecoderJitCache::Jit_WeightsU8ToFloat}, - {&VertexDecoder::Step_WeightsU16ToFloat, &VertexDecoderJitCache::Jit_WeightsU16ToFloat}, - {&VertexDecoder::Step_TcFloat, &VertexDecoderJitCache::Jit_TcFloat}, {&VertexDecoder::Step_TcU8ToFloat, &VertexDecoderJitCache::Jit_TcU8ToFloat}, {&VertexDecoder::Step_TcU16ToFloat, &VertexDecoderJitCache::Jit_TcU16ToFloat}, @@ -201,7 +202,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int // Add code to convert matrices to 4x4. // Later we might want to do this when the matrices are loaded instead. int boneCount = 0; - if (dec.weighttype && g_Config.bSoftwareSkinning && dec.morphcount == 1) { + if (dec.weighttype) { MOV(PTRBITS, R(tempReg1), ImmPtr(&threeMasks)); MOVAPS(XMM4, MatR(tempReg1)); MOV(PTRBITS, R(tempReg1), ImmPtr(&aOne)); @@ -228,20 +229,14 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int // Keep the scale/offset in a few fp registers if we need it. if (prescaleStep) { MOV(PTRBITS, R(tempReg1), ImmPtr(&gstate_c.uv)); - MOVSS(fpScaleOffsetReg, MDisp(tempReg1, 0)); - MOVSS(fpScratchReg, MDisp(tempReg1, 4)); - UNPCKLPS(fpScaleOffsetReg, R(fpScratchReg)); + MOVUPS(fpScaleOffsetReg, MatR(tempReg1)); if ((dec.VertexType() & GE_VTYPE_TC_MASK) == GE_VTYPE_TC_8BIT) { - MOV(PTRBITS, R(tempReg2), ImmPtr(&by128)); + MOV(PTRBITS, R(tempReg2), ImmPtr(&by128_11)); MULPS(fpScaleOffsetReg, MatR(tempReg2)); } else if ((dec.VertexType() & GE_VTYPE_TC_MASK) == GE_VTYPE_TC_16BIT) { - MOV(PTRBITS, R(tempReg2), ImmPtr(&by32768)); + MOV(PTRBITS, R(tempReg2), ImmPtr(&by32768_11)); MULPS(fpScaleOffsetReg, MatR(tempReg2)); } - MOVSS(fpScratchReg, MDisp(tempReg1, 8)); - MOVSS(fpScratchReg2, MDisp(tempReg1, 12)); - UNPCKLPS(fpScratchReg, R(fpScratchReg2)); - UNPCKLPD(fpScaleOffsetReg, R(fpScratchReg)); } // Let's not bother with a proper stack frame. We just grab the arguments and go. @@ -281,175 +276,6 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int return (JittedVertexDecoder)start; } -void VertexDecoderJitCache::Jit_WeightsU8() { - switch (dec_->nweights) { - case 1: - MOVZX(32, 8, tempReg1, MDisp(srcReg, dec_->weightoff)); - break; - case 2: - MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->weightoff)); - break; - case 3: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - AND(32, R(tempReg1), Imm32(0x00FFFFFF)); - break; - case 4: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - break; - case 5: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOVZX(32, 8, tempReg2, MDisp(srcReg, dec_->weightoff + 4)); - break; - case 6: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOVZX(32, 16, tempReg2, MDisp(srcReg, dec_->weightoff + 4)); - break; - case 7: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4)); - AND(32, R(tempReg2), Imm32(0x00FFFFFF)); - break; - case 8: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4)); - break; - } - - if (dec_->nweights <= 4) { - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - } else { - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - MOV(32, MDisp(dstReg, dec_->decFmt.w1off), R(tempReg2)); - } -} - -void VertexDecoderJitCache::Jit_WeightsU16() { - switch (dec_->nweights) { - case 1: - MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->weightoff)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), Imm32(0)); - return; - - case 2: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), Imm32(0)); - return; - - case 3: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOVZX(32, 16, tempReg2, MDisp(srcReg, dec_->weightoff + 4)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), R(tempReg2)); - return; - - case 4: - // Anything above 4 will do 4 here, and then the rest after. - case 5: - case 6: - case 7: - case 8: - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff)); - MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), R(tempReg2)); - break; - } - - // Basic implementation - a short at a time. TODO: Optimize - int j; - for (j = 4; j < dec_->nweights; j++) { - MOV(16, R(tempReg1), MDisp(srcReg, dec_->weightoff + j * 2)); - MOV(16, MDisp(dstReg, dec_->decFmt.w0off + j * 2), R(tempReg1)); - } - while (j & 3) { - MOV(16, MDisp(dstReg, dec_->decFmt.w0off + j * 2), Imm16(0)); - j++; - } -} - -void VertexDecoderJitCache::Jit_WeightsU8ToFloat() { - if (dec_->nweights >= 4) { - Jit_AnyU8ToFloat(dec_->weightoff, 32); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - if (dec_->nweights > 4) { - Jit_AnyU8ToFloat(dec_->weightoff + 4, (dec_->nweights - 4) * 8); - MOVUPS(MDisp(dstReg, dec_->decFmt.w1off), XMM3); - } - } else { - Jit_AnyU8ToFloat(dec_->weightoff, dec_->nweights * 8); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - } -} - -void VertexDecoderJitCache::Jit_WeightsU16ToFloat() { - if (dec_->nweights >= 4) { - Jit_AnyU16ToFloat(dec_->weightoff, 64); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - if (dec_->nweights > 4) { - Jit_AnyU16ToFloat(dec_->weightoff + 4 * 2, (dec_->nweights - 4) * 16); - MOVUPS(MDisp(dstReg, dec_->decFmt.w1off), XMM3); - } - } else { - Jit_AnyU16ToFloat(dec_->weightoff, dec_->nweights * 16); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - } -} - -void VertexDecoderJitCache::Jit_WeightsFloat() { - int j; - switch (dec_->nweights) { - case 1: - // MOVSS: When the source operand is a memory location and destination operand is an XMM register, the three high-order doublewords of the destination operand are cleared to all 0s. - MOVSS(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - break; - - case 2: - MOVQ_xmm(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - break; - - case 4: - MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - break; - - case 5: - MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVSS(XMM4, MDisp(srcReg, dec_->weightoff + 16)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4); - break; - - case 6: - MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVQ_xmm(XMM4, MDisp(srcReg, dec_->weightoff + 16)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4); - break; - - case 8: - MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff)); - MOVUPS(XMM4, MDisp(srcReg, dec_->weightoff + 16)); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3); - MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4); - break; - - default: - for (j = 0; j < dec_->nweights; j++) { - MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff + j * 4)); - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + j * 4), R(tempReg1)); - } - while (j & 3) { // Zero additional weights rounding up to 4. - MOV(32, MDisp(dstReg, dec_->decFmt.w0off + j * 4), Imm32(0)); - j++; - } - break; - } -} - void VertexDecoderJitCache::Jit_WeightsU8Skin() { MOV(PTRBITS, R(tempReg2), ImmPtr(&bones)); diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 9924d9c888..35b81a3d89 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -204,18 +204,6 @@ ID3D11InputLayout *DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshade D3D11_INPUT_ELEMENT_DESC VertexElements[8]; D3D11_INPUT_ELEMENT_DESC *VertexElement = &VertexElements[0]; - // Vertices Elements orders - // WEIGHT - if (decFmt.w0fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w0fmt, decFmt.w0off, "TEXCOORD", 1); - VertexElement++; - } - - if (decFmt.w1fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w1fmt, decFmt.w1off, "TEXCOORD", 2); - VertexElement++; - } - // TC if (decFmt.uvfmt != 0) { VertexAttribSetup(VertexElement, decFmt.uvfmt, decFmt.uvoff, "TEXCOORD", 0); @@ -257,72 +245,6 @@ ID3D11InputLayout *DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshade } } -void DrawEngineD3D11::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) { - if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) - Flush(); - - // TODO: Is this the right thing to do? - if (prim == GE_PRIM_KEEP_PREVIOUS) { - prim = prevPrim_ != GE_PRIM_INVALID ? prevPrim_ : GE_PRIM_POINTS; - } else { - prevPrim_ = prim; - } - - SetupVertexDecoder(vertType); - - *bytesRead = vertexCount * dec_->VertexSize(); - - if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) - return; - - DeferredDrawCall &dc = drawCalls[numDrawCalls]; - dc.verts = verts; - dc.inds = inds; - dc.vertType = vertType; - dc.indexType = (vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; - dc.prim = prim; - dc.vertexCount = vertexCount; - - if (g_Config.bVertexCache) { - u32 dhash = dcid_; - dhash ^= (u32)(uintptr_t)verts; - dhash = __rotl(dhash, 13); - dhash ^= (u32)(uintptr_t)inds; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertType; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertexCount; - dhash = __rotl(dhash, 13); - dhash ^= (u32)prim; - dcid_ = dhash; - } - - if (inds) { - GetIndexBounds(inds, vertexCount, vertType, &dc.indexLowerBound, &dc.indexUpperBound); - } else { - dc.indexLowerBound = 0; - dc.indexUpperBound = vertexCount - 1; - } - - uvScale[numDrawCalls] = gstate_c.uv; - - numDrawCalls++; - vertexCountInDrawCalls_ += vertexCount; - - if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) { - DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); - decodeCounter_++; - } - - if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { - // Rendertarget == texture? - if (!g_Config.bDisableSlowFramebufEffects) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - Flush(); - } - } -} - void DrawEngineD3D11::MarkUnreliable(VertexArrayInfoD3D11 *vai) { vai->status = VertexArrayInfoD3D11::VAI_UNRELIABLE; if (vai->vbo) { @@ -409,8 +331,8 @@ void DrawEngineD3D11::DoFlush() { // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. - if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) + // Also avoid caching when skinning. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) useCache = false; if (useCache) { diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 6928bca67b..9d4589baae 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -105,8 +105,6 @@ public: DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context); virtual ~DrawEngineD3D11(); - void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead); - void SetShaderManager(ShaderManagerD3D11 *shaderManager) { shaderManager_ = shaderManager; } @@ -135,9 +133,6 @@ public: } void DispatchFlush() override { Flush(); } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override { - SubmitPrim(verts, inds, prim, vertexCount, vertType, bytesRead); - } void ClearTrackedVertexArrays() override; diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 6da4b477c1..9cd78f97dc 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -197,13 +197,6 @@ void FramebufferManagerD3D11::SetDrawEngine(DrawEngineD3D11 *td) { drawEngine_ = td; } -void FramebufferManagerD3D11::DisableState() { - context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF); - context_->RSSetState(stockD3D11.rasterStateNoCull); - context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); -} - void FramebufferManagerD3D11::CompilePostShader() { std::string vsSource; std::string psSource; @@ -459,15 +452,6 @@ void FramebufferManagerD3D11::BindPostShader(const PostShaderUniforms &uniforms) context_->PSSetConstantBuffers(0, 1, &postConstants_); } -void FramebufferManagerD3D11::RebindFramebuffer() { - if (currentRenderVfb_ && currentRenderVfb_->fbo) { - draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); - } else { - // Should this even happen? - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); - } -} - void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) { if (!useBufferedRendering_ || !vfb->fbo) { return; @@ -740,8 +724,6 @@ void FramebufferManagerD3D11::DestroyAllFBOs() { tempFBOs_.clear(); SetNumExtraFBOs(0); - - DisableState(); } void FramebufferManagerD3D11::Resized() { diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index 508e995e52..253bc8dd6e 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -59,16 +59,12 @@ public: virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; - virtual void RebindFramebuffer() override; - // TODO: Remove ID3D11Buffer *GetDynamicQuadBuffer() { return quadBuffer_; } protected: - void DisableState() override; - // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 24dcfdd734..2b5d760302 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -66,31 +66,6 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" -struct D3D11CommandTableEntry { - uint8_t cmd; - uint8_t flags; - uint64_t dirty; - GPU_D3D11::CmdFunc func; -}; - -// This table gets crunched into a faster form by init. -static const D3D11CommandTableEntry commandTable[] = { - // Changes that dirty the current texture. - { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_TexSize0 }, - - // Changing the vertex type requires us to flush. - { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_VertexType }, - - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, - - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_LoadClut }, -}; - -GPU_D3D11::CommandInfo GPU_D3D11::cmdInfo_[256]{}; - GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw), drawEngine_(draw, (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE), @@ -126,48 +101,9 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - memset(cmdInfo_, 0, sizeof(cmdInfo_)); - - // Import both the global and local command tables, and check for dupes - std::set dupeCheck; - for (size_t i = 0; i < commonCommandTableSize; i++) { - const u8 cmd = commonCommandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); - cmdInfo_[cmd].func = commonCommandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - - for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { - const u8 cmd = commandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commandTable[i].flags | (commandTable[i].dirty << 8); - cmdInfo_[cmd].func = commandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - - // Find commands missing from the table. - for (int i = 0; i < 0xEF; i++) { - if (dupeCheck.find((u8)i) == dupeCheck.end()) { - ERROR_LOG(G3D, "Command missing from table: %02x (%i)", i, i); - } - } - // No need to flush before the tex scale/offset commands if we are baking // the tex scale/offset into the vertices anyway. - UpdateCmdInfo(); + CheckGPUFeatures(); BuildReportingInfo(); @@ -187,26 +123,16 @@ GPU_D3D11::~GPU_D3D11() { stockD3D11.Destroy(); } -void GPU_D3D11::UpdateCmdInfo() { - if (g_Config.bSoftwareSkinning) { - cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; - } else { - cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexType; - } - - CheckGPUFeatures(); -} - void GPU_D3D11::CheckGPUFeatures() { u32 features = 0; features |= GPU_SUPPORTS_BLEND_MINMAX; features |= GPU_PREFER_CPU_DOWNLOAD; - // Accurate depth is required on AMD so we ignore the compat flag to disable it on those. See #9545 - if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || draw_->GetDeviceCaps().vendor == Draw::GPUVendor::VENDOR_AMD) { + // Accurate depth is required on AMD/nVidia (for reverse Z) so we ignore the compat flag to disable it on those. See #9545 + auto vendor = draw_->GetDeviceCaps().vendor; + + if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || vendor == Draw::GPUVendor::VENDOR_AMD || vendor == Draw::GPUVendor::VENDOR_NVIDIA) { features |= GPU_SUPPORTS_ACCURATE_DEPTH; // Breaks text in PaRappa for some reason. } @@ -288,8 +214,8 @@ void GPU_D3D11::InitClear() { void GPU_D3D11::BeginHostFrame() { GPUCommon::BeginHostFrame(); - UpdateCmdInfo(); if (resized_) { + CheckGPUFeatures(); framebufferManager_->Resized(); drawEngine_.Resized(); textureCacheD3D11_->NotifyConfigChanged(); @@ -330,26 +256,6 @@ void GPU_D3D11::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat f framebufferManagerD3D11_->SetDisplayFramebuffer(framebuf, stride, format); } -bool GPU_D3D11::FramebufferDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->dirtyAfterDisplay; - vfb->dirtyAfterDisplay = false; - return dirty; - } - return true; -} - -bool GPU_D3D11::FramebufferReallyDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->reallyDirtyAfterDisplay; - vfb->reallyDirtyAfterDisplay = false; - return dirty; - } - return true; -} - void GPU_D3D11::CopyDisplayToOutput() { float blendColor[4]{}; context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], blendColor, 0xFFFFFFFF); @@ -365,44 +271,6 @@ void GPU_D3D11::CopyDisplayToOutput() { gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } -// Maybe should write this in ASM... -void GPU_D3D11::FastRunLoop(DisplayList &list) { - PROFILE_THIS_SCOPE("gpuloop"); - const CommandInfo *cmdInfo = cmdInfo_; - int dc = downcount; - for (; dc > 0; --dc) { - // We know that display list PCs have the upper nibble == 0 - no need to mask the pointer - const u32 op = *(const u32 *)(Memory::base + list.pc); - const u32 cmd = op >> 24; - const CommandInfo &info = cmdInfo[cmd]; - const u32 diff = op ^ gstate.cmdmem[cmd]; - if (diff == 0) { - if (info.flags & FLAG_EXECUTE) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } - } else { - uint64_t flags = info.flags; - if (flags & FLAG_FLUSHBEFOREONCHANGE) { - drawEngine_.Flush(); - } - gstate.cmdmem[cmd] = op; - if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } else { - uint64_t dirty = flags >> 8; - if (dirty) - gstate_c.Dirty(dirty); - } - } - list.pc += 4; - } - downcount = 0; -} - void GPU_D3D11::FinishDeferred() { // This finishes reading any vertex data that is pending. drawEngine_.FinishDeferred(); @@ -435,85 +303,6 @@ void GPU_D3D11::ExecuteOp(u32 op, u32 diff) { } } -void GPU_D3D11::Execute_Prim(u32 op, u32 diff) { - // This drives all drawing. All other state we just buffer up, then we apply it only - // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. - - u32 data = op & 0xFFFFFF; - u32 count = data & 0xFFFF; - if (count == 0) - return; - - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - SetDrawType(DRAW_PRIM, prim); - - // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. - - if (gstate.isAntiAliasEnabled()) { - // Discard AA lines in DOA - if (prim == GE_PRIM_LINE_STRIP) - return; - // Discard AA lines in Summon Night 5 - if ((prim == GE_PRIM_LINES) && gstate.isSkinningEnabled()) - return; - } - - // This also make skipping drawing very effective. - framebufferManagerD3D11_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - drawEngine_.SetupVertexDecoder(gstate.vertType); - // Rough estimate, not sure what's correct. - cyclesExecuted += EstimatePerVertexCost() * count; - return; - } - - u32 vertexAddr = gstate_c.vertexAddr; - if (!Memory::IsValidAddress(vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", vertexAddr); - return; - } - - void *verts = Memory::GetPointerUnchecked(vertexAddr); - void *inds = 0; - u32 vertexType = gstate.vertType; - if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - u32 indexAddr = gstate_c.indexAddr; - if (!Memory::IsValidAddress(indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", indexAddr); - return; - } - inds = Memory::GetPointerUnchecked(indexAddr); - } - -#ifndef MOBILE_DEVICE - if (prim > GE_PRIM_RECTANGLES) { - ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); - } -#endif - - if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { - vertexCost_ = EstimatePerVertexCost(); - } - gpuStats.vertexGPUCycles += vertexCost_ * count; - cyclesExecuted += vertexCost_* count; - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitPrim(verts, inds, prim, count, vertexType, &bytesRead); - - // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). - // Some games rely on this, they don't bother reloading VADDR and IADDR. - // The VADDR/IADDR registers are NOT updated. - AdvanceVerts(vertexType, count, bytesRead); -} - -void GPU_D3D11::Execute_LoadClut(u32 op, u32 diff) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - textureCacheD3D11_->LoadClut(gstate.getClutAddress(), gstate.getClutLoadBytes()); - // This could be used to "dirty" textures with clut. -} - void GPU_D3D11::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, diff --git a/GPU/D3D11/GPU_D3D11.h b/GPU/D3D11/GPU_D3D11.h index 9d7ff6bc59..acb4dd3e07 100644 --- a/GPU/D3D11/GPU_D3D11.h +++ b/GPU/D3D11/GPU_D3D11.h @@ -36,7 +36,7 @@ public: GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw); ~GPU_D3D11(); - void CheckGPUFeatures(); + void CheckGPUFeatures() override; void PreExecuteOp(u32 op, u32 diff) override; void ExecuteOp(u32 op, u32 diff) override; @@ -50,25 +50,6 @@ public: void DoState(PointerWrap &p) override; void ClearShaderCache() override; - bool DecodeTexture(u8 *dest, const GPUgstate &state) override { - return false; - } - bool FramebufferDirty() override; - bool FramebufferReallyDirty() override; - - void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override { - primaryInfo = reportingPrimaryInfo_; - fullInfo = reportingFullInfo_; - } - - typedef void (GPU_D3D11::*CmdFunc)(u32 op, u32 diff); - struct CommandInfo { - uint64_t flags; - GPU_D3D11::CmdFunc func; - }; - - void Execute_Prim(u32 op, u32 diff); - void Execute_LoadClut(u32 op, u32 diff); // Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend. std::vector DebugGetShaderIDs(DebugShaderType shader) override; @@ -78,12 +59,9 @@ public: void EndHostFrame() override; protected: - void FastRunLoop(DisplayList &list) override; void FinishDeferred() override; private: - void UpdateCmdInfo(); - void Flush() { drawEngine_.Flush(); } @@ -104,11 +82,6 @@ private: DrawEngineD3D11 drawEngine_; ShaderManagerD3D11 *shaderManagerD3D11_; - static CommandInfo cmdInfo_[256]; - int lastVsync_; int vertexCost_ = 0; - - std::string reportingPrimaryInfo_; - std::string reportingFullInfo_; }; diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 75f8d9535e..7e79d57224 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -63,8 +63,8 @@ std::string D3D11FragmentShader::GetShaderString(DebugShaderStringType type) con } } -D3D11VertexShader::D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, VShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting) - : device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr), usesLighting_(usesLighting) { +D3D11VertexShader::D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, VShaderID id, const char *code, int vertType, bool useHWTransform) + : device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr) { source_ = code; module_ = CreateVertexShaderD3D11(device, code, strlen(code), &bytecode_, featureLevel); @@ -93,24 +93,19 @@ ShaderManagerD3D11::ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext codeBuffer_ = new char[16384]; memset(&ub_base, 0, sizeof(ub_base)); memset(&ub_lights, 0, sizeof(ub_lights)); - memset(&ub_bones, 0, sizeof(ub_bones)); INFO_LOG(G3D, "sizeof(ub_base): %d", (int)sizeof(ub_base)); INFO_LOG(G3D, "sizeof(ub_lights): %d", (int)sizeof(ub_lights)); - INFO_LOG(G3D, "sizeof(ub_bones): %d", (int)sizeof(ub_bones)); D3D11_BUFFER_DESC desc{sizeof(ub_base), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE }; ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_base)); desc.ByteWidth = sizeof(ub_lights); ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_lights)); - desc.ByteWidth = sizeof(ub_bones); - ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_bones)); } ShaderManagerD3D11::~ShaderManagerD3D11() { push_base->Release(); push_lights->Release(); - push_bones->Release(); ClearShaders(); delete[] codeBuffer_; } @@ -159,21 +154,15 @@ uint64_t ShaderManagerD3D11::UpdateUniforms() { memcpy(map.pData, &ub_lights, sizeof(ub_lights)); context_->Unmap(push_lights, 0); } - if (dirty & DIRTY_BONE_UNIFORMS) { - BoneUpdateUniforms(&ub_bones, dirty); - context_->Map(push_bones, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, &ub_bones, sizeof(ub_bones)); - context_->Unmap(push_bones, 0); - } } gstate_c.CleanUniforms(); return dirty; } void ShaderManagerD3D11::BindUniforms() { - ID3D11Buffer *vs_cbs[3] = { push_base, push_lights, push_bones }; + ID3D11Buffer *vs_cbs[2] = { push_base, push_lights }; ID3D11Buffer *ps_cbs[1] = { push_base }; - context_->VSSetConstantBuffers(0, 3, vs_cbs); + context_->VSSetConstantBuffers(0, 2, vs_cbs); context_->PSSetConstantBuffers(0, 1, ps_cbs); } @@ -207,9 +196,8 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader ** D3D11VertexShader *vs; if (vsIter == vsCache_.end()) { // Vertex shader not in cache. Let's compile it. - bool usesLighting; - GenerateVertexShaderD3D11(VSID, codeBuffer_, &usesLighting, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11); - vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform, usesLighting); + GenerateVertexShaderD3D11(VSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11); + vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform); vsCache_[VSID] = vs; } else { vs = vsIter->second; diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index 3d66c9dfb5..cc0da972bd 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -54,19 +54,13 @@ protected: class D3D11VertexShader { public: - D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, VShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting); + D3D11VertexShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, VShaderID id, const char *code, int vertType, bool useHWTransform); ~D3D11VertexShader(); const std::string &source() const { return source_; } const std::vector &bytecode() const { return bytecode_; } bool Failed() const { return failed_; } bool UseHWTransform() const { return useHWTransform_; } - bool HasBones() const { - return id_.Bit(VS_BIT_ENABLE_BONES); - } - bool HasLights() const { - return usesLighting_; - } std::string GetShaderString(DebugShaderStringType type) const; ID3D11VertexShader *GetShader() const { return module_; } @@ -80,7 +74,6 @@ protected: bool failed_; bool useHWTransform_; - bool usesLighting_; VShaderID id_; }; @@ -108,13 +101,6 @@ public: // Applies dirty changes and copies the buffer. bool IsBaseDirty() { return true; } bool IsLightDirty() { return true; } - bool IsBoneDirty() { return true; } - - /* - uint32_t PushBaseBuffer(D3D11PushBuffer *dest, VkBuffer *buf); - uint32_t PushLightBuffer(D3D11PushBuffer *dest, VkBuffer *buf); - uint32_t PushBoneBuffer(D3D11PushBuffer *dest, VkBuffer *buf); - */ private: void Clear(); @@ -134,12 +120,10 @@ private: // Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time. UB_VS_FS_Base ub_base; UB_VS_Lights ub_lights; - UB_VS_Bones ub_bones; // Not actual pushbuffers, requires D3D11.1, let's try to live without that first. ID3D11Buffer *push_base; ID3D11Buffer *push_lights; - ID3D11Buffer *push_bones; D3D11FragmentShader *lastFShader_; D3D11VertexShader *lastVShader_; diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 002a118fa4..ee76b37322 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -462,4 +462,8 @@ void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRe context_->OMSetDepthStencilState(depthStencilState_, applyStencilRef ? stencilRef : dynState_.stencilRef); } gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE); + + // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. + if (fboTexBound_) + gstate_c.Dirty(DIRTY_BLEND_STATE); } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index f63a7028c7..a983a765dd 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -775,22 +775,19 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture & FreeAlignedMemory(mapData); } -bool TextureCacheD3D11::DecodeTexture(u8 *output, const GPUgstate &state) { - OutputDebugStringA("TextureCache::DecodeTexture : FixMe\r\n"); - return true; -} - bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { - ApplyTexture(); SetTexture(false); if (!nextTexture_) return false; + // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. + TexCacheEntry *entry = nextTexture_; + ApplyTexture(); + // TODO: Centralize. - if (nextTexture_->framebuffer) { - VirtualFramebuffer *vfb = nextTexture_->framebuffer; - bool flipY = GetGPUBackend() == GPUBackend::OPENGL && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, flipY); + if (entry->framebuffer) { + VirtualFramebuffer *vfb = entry->framebuffer; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. @@ -800,7 +797,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level return retval; } - ID3D11Texture2D *texture = (ID3D11Texture2D *)nextTexture_->texturePtr; + ID3D11Texture2D *texture = (ID3D11Texture2D *)entry->texturePtr; if (!texture) return false; diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index c7fdc9899d..c20ed762a9 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -57,9 +57,6 @@ public: shaderManager_ = sm; } - // Only used by Qt UI? - bool DecodeTexture(u8 *output, const GPUgstate &state); - void ForgetLastTexture() override; void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; diff --git a/GPU/D3D11/VertexShaderGeneratorD3D11.cpp b/GPU/D3D11/VertexShaderGeneratorD3D11.cpp index 1153d6358c..75affc997d 100644 --- a/GPU/D3D11/VertexShaderGeneratorD3D11.cpp +++ b/GPU/D3D11/VertexShaderGeneratorD3D11.cpp @@ -19,7 +19,6 @@ #include "GPU/D3D11/VertexShaderGeneratorD3D11.h" #include "GPU/Directx9/VertexShaderGeneratorDX9.h" -void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, bool *usesLighting, ShaderLanguage lang) { - *usesLighting = true; +void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, ShaderLanguage lang) { DX9::GenerateVertexShaderHLSL(id, buffer, lang); } diff --git a/GPU/D3D11/VertexShaderGeneratorD3D11.h b/GPU/D3D11/VertexShaderGeneratorD3D11.h index e9c6d0ca42..fcf6f7f749 100644 --- a/GPU/D3D11/VertexShaderGeneratorD3D11.h +++ b/GPU/D3D11/VertexShaderGeneratorD3D11.h @@ -19,4 +19,4 @@ #include "GPU/Common/ShaderId.h" -void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, bool *usesLighting, ShaderLanguage lang); +void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, ShaderLanguage lang); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 1acd41d7a3..a19c1f4116 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -175,16 +175,6 @@ IDirect3DVertexDeclaration9 *DrawEngineDX9::SetupDecFmtForDraw(VSShader *vshader D3DVERTEXELEMENT9 *VertexElement = &VertexElements[0]; // Vertices Elements orders - // WEIGHT - if (decFmt.w0fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w0fmt, decFmt.w0off, D3DDECLUSAGE_TEXCOORD, 1); - VertexElement++; - } - - if (decFmt.w1fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w1fmt, decFmt.w1off, D3DDECLUSAGE_TEXCOORD, 2); - VertexElement++; - } // TC if (decFmt.uvfmt != 0) { @@ -232,70 +222,6 @@ IDirect3DVertexDeclaration9 *DrawEngineDX9::SetupDecFmtForDraw(VSShader *vshader } } -void DrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) { - if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) - Flush(); - - // TODO: Is this the right thing to do? - if (prim == GE_PRIM_KEEP_PREVIOUS) { - prim = prevPrim_ != GE_PRIM_INVALID ? prevPrim_ : GE_PRIM_POINTS; - } else { - prevPrim_ = prim; - } - - SetupVertexDecoder(vertType); - - *bytesRead = vertexCount * dec_->VertexSize(); - - if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) - return; - - DeferredDrawCall &dc = drawCalls[numDrawCalls]; - dc.verts = verts; - dc.inds = inds; - dc.vertType = vertType; - dc.indexType = (vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; - dc.prim = prim; - dc.vertexCount = vertexCount; - - u32 dhash = dcid_; - dhash ^= (u32)(uintptr_t)verts; - dhash = __rotl(dhash, 13); - dhash ^= (u32)(uintptr_t)inds; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertType; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertexCount; - dhash = __rotl(dhash, 13); - dhash ^= (u32)prim; - dcid_ = dhash; - - if (inds) { - GetIndexBounds(inds, vertexCount, vertType, &dc.indexLowerBound, &dc.indexUpperBound); - } else { - dc.indexLowerBound = 0; - dc.indexUpperBound = vertexCount - 1; - } - - uvScale[numDrawCalls] = gstate_c.uv; - - numDrawCalls++; - vertexCountInDrawCalls_ += vertexCount; - - if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) { - DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); - decodeCounter_++; - } - - if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { - // Rendertarget == texture? - if (!g_Config.bDisableSlowFramebufEffects) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - Flush(); - } - } -} - void DrawEngineDX9::MarkUnreliable(VertexArrayInfoDX9 *vai) { vai->status = VertexArrayInfoDX9::VAI_UNRELIABLE; if (vai->vbo) { @@ -388,8 +314,8 @@ void DrawEngineDX9::DoFlush() { // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. - if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) + // Also avoid caching when skinning. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) useCache = false; if (useCache) { diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index 35cc5fd18e..ef015b02b5 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -103,8 +103,6 @@ public: DrawEngineDX9(Draw::DrawContext *draw); virtual ~DrawEngineDX9(); - void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead); - void SetShaderManager(ShaderManagerDX9 *shaderManager) { shaderManager_ = shaderManager; } @@ -134,9 +132,6 @@ public: } void DispatchFlush() override { Flush(); } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override { - SubmitPrim(verts, inds, prim, vertexCount, vertType, bytesRead); - } private: void DoFlush(); diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index fa0235a2c5..3d7e7c03b7 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -81,17 +81,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { D3DDECL_END() }; - void FramebufferManagerDX9::DisableState() { - dxstate.blend.disable(); - dxstate.cullMode.set(false, false); - dxstate.depthTest.disable(); - dxstate.scissorTest.disable(); - dxstate.stencilTest.disable(); - dxstate.colorMask.set(true, true, true, true); - dxstate.stencilMask.set(0xFF); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); - } - FramebufferManagerDX9::FramebufferManagerDX9(Draw::DrawContext *draw) : FramebufferManagerCommon(draw), drawPixelsTex_(0), @@ -249,7 +238,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) { - // TODO: StretchRect instead? + // TODO: StretchRect instead when possible? float coord[20] = { x,y,0, u0,v0, x+w,y,0, u1,v0, @@ -297,7 +286,13 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } dxstate.texMipLodBias.set(0.0f); dxstate.texMaxMipLevel.set(0); - device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + dxstate.blend.disable(); + dxstate.cullMode.set(false, false); + dxstate.depthTest.disable(); + dxstate.scissorTest.disable(); + dxstate.stencilTest.disable(); + dxstate.colorMask.set(true, true, true, true); + dxstate.stencilMask.set(0xFF); HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coord, 5 * sizeof(float)); if (FAILED(hr)) { ERROR_LOG_REPORT(G3D, "DrawActiveTexture() failed: %08x", hr); @@ -537,9 +532,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } } - // TODO: SSE/NEON - // Could also make C fake-simd for 64-bit, two 8888 pixels fit in a register :) - void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) { + void ConvertFromBGRA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) { // Must skip stride in the cases below. Some games pack data into the cracks, like MotoGP. const u32 *src32 = (const u32 *)src; @@ -617,7 +610,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { // TODO: Handle the other formats? We don't currently create them, I think. const int dstByteOffset = (y * vfb->fb_stride + x) * dstBpp; // Pixel size always 4 here because we always request BGRA8888. - ConvertFromRGBA8888(Memory::GetPointer(fb_address + dstByteOffset), (u8 *)locked.pBits, vfb->fb_stride, locked.Pitch / 4, w, h, vfb->format); + ConvertFromBGRA8888(Memory::GetPointer(fb_address + dstByteOffset), (u8 *)locked.pBits, vfb->fb_stride, locked.Pitch / 4, w, h, vfb->format); offscreen->UnlockRect(); } else { ERROR_LOG_REPORT(G3D, "Unable to lock rect from %08x: %d,%d %dx%d of %dx%d", fb_address, rect.left, rect.top, rect.right, rect.bottom, vfb->renderWidth, vfb->renderHeight); @@ -727,8 +720,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { offscreenSurfaces_.clear(); SetNumExtraFBOs(0); - - DisableState(); } void FramebufferManagerDX9::Resized() { diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index dd1b3bd2ca..bc2ce7c31d 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -73,7 +73,6 @@ protected: void Bind2DShader() override; void BindPostShader(const PostShaderUniforms &uniforms) override; void SetViewport2D(int x, int y, int w, int h) override; - void DisableState() override; void DecimateFBOs() override; // Used by ReadFramebufferToMemory and later framebuffer block copies diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 158442285c..52f1a6e2d6 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -50,31 +50,6 @@ namespace DX9 { -struct D3D9CommandTableEntry { - uint8_t cmd; - uint8_t flags; - uint64_t dirty; - GPU_DX9::CmdFunc func; -}; - -// This table gets crunched into a faster form by init. -static const D3D9CommandTableEntry commandTable[] = { - // Changes that dirty the current texture. - { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_TexSize0 }, - - // Changing the vertex type requires us to flush. - { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_VertexType }, - - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, - - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_LoadClut }, -}; - -GPU_DX9::CommandInfo GPU_DX9::cmdInfo_[256]; - GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw), depalShaderCache_(draw), @@ -108,47 +83,7 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - memset(cmdInfo_, 0, sizeof(cmdInfo_)); - - // Import both the global and local command tables, and check for dupes - std::set dupeCheck; - for (size_t i = 0; i < commonCommandTableSize; i++) { - const u8 cmd = commonCommandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); - cmdInfo_[cmd].func = commonCommandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - - for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { - const u8 cmd = commandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commandTable[i].flags | (commandTable[i].dirty << 8); - cmdInfo_[cmd].func = commandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - // Find commands missing from the table. - for (int i = 0; i < 0xEF; i++) { - if (dupeCheck.find((u8)i) == dupeCheck.end()) { - ERROR_LOG(G3D, "Command missing from table: %02x (%i)", i, i); - } - } - - // No need to flush before the tex scale/offset commands if we are baking - // the tex scale/offset into the vertices anyway. - UpdateCmdInfo(); + CheckGPUFeatures(); BuildReportingInfo(); @@ -166,18 +101,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) } } -void GPU_DX9::UpdateCmdInfo() { - if (g_Config.bSoftwareSkinning) { - cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; - } else { - cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexType; - } - - CheckGPUFeatures(); -} - void GPU_DX9::CheckGPUFeatures() { u32 features = 0; @@ -186,8 +109,9 @@ void GPU_DX9::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; features |= GPU_PREFER_CPU_DOWNLOAD; - // Accurate depth is required on AMD so we ignore the compat flag to disable it on those. See #9545 - if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || draw_->GetDeviceCaps().vendor == Draw::GPUVendor::VENDOR_AMD) { + auto vendor = draw_->GetDeviceCaps().vendor; + // Accurate depth is required on AMD/nVidia (for reverse Z) so we ignore the compat flag to disable it on those. See #9545 + if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || vendor == Draw::GPUVendor::VENDOR_AMD || vendor == Draw::GPUVendor::VENDOR_NVIDIA) { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } @@ -264,8 +188,8 @@ void GPU_DX9::InitClear() { void GPU_DX9::BeginHostFrame() { GPUCommon::BeginHostFrame(); - UpdateCmdInfo(); if (resized_) { + CheckGPUFeatures(); framebufferManager_->Resized(); drawEngine_.Resized(); shaderManagerDX9_->DirtyShader(); @@ -305,26 +229,6 @@ void GPU_DX9::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for framebufferManagerDX9_->SetDisplayFramebuffer(framebuf, stride, format); } -bool GPU_DX9::FramebufferDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->dirtyAfterDisplay; - vfb->dirtyAfterDisplay = false; - return dirty; - } - return true; -} - -bool GPU_DX9::FramebufferReallyDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->reallyDirtyAfterDisplay; - vfb->reallyDirtyAfterDisplay = false; - return dirty; - } - return true; -} - void GPU_DX9::CopyDisplayToOutput() { dxstate.depthWrite.set(true); dxstate.colorMask.set(true, true, true, true); @@ -340,44 +244,6 @@ void GPU_DX9::CopyDisplayToOutput() { gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } -// Maybe should write this in ASM... -void GPU_DX9::FastRunLoop(DisplayList &list) { - PROFILE_THIS_SCOPE("gpuloop"); - const CommandInfo *cmdInfo = cmdInfo_; - int dc = downcount; - for (; dc > 0; --dc) { - // We know that display list PCs have the upper nibble == 0 - no need to mask the pointer - const u32 op = *(const u32 *)(Memory::base + list.pc); - const u32 cmd = op >> 24; - const CommandInfo &info = cmdInfo[cmd]; - const u32 diff = op ^ gstate.cmdmem[cmd]; - if (diff == 0) { - if (info.flags & FLAG_EXECUTE) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } - } else { - uint64_t flags = info.flags; - if (flags & FLAG_FLUSHBEFOREONCHANGE) { - drawEngine_.Flush(); - } - gstate.cmdmem[cmd] = op; - if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } else { - uint64_t dirty = flags >> 8; - if (dirty) - gstate_c.Dirty(dirty); - } - } - list.pc += 4; - } - downcount = 0; -} - void GPU_DX9::FinishDeferred() { // This finishes reading any vertex data that is pending. drawEngine_.FinishDeferred(); @@ -410,84 +276,6 @@ void GPU_DX9::ExecuteOp(u32 op, u32 diff) { } } -void GPU_DX9::Execute_Prim(u32 op, u32 diff) { - // This drives all drawing. All other state we just buffer up, then we apply it only - // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. - - u32 data = op & 0xFFFFFF; - u32 count = data & 0xFFFF; - if (count == 0) - return; - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - SetDrawType(DRAW_PRIM, prim); - - // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. - - if (gstate.isAntiAliasEnabled()) { - // Discard AA lines in DOA - if (prim == GE_PRIM_LINE_STRIP) - return; - // Discard AA lines in Summon Night 5 - if ((prim == GE_PRIM_LINES) && gstate.isSkinningEnabled()) - return; - } - - // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - drawEngine_.SetupVertexDecoder(gstate.vertType); - // Rough estimate, not sure what's correct. - cyclesExecuted += EstimatePerVertexCost() * count; - return; - } - - u32 vertexAddr = gstate_c.vertexAddr; - if (!Memory::IsValidAddress(vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", vertexAddr); - return; - } - - void *verts = Memory::GetPointerUnchecked(vertexAddr); - void *inds = 0; - u32 vertexType = gstate.vertType; - if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - u32 indexAddr = gstate_c.indexAddr; - if (!Memory::IsValidAddress(indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", indexAddr); - return; - } - inds = Memory::GetPointerUnchecked(indexAddr); - } - -#ifndef MOBILE_DEVICE - if (prim > GE_PRIM_RECTANGLES) { - ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); - } -#endif - - if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { - vertexCost_ = EstimatePerVertexCost(); - } - gpuStats.vertexGPUCycles += vertexCost_ * count; - cyclesExecuted += vertexCost_* count; - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitPrim(verts, inds, prim, count, vertexType, &bytesRead); - - // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). - // Some games rely on this, they don't bother reloading VADDR and IADDR. - // The VADDR/IADDR registers are NOT updated. - AdvanceVerts(vertexType, count, bytesRead); -} - -void GPU_DX9::Execute_LoadClut(u32 op, u32 diff) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - textureCacheDX9_->LoadClut(gstate.getClutAddress(), gstate.getClutLoadBytes()); - // This could be used to "dirty" textures with clut. -} - void GPU_DX9::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 9c0da49c11..3fb4be032d 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -37,7 +37,7 @@ public: GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw); ~GPU_DX9(); - void CheckGPUFeatures(); + void CheckGPUFeatures() override; void PreExecuteOp(u32 op, u32 diff) override; void ExecuteOp(u32 op, u32 diff) override; @@ -51,26 +51,6 @@ public: void DoState(PointerWrap &p) override; void ClearShaderCache() override; - bool DecodeTexture(u8 *dest, const GPUgstate &state) override { - return textureCacheDX9_->DecodeTexture(dest, state); - } - bool FramebufferDirty() override; - bool FramebufferReallyDirty() override; - - void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override { - primaryInfo = reportingPrimaryInfo_; - fullInfo = reportingFullInfo_; - } - - typedef void (GPU_DX9::*CmdFunc)(u32 op, u32 diff); - struct CommandInfo { - uint64_t flags; - GPU_DX9::CmdFunc func; - }; - - void Execute_Prim(u32 op, u32 diff); - void Execute_TexSize0(u32 op, u32 diff); - void Execute_LoadClut(u32 op, u32 diff); // Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend. std::vector DebugGetShaderIDs(DebugShaderType shader) override; @@ -79,16 +59,12 @@ public: void BeginHostFrame() override; protected: - void FastRunLoop(DisplayList &list) override; void FinishDeferred() override; private: - void UpdateCmdInfo(); - void Flush() { drawEngine_.Flush(); } - // void ApplyDrawState(int prim); void CheckFlushOp(int cmd, u32 diff); void BuildReportingInfo(); @@ -105,13 +81,8 @@ private: DrawEngineDX9 drawEngine_; ShaderManagerDX9 *shaderManagerDX9_; - static CommandInfo cmdInfo_[256]; - int lastVsync_; int vertexCost_ = 0; - - std::string reportingPrimaryInfo_; - std::string reportingFullInfo_; }; } // namespace DX9 diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 5d070fc2c5..eae6854e95 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -314,7 +314,7 @@ void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) { } const uint64_t vsUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | -DIRTY_FOGCOEF | DIRTY_BONE_UNIFORMS | DIRTY_UVSCALEOFFSET | DIRTY_DEPTHRANGE | +DIRTY_FOGCOEF | DIRTY_UVSCALEOFFSET | DIRTY_DEPTHRANGE | DIRTY_AMBIENT | DIRTY_MATAMBIENTALPHA | DIRTY_MATSPECULAR | DIRTY_MATDIFFUSE | DIRTY_MATEMISSIVE | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3; void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { @@ -388,38 +388,6 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { ComputeGuardband(gb, 0.0f); VSSetFloatUniform4(CONST_VS_GUARDBAND, gb); } - // TODO: Could even set all bones in one go if they're all dirty. -#ifdef USE_BONE_ARRAY - if (u_bone != 0) { - float allBones[8 * 16]; - - bool allDirty = true; - for (int i = 0; i < numBones; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i); - } else { - allDirty = false; - } - } - if (allDirty) { - // Set them all with one call - //glUniformMatrix4fv(u_bone, numBones, GL_FALSE, allBones); - } else { - // Set them one by one. Could try to coalesce two in a row etc but too lazy. - for (int i = 0; i < numBones; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - //glUniformMatrix4fv(u_bone + i, 1, GL_FALSE, allBones + 16 * i); - } - } - } - } -#else - for (int i = 0; i < 8; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - VSSetMatrix4x3_3(CONST_VS_BONE0 + 3 * i, gstate.boneMatrix + 12 * i); - } - } -#endif // Texturing if (dirtyUniforms & DIRTY_UVSCALEOFFSET) { @@ -494,8 +462,8 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { } VSSetFloat24Uniform3(CONST_VS_LIGHTDIR + i, &gstate.ldir[i * 3]); VSSetFloat24Uniform3(CONST_VS_LIGHTATT + i, &gstate.latt[i * 3]); - VSSetFloat(CONST_VS_LIGHTANGLE + i, getFloat24(gstate.lcutoff[i])); - VSSetFloat(CONST_VS_LIGHTSPOTCOEF + i, getFloat24(gstate.lconv[i])); + float angle_spotCoef[4] = { getFloat24(gstate.lcutoff[i]), getFloat24(gstate.lconv[i]) }; + VSSetFloatUniform4(CONST_VS_LIGHTANGLE_SPOTCOEF + i, angle_spotCoef); VSSetColorUniform3(CONST_VS_LIGHTAMBIENT + i, gstate.lcolor[i * 3]); VSSetColorUniform3(CONST_VS_LIGHTDIFFUSE + i, gstate.lcolor[i * 3 + 1]); VSSetColorUniform3(CONST_VS_LIGHTSPECULAR + i, gstate.lcolor[i * 3 + 2]); diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 95f7b42718..6f51582cf2 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -181,7 +181,6 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer shaderManagerDX9_->DirtyLastShader(); - DisableState(); dxstate.colorMask.set(false, false, false, true); dxstate.stencilTest.enable(); dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 798fec698b..11876f12b4 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -171,7 +171,6 @@ void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { dxstate.texMaxMipLevel.set(0); dxstate.texMipLodBias.set(0.0f); } - entry.lodBias = lodBias; } else { dxstate.texMaxMipLevel.set(0); dxstate.texMipLodBias.set(0.0f); @@ -788,12 +787,6 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re texture->UnlockRect(level); } -bool TextureCacheDX9::DecodeTexture(u8 *output, const GPUgstate &state) -{ - OutputDebugStringA("TextureCache::DecodeTexture : FixMe\r\n"); - return true; -} - bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { SetTexture(true); ApplyTexture(); diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 451cb922c5..a4c19572f4 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -49,9 +49,6 @@ public: shaderManager_ = sm; } - // Only used by Qt UI? - bool DecodeTexture(u8 *output, const GPUgstate &state); - void ForgetLastTexture() override; void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 8fb45d34cc..7fa051c7aa 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -38,25 +38,6 @@ namespace DX9 { -// The PSP does not have a proper triangle clipper on the sides. It does have on for the front plane. -// It has a guard band though and can rasterize rather large -// triangles that go outside the viewport. However, there are limits, and it will drop triangles that are very -// large. Some games appear to draw broken geometry, probably game bugs that were never discovered because the PSP -// would drop the geometry, including Parappa The Rapper in an obscure case and Outrun. Try to get rid of those -// triangles by setting the W of one of the vertices to NaN if they are discovered. - -static const char * const boneWeightAttrDecl[9] = { - "#ERROR#", - "float a_w1:TEXCOORD1;\n", - "float2 a_w1:TEXCOORD1;\n", - "float3 a_w1:TEXCOORD1;\n", - "float4 a_w1:TEXCOORD1;\n", - "float4 a_w1:TEXCOORD1;\n float a_w2:TEXCOORD2;\n", - "float4 a_w1:TEXCOORD1;\n float2 a_w2:TEXCOORD2;\n", - "float4 a_w1:TEXCOORD1;\n float3 a_w2:TEXCOORD2;\n", - "float4 a_w1:TEXCOORD1;\n float4 a_w2:TEXCOORD2;\n", -}; - enum DoLightComputation { LIGHT_OFF, LIGHT_SHADE, @@ -108,7 +89,6 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage bool flipNormal = id.Bit(VS_BIT_NORM_REVERSE); int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); - bool enableBones = id.Bit(VS_BIT_ENABLE_BONES); bool enableLighting = id.Bit(VS_BIT_LIGHTING_ENABLE); int matUpdate = id.Bits(VS_BIT_MATERIAL_UPDATE, 3); @@ -130,12 +110,6 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage } } - int numBoneWeights = 0; - int boneWeightScale = id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2); - if (enableBones) { - numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); - } - if (lang == HLSL_DX9) { WRITE(p, "#pragma warning( disable : 3571 )\n"); if (isModeThrough) { @@ -158,15 +132,6 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, "float4x3 u_view : register(c%i);\n", CONST_VS_VIEW); if (doTextureTransform) WRITE(p, "float4x3 u_tex : register(c%i);\n", CONST_VS_TEXMTX); - if (enableBones) { -#ifdef USE_BONE_ARRAY - WRITE(p, "float4x3 u_bone[%i] : register(c%i);\n", numBones, CONST_VS_BONE0); -#else - for (int i = 0; i < numBoneWeights; i++) { - WRITE(p, "float4x3 u_bone%i : register(c%i);\n", i, CONST_VS_BONE0 + i * 3); - } -#endif - } if (doTexture) { WRITE(p, "float4 u_uvscaleoffset : register(c%i);\n", CONST_VS_UVSCALEOFFSET); } @@ -184,8 +149,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN) { WRITE(p, "float3 u_lightdir%i : register(c%i);\n", i, CONST_VS_LIGHTDIR + i); - WRITE(p, "float4 u_lightangle%i : register(c%i);\n", i, CONST_VS_LIGHTANGLE + i); - WRITE(p, "float4 u_lightspotCoef%i : register(c%i);\n", i, CONST_VS_LIGHTSPOTCOEF + i); + WRITE(p, "float4 u_lightangle_spotCoef%i : register(c%i);\n", i, CONST_VS_LIGHTANGLE_SPOTCOEF + i); } WRITE(p, "float3 u_lightambient%i : register(c%i);\n", i, CONST_VS_LIGHTAMBIENT + i); WRITE(p, "float3 u_lightdiffuse%i : register(c%i);\n", i, CONST_VS_LIGHTDIFFUSE + i); @@ -211,7 +175,6 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage } else { WRITE(p, "cbuffer base : register(b0) {\n%s};\n", cb_baseStr); WRITE(p, "cbuffer lights: register(b1) {\n%s};\n", cb_vs_lightsStr); - WRITE(p, "cbuffer bones : register(b2) {\n%s};\n", cb_vs_bonesStr); } // And the "varyings". @@ -221,9 +184,6 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage if ((doSpline || doBezier) && lang == HLSL_D3D11) { WRITE(p, " uint instanceId : SV_InstanceID;\n"); } - if (enableBones) { - WRITE(p, " %s", boneWeightAttrDecl[numBoneWeights]); - } if (doTexture && hasTexcoord) { WRITE(p, " float2 texcoord : TEXCOORD0;\n"); } @@ -427,184 +387,113 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage } WRITE(p, " Out.gl_Position = outPos;\n"); } else { - // Step 1: World Transform / Skinning - if (!enableBones) { - // Hardware tessellation - if (doSpline || doBezier) { - WRITE(p, " uint num_patches_u = %s;\n", doBezier ? "(u_spline_count_u - 1) / 3u" : "u_spline_count_u - 3"); - WRITE(p, " float2 tess_pos = In.position.xy;\n"); - WRITE(p, " int u = In.instanceId %% num_patches_u;\n"); - WRITE(p, " int v = In.instanceId / num_patches_u;\n"); - WRITE(p, " int2 patch_pos = int2(u, v);\n"); - WRITE(p, " float3 _pos[16];\n"); - WRITE(p, " float2 _tex[16];\n"); - WRITE(p, " float4 _col[16];\n"); - WRITE(p, " int idx;\n"); - WRITE(p, " int2 index;\n"); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - WRITE(p, " idx = (%i + v%s) * u_spline_count_u + (%i + u%s);\n", i, doBezier ? " * 3" : "", j, doBezier ? " * 3" : ""); - WRITE(p, " index = int2(idx, 0);\n"); - WRITE(p, " _pos[%i] = u_tess_pos_tex.Load(index).xyz;\n", i * 4 + j); - if (doTexture && hasTexcoord && hasTexcoordTess) - WRITE(p, " _tex[%i] = u_tess_tex_tex.Load(index).xy;\n", i * 4 + j); - if (hasColor && hasColorTess) - WRITE(p, " _col[%i] = u_tess_col_tex.Load(index).rgba;\n", i * 4 + j); - } - } - WRITE(p, " float2 weights[4];\n"); - if (doBezier) { - // Bernstein 3D - WRITE(p, " weights[0] = (1.0 - tess_pos) * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); - WRITE(p, " weights[1] = 3.0 * tess_pos * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); - WRITE(p, " weights[2] = 3.0 * tess_pos * tess_pos * (1.0 - tess_pos);\n"); - WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); - } else if (doSpline) { - WRITE(p, " int2 spline_num_patches = int2(u_spline_count_u - 3, u_spline_count_v - 3);\n"); - WRITE(p, " int2 spline_type = int2(u_spline_type_u, u_spline_type_v);\n"); - WRITE(p, " float2 knots[6];\n"); - WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); - WRITE(p, " spline_weight(tess_pos + patch_pos, knots, weights);\n"); - } - WRITE(p, " float3 pos = tess_sample(_pos, weights);\n"); - if (doTexture && hasTexcoord) { - if (hasTexcoordTess) - WRITE(p, " float2 tex = tess_sample(_tex, weights);\n"); - else - WRITE(p, " float2 tex = tess_pos + patch_pos;\n"); - } - if (hasColor) { - if (hasColorTess) - WRITE(p, " float4 col = tess_sample(_col, weights);\n"); - else - WRITE(p, " float4 col = u_tess_col_tex.Load(int2(0, 0)).rgba;\n"); - } - if (hasNormal) { - // Curved surface is probably always need to compute normal(not sampling from control points) - if (doBezier) { - // Bernstein derivative - WRITE(p, " float2 bernderiv[4];\n"); - WRITE(p, " bernderiv[0] = -3.0 * (tess_pos - 1.0) * (tess_pos - 1.0); \n"); - WRITE(p, " bernderiv[1] = 9.0 * tess_pos * tess_pos - 12.0 * tess_pos + 3.0; \n"); - WRITE(p, " bernderiv[2] = 3.0 * (2.0 - 3.0 * tess_pos) * tess_pos; \n"); - WRITE(p, " bernderiv[3] = 3.0 * tess_pos * tess_pos; \n"); - - WRITE(p, " float2 bernderiv_u[4];\n"); - WRITE(p, " float2 bernderiv_v[4];\n"); - WRITE(p, " for (int i = 0; i < 4; i++) {\n"); - WRITE(p, " bernderiv_u[i] = float2(bernderiv[i].x, weights[i].y);\n"); - WRITE(p, " bernderiv_v[i] = float2(weights[i].x, bernderiv[i].y);\n"); - WRITE(p, " }\n"); - - WRITE(p, " float3 du = tess_sample(_pos, bernderiv_u);\n"); - WRITE(p, " float3 dv = tess_sample(_pos, bernderiv_v);\n"); - } else if (doSpline) { - WRITE(p, " float2 tess_next_u = float2(In.normal.x, 0.0);\n"); - WRITE(p, " float2 tess_next_v = float2(0.0, In.normal.y);\n"); - // Right - WRITE(p, " float2 tess_pos_r = tess_pos + tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_r + patch_pos, knots, weights);\n"); - WRITE(p, " float3 pos_r = tess_sample(_pos, weights);\n"); - // Left - WRITE(p, " float2 tess_pos_l = tess_pos - tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_l + patch_pos, knots, weights);\n"); - WRITE(p, " float3 pos_l = tess_sample(_pos, weights);\n"); - // Down - WRITE(p, " float2 tess_pos_d = tess_pos + tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_d + patch_pos, knots, weights);\n"); - WRITE(p, " float3 pos_d = tess_sample(_pos, weights);\n"); - // Up - WRITE(p, " float2 tess_pos_u = tess_pos - tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_u + patch_pos, knots, weights);\n"); - WRITE(p, " float3 pos_u = tess_sample(_pos, weights);\n"); - - WRITE(p, " float3 du = pos_r - pos_l;\n"); - WRITE(p, " float3 dv = pos_d - pos_u;\n"); - } - WRITE(p, " float3 nrm = cross(du, dv);\n"); - WRITE(p, " nrm = normalize(nrm);\n"); - } - WRITE(p, " float3 worldpos = mul(float4(pos.xyz, 1.0), u_world);\n"); - if (hasNormal) - WRITE(p, " float3 worldnormal = normalize(mul(float4(%snrm, 0.0), u_world));\n", flipNormalTess ? "-" : ""); - else - WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n"); - } else { - // No skinning, just standard T&L. - WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world);\n"); - if (hasNormal) - WRITE(p, " float3 worldnormal = normalize(mul(float4(%sIn.normal, 0.0), u_world));\n", flipNormal ? "-" : ""); - else - WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n"); - } - } else { - static const char * const boneWeightAttr[8] = { - "a_w1.x", "a_w1.y", "a_w1.z", "a_w1.w", - "a_w2.x", "a_w2.y", "a_w2.z", "a_w2.w", - }; - -#if defined(USE_FOR_LOOP) && defined(USE_BONE_ARRAY) - - // To loop through the weights, we unfortunately need to put them in a float array. - // GLSL ES sucks - no way to directly initialize an array! - switch (numBoneWeights) { - case 1: WRITE(p, " float w[1]; w[0] = a_w1;\n"); break; - case 2: WRITE(p, " float w[2]; w[0] = a_w1.x; w[1] = a_w1.y;\n"); break; - case 3: WRITE(p, " float w[3]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z;\n"); break; - case 4: WRITE(p, " float w[4]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w;\n"); break; - case 5: WRITE(p, " float w[5]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2;\n"); break; - case 6: WRITE(p, " float w[6]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y;\n"); break; - case 7: WRITE(p, " float w[7]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y; w[6] = a_w2.z;\n"); break; - case 8: WRITE(p, " float w[8]; w[0] = a_w1.x; w[1] = a_w1.y; w[2] = a_w1.z; w[3] = a_w1.w; w[4] = a_w2.x; w[5] = a_w2.y; w[6] = a_w2.z; w[7] = a_w2.w;\n"); break; - } - - WRITE(p, " mat4 skinMatrix = w[0] * u_bone[0];\n"); - if (numBoneWeights > 1) { - WRITE(p, " for (int i = 1; i < %i; i++) {\n", numBoneWeights); - WRITE(p, " skinMatrix += w[i] * u_bone[i];\n"); - WRITE(p, " }\n"); - } - -#else - if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) { - if (numBoneWeights == 1) - WRITE(p, " float4x3 skinMatrix = mul(In.a_w1, u_bone[0])"); - else - WRITE(p, " float4x3 skinMatrix = mul(In.a_w1.x, u_bone[0])"); - for (int i = 1; i < numBoneWeights; i++) { - const char *weightAttr = boneWeightAttr[i]; - // workaround for "cant do .x of scalar" issue - if (numBoneWeights == 1 && i == 0) weightAttr = "a_w1"; - if (numBoneWeights == 5 && i == 4) weightAttr = "a_w2"; - WRITE(p, " + mul(In.%s, u_bone[%i])", weightAttr, i); - } - } else { - if (numBoneWeights == 1) - WRITE(p, " float4x3 skinMatrix = mul(In.a_w1, u_bone0)"); - else - WRITE(p, " float4x3 skinMatrix = mul(In.a_w1.x, u_bone0)"); - for (int i = 1; i < numBoneWeights; i++) { - const char *weightAttr = boneWeightAttr[i]; - // workaround for "cant do .x of scalar" issue - if (numBoneWeights == 1 && i == 0) weightAttr = "a_w1"; - if (numBoneWeights == 5 && i == 4) weightAttr = "a_w2"; - WRITE(p, " + mul(In.%s, u_bone%i)", weightAttr, i); + // Step 1: World Transform + // Hardware tessellation + if (doSpline || doBezier) { + WRITE(p, " uint num_patches_u = %s;\n", doBezier ? "(u_spline_count_u - 1) / 3u" : "u_spline_count_u - 3"); + WRITE(p, " float2 tess_pos = In.position.xy;\n"); + WRITE(p, " int u = In.instanceId %% num_patches_u;\n"); + WRITE(p, " int v = In.instanceId / num_patches_u;\n"); + WRITE(p, " int2 patch_pos = int2(u, v);\n"); + WRITE(p, " float3 _pos[16];\n"); + WRITE(p, " float2 _tex[16];\n"); + WRITE(p, " float4 _col[16];\n"); + WRITE(p, " int idx;\n"); + WRITE(p, " int2 index;\n"); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + WRITE(p, " idx = (%i + v%s) * u_spline_count_u + (%i + u%s);\n", i, doBezier ? " * 3" : "", j, doBezier ? " * 3" : ""); + WRITE(p, " index = int2(idx, 0);\n"); + WRITE(p, " _pos[%i] = u_tess_pos_tex.Load(index).xyz;\n", i * 4 + j); + if (doTexture && hasTexcoord && hasTexcoordTess) + WRITE(p, " _tex[%i] = u_tess_tex_tex.Load(index).xy;\n", i * 4 + j); + if (hasColor && hasColorTess) + WRITE(p, " _col[%i] = u_tess_col_tex.Load(index).rgba;\n", i * 4 + j); } } -#endif - - WRITE(p, ";\n"); - - // Trying to simplify this results in bugs in LBP... - WRITE(p, " float3 skinnedpos = mul(float4(In.position.xyz, 1.0), skinMatrix);\n"); - WRITE(p, " float3 worldpos = mul(float4(skinnedpos, 1.0), u_world);\n"); - + WRITE(p, " float2 weights[4];\n"); + if (doBezier) { + // Bernstein 3D + WRITE(p, " weights[0] = (1.0 - tess_pos) * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); + WRITE(p, " weights[1] = 3.0 * tess_pos * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); + WRITE(p, " weights[2] = 3.0 * tess_pos * tess_pos * (1.0 - tess_pos);\n"); + WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); + } else if (doSpline) { + WRITE(p, " int2 spline_num_patches = int2(u_spline_count_u - 3, u_spline_count_v - 3);\n"); + WRITE(p, " int2 spline_type = int2(u_spline_type_u, u_spline_type_v);\n"); + WRITE(p, " float2 knots[6];\n"); + WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); + WRITE(p, " spline_weight(tess_pos + patch_pos, knots, weights);\n"); + } + WRITE(p, " float3 pos = tess_sample(_pos, weights);\n"); + if (doTexture && hasTexcoord) { + if (hasTexcoordTess) + WRITE(p, " float2 tex = tess_sample(_tex, weights);\n"); + else + WRITE(p, " float2 tex = tess_pos + patch_pos;\n"); + } + if (hasColor) { + if (hasColorTess) + WRITE(p, " float4 col = tess_sample(_col, weights);\n"); + else + WRITE(p, " float4 col = u_tess_col_tex.Load(int2(0, 0)).rgba;\n"); + } if (hasNormal) { - WRITE(p, " float3 skinnednormal = mul(float4(%sIn.normal, 0.0), skinMatrix);\n", flipNormal ? "-" : ""); - } else { - WRITE(p, " float3 skinnednormal = mul(float4(0.0, 0.0, %s1.0, 0.0), skinMatrix);\n", flipNormal ? "-" : ""); + // Curved surface is probably always need to compute normal(not sampling from control points) + if (doBezier) { + // Bernstein derivative + WRITE(p, " float2 bernderiv[4];\n"); + WRITE(p, " bernderiv[0] = -3.0 * (tess_pos - 1.0) * (tess_pos - 1.0); \n"); + WRITE(p, " bernderiv[1] = 9.0 * tess_pos * tess_pos - 12.0 * tess_pos + 3.0; \n"); + WRITE(p, " bernderiv[2] = 3.0 * (2.0 - 3.0 * tess_pos) * tess_pos; \n"); + WRITE(p, " bernderiv[3] = 3.0 * tess_pos * tess_pos; \n"); + + WRITE(p, " float2 bernderiv_u[4];\n"); + WRITE(p, " float2 bernderiv_v[4];\n"); + WRITE(p, " for (int i = 0; i < 4; i++) {\n"); + WRITE(p, " bernderiv_u[i] = float2(bernderiv[i].x, weights[i].y);\n"); + WRITE(p, " bernderiv_v[i] = float2(weights[i].x, bernderiv[i].y);\n"); + WRITE(p, " }\n"); + + WRITE(p, " float3 du = tess_sample(_pos, bernderiv_u);\n"); + WRITE(p, " float3 dv = tess_sample(_pos, bernderiv_v);\n"); + } else if (doSpline) { + WRITE(p, " float2 tess_next_u = float2(In.normal.x, 0.0);\n"); + WRITE(p, " float2 tess_next_v = float2(0.0, In.normal.y);\n"); + // Right + WRITE(p, " float2 tess_pos_r = tess_pos + tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_r + patch_pos, knots, weights);\n"); + WRITE(p, " float3 pos_r = tess_sample(_pos, weights);\n"); + // Left + WRITE(p, " float2 tess_pos_l = tess_pos - tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_l + patch_pos, knots, weights);\n"); + WRITE(p, " float3 pos_l = tess_sample(_pos, weights);\n"); + // Down + WRITE(p, " float2 tess_pos_d = tess_pos + tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_d + patch_pos, knots, weights);\n"); + WRITE(p, " float3 pos_d = tess_sample(_pos, weights);\n"); + // Up + WRITE(p, " float2 tess_pos_u = tess_pos - tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_u + patch_pos, knots, weights);\n"); + WRITE(p, " float3 pos_u = tess_sample(_pos, weights);\n"); + + WRITE(p, " float3 du = pos_r - pos_l;\n"); + WRITE(p, " float3 dv = pos_d - pos_u;\n"); + } + WRITE(p, " float3 nrm = cross(du, dv);\n"); + WRITE(p, " nrm = normalize(nrm);\n"); } - WRITE(p, " float3 worldnormal = normalize(mul(float4(skinnednormal, 0.0), u_world));\n"); + WRITE(p, " float3 worldpos = mul(float4(pos.xyz, 1.0), u_world);\n"); + if (hasNormal) + WRITE(p, " float3 worldnormal = normalize(mul(float4(%snrm, 0.0), u_world));\n", flipNormalTess ? "-" : ""); + else + WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n"); + } else { + WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world);\n"); + if (hasNormal) + WRITE(p, " float3 worldnormal = normalize(mul(float4(%sIn.normal, 0.0), u_world));\n", flipNormal ? "-" : ""); + else + WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n"); } WRITE(p, " float4 viewPos = float4(mul(float4(worldpos, 1.0), u_view), 1.0);\n"); @@ -713,8 +602,8 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: WRITE(p, " float angle%i = dot(normalize(u_lightdir%i), toLight);\n", i, i); - WRITE(p, " if (angle%i >= u_lightangle%i.x) {\n", i, i); - WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, u_lightspotCoef%i.x);\n", i, i, i); + WRITE(p, " if (angle%i >= u_lightangle_spotCoef%i.x) {\n", i, i); + WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, u_lightangle_spotCoef%i.y);\n", i, i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.h b/GPU/Directx9/VertexShaderGeneratorDX9.h index b9c13e3b7b..82d26c68d9 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.h +++ b/GPU/Directx9/VertexShaderGeneratorDX9.h @@ -21,40 +21,30 @@ namespace DX9 { -// #define USE_BONE_ARRAY - void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang = HLSL_DX9); -#define CONST_VS_PROJ 0 -#define CONST_VS_PROJ_THROUGH 4 -#define CONST_VS_VIEW 8 -#define CONST_VS_WORLD 11 -#define CONST_VS_TEXMTX 14 -#define CONST_VS_UVSCALEOFFSET 17 -#define CONST_VS_FOGCOEF 18 -#define CONST_VS_AMBIENT 19 -#define CONST_VS_BONE0 20 -#define CONST_VS_BONE1 23 -#define CONST_VS_BONE2 26 -#define CONST_VS_BONE3 29 -#define CONST_VS_BONE4 32 -#define CONST_VS_BONE5 35 -#define CONST_VS_BONE6 38 -#define CONST_VS_BONE7 41 -#define CONST_VS_BONE8 44 -#define CONST_VS_MATAMBIENTALPHA 47 -#define CONST_VS_MATDIFFUSE 48 -#define CONST_VS_MATSPECULAR 49 -#define CONST_VS_MATEMISSIVE 50 -#define CONST_VS_LIGHTPOS 51 -#define CONST_VS_LIGHTDIR 55 -#define CONST_VS_LIGHTATT 59 -#define CONST_VS_LIGHTANGLE 63 -#define CONST_VS_LIGHTSPOTCOEF 67 -#define CONST_VS_LIGHTDIFFUSE 71 -#define CONST_VS_LIGHTSPECULAR 75 -#define CONST_VS_LIGHTAMBIENT 79 -#define CONST_VS_DEPTHRANGE 83 + enum { + CONST_VS_PROJ = 0, + CONST_VS_PROJ_THROUGH = 4, + CONST_VS_VIEW = 8, + CONST_VS_WORLD = 11, + CONST_VS_TEXMTX = 14, + CONST_VS_UVSCALEOFFSET = 17, + CONST_VS_FOGCOEF = 18, + CONST_VS_AMBIENT = 19, + CONST_VS_MATAMBIENTALPHA = 20, + CONST_VS_MATDIFFUSE = 21, + CONST_VS_MATSPECULAR = 22, + CONST_VS_MATEMISSIVE = 23, + CONST_VS_LIGHTPOS = 24, + CONST_VS_LIGHTDIR = 28, + CONST_VS_LIGHTATT = 32, + CONST_VS_LIGHTANGLE_SPOTCOEF = 36, + CONST_VS_LIGHTDIFFUSE = 40, + CONST_VS_LIGHTSPECULAR = 44, + CONST_VS_LIGHTAMBIENT = 48, + CONST_VS_DEPTHRANGE = 52, + }; #define CONST_VS_GUARDBAND 84 }; diff --git a/GPU/GLES/DepalettizeShaderGLES.cpp b/GPU/GLES/DepalettizeShaderGLES.cpp index 71ef33d4c2..77614c93df 100644 --- a/GPU/GLES/DepalettizeShaderGLES.cpp +++ b/GPU/GLES/DepalettizeShaderGLES.cpp @@ -23,7 +23,6 @@ #include "Core/Reporting.h" #include "DepalettizeShaderGLES.h" #include "GPU/GLES/TextureCacheGLES.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/Common/DepalettizeShaderCommon.h" #ifdef _WIN32 @@ -58,38 +57,8 @@ static const char *depalVShader300 = " gl_Position = a_position;\n" "}\n"; - -static bool CheckShaderCompileSuccess(GLuint shader, const char *code) { - GLint success; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (!success) { -#define MAX_INFO_LOG_SIZE 2048 - GLchar infoLog[MAX_INFO_LOG_SIZE]; - GLsizei len; - glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog); - infoLog[len] = '\0'; -#ifdef __ANDROID__ - ELOG("Error in shader compilation! %s\n", infoLog); - ELOG("Shader source:\n%s\n", (const char *)code); -#endif - ERROR_LOG(G3D, "Error in shader compilation!\n"); - ERROR_LOG(G3D, "Info log: %s\n", infoLog); - ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); -#ifdef SHADERLOG - OutputDebugStringUTF8(infoLog); -#endif - shader = 0; - return false; - } else { - DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code); -#ifdef SHADERLOG - OutputDebugStringUTF8(code); -#endif - return true; - } -} - -DepalShaderCacheGLES::DepalShaderCacheGLES() { +DepalShaderCacheGLES::DepalShaderCacheGLES(Draw::DrawContext *draw) { + render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); // Pre-build the vertex program useGL3_ = gl_extensions.GLES3 || gl_extensions.VersionGEThan(3, 3); @@ -102,25 +71,12 @@ DepalShaderCacheGLES::~DepalShaderCacheGLES() { } bool DepalShaderCacheGLES::CreateVertexShader() { - if (vertexShaderFailed_) { - return false; - } - - vertexShader_ = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader_, 1, useGL3_ ? &depalVShader300 : &depalVShader100, 0); - glCompileShader(vertexShader_); - - if (!CheckShaderCompileSuccess(vertexShader_, useGL3_ ? depalVShader300 : depalVShader100)) { - glDeleteShader(vertexShader_); - vertexShader_ = 0; - // Don't try to recompile. - vertexShaderFailed_ = true; - } - - return !vertexShaderFailed_; + std::string src(useGL3_ ? depalVShader300 : depalVShader100); + vertexShader_ = render_->CreateShader(GL_VERTEX_SHADER, src, "depal"); + return true; } -GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) { +GLRTexture *DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) { u32 clutId = GetClutID(clutFormat, clutHash); auto oldtex = texCache_.find(clutId); @@ -133,18 +89,13 @@ GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u3 int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512; DepalTexture *tex = new DepalTexture(); - glGenTextures(1, &tex->texture); - glBindTexture(GL_TEXTURE_2D, tex->texture); + tex->texture = render_->CreateTexture(GL_TEXTURE_2D); GLuint components = dstFmt == GL_UNSIGNED_SHORT_5_6_5 ? GL_RGB : GL_RGBA; - GLuint components2 = components; - glTexImage2D(GL_TEXTURE_2D, 0, components, texturePixels, 1, 0, components2, dstFmt, (void *)rawClut); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + uint8_t *clutCopy = new uint8_t[1024]; + memcpy(clutCopy, rawClut, 1024); + render_->TextureImage(tex->texture, 0, texturePixels, 1, components, components2, dstFmt, clutCopy, GLRAllocType::NEW, false); tex->lastFrame = gpuStats.numFlips; texCache_[clutId] = tex; @@ -153,20 +104,20 @@ GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u3 void DepalShaderCacheGLES::Clear() { for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) { - glDeleteShader(shader->second->fragShader); + render_->DeleteShader(shader->second->fragShader); if (shader->second->program) { - glDeleteProgram(shader->second->program); + render_->DeleteProgram(shader->second->program); } delete shader->second; } cache_.clear(); for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) { - glDeleteTextures(1, &tex->second->texture); + render_->DeleteTexture(tex->second->texture); delete tex->second; } texCache_.clear(); if (vertexShader_) { - glDeleteShader(vertexShader_); + render_->DeleteShader(vertexShader_); vertexShader_ = 0; } } @@ -174,7 +125,7 @@ void DepalShaderCacheGLES::Clear() { void DepalShaderCacheGLES::Decimate() { for (auto tex = texCache_.begin(); tex != texCache_.end(); ) { if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) { - glDeleteTextures(1, &tex->second->texture); + render_->DeleteTexture(tex->second->texture); delete tex->second; texCache_.erase(tex++); } else { @@ -188,10 +139,14 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBuf auto shader = cache_.find(id); if (shader != cache_.end()) { + DepalShader *depal = shader->second; + // If compile failed previously, try to recover. + if (depal->fragShader->failed || vertexShader_->failed) + return nullptr; return shader->second; } - if (vertexShader_ == 0) { + if (!vertexShader_) { if (!CreateVertexShader()) { // The vertex shader failed, no need to bother trying the fragment. return nullptr; @@ -201,64 +156,33 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBuf char *buffer = new char[2048]; GenerateDepalShader(buffer, pixelFormat, useGL3_ ? GLSL_300 : GLSL_140); - - GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER); - - const char *buf = buffer; - glShaderSource(fragShader, 1, &buf, 0); - glCompileShader(fragShader); - - CheckShaderCompileSuccess(fragShader, buffer); - - GLuint program = glCreateProgram(); - glAttachShader(program, vertexShader_); - glAttachShader(program, fragShader); - glBindAttribLocation(program, 0, "a_position"); - glBindAttribLocation(program, 1, "a_texcoord0"); - - glLinkProgram(program); - glUseProgram(program); - - GLint u_tex = glGetUniformLocation(program, "tex"); - GLint u_pal = glGetUniformLocation(program, "pal"); - - glUniform1i(u_tex, 0); - glUniform1i(u_pal, 3); + std::string src(buffer); + GLRShader *fragShader = render_->CreateShader(GL_FRAGMENT_SHADER, src, "depal"); DepalShader *depal = new DepalShader(); + + std::vector semantics; + semantics.push_back({ 0, "a_position" }); + semantics.push_back({ 1, "a_texcoord0" }); + + std::vector queries; + queries.push_back({ &depal->u_tex, "tex" }); + queries.push_back({ &depal->u_pal, "pal" }); + + std::vector initializer; + initializer.push_back({ &depal->u_tex, 0, 0 }); + initializer.push_back({ &depal->u_pal, 0, 3 }); + + std::vector shaders{ vertexShader_, fragShader }; + + GLRProgram *program = render_->CreateProgram(shaders, semantics, queries, initializer, false); + depal->program = program; depal->fragShader = fragShader; depal->code = buffer; cache_[id] = depal; - GLint linkStatus = GL_FALSE; - glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); - if (linkStatus != GL_TRUE) { - GLint bufLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); - if (bufLength) { - char* errorbuf = new char[bufLength]; - glGetProgramInfoLog(program, bufLength, NULL, errorbuf); -#ifdef SHADERLOG - OutputDebugStringUTF8(buffer); - OutputDebugStringUTF8(errorbuf); -#endif - ERROR_LOG(G3D, "Could not link program:\n %s \n\n %s", errorbuf, buf); - delete[] errorbuf; // we're dead! - } - - // Since it failed, let's mark it in the cache so we don't keep retrying. - // That will only make it slower. - depal->program = 0; - - // We will delete the shader later in Clear(). - glDeleteProgram(program); - } else { - depal->a_position = glGetAttribLocation(program, "a_position"); - depal->a_texcoord0 = glGetAttribLocation(program, "a_texcoord0"); - } - delete[] buffer; return depal->program ? depal : nullptr; } diff --git a/GPU/GLES/DepalettizeShaderGLES.h b/GPU/GLES/DepalettizeShaderGLES.h index a32acb2cb3..6fd9749fec 100644 --- a/GPU/GLES/DepalettizeShaderGLES.h +++ b/GPU/GLES/DepalettizeShaderGLES.h @@ -19,34 +19,36 @@ #include "Common/CommonTypes.h" #include "gfx/gl_common.h" +#include "thin3d/thin3d.h" +#include "thin3d/GLRenderManager.h" #include "GPU/ge_constants.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/DepalettizeShaderCommon.h" class DepalShader { public: - GLuint program; - GLuint fragShader; - GLint a_position; - GLint a_texcoord0; + GLRProgram *program; + GLRShader *fragShader; + GLint u_tex; + GLint u_pal; std::string code; }; class DepalTexture { public: - GLuint texture; + GLRTexture *texture; int lastFrame; }; // Caches both shaders and palette textures. class DepalShaderCacheGLES : public DepalShaderCacheCommon { public: - DepalShaderCacheGLES(); + DepalShaderCacheGLES(Draw::DrawContext *draw); ~DepalShaderCacheGLES(); // This also uploads the palette and binds the correct texture. DepalShader *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat); - GLuint GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut); + GLRTexture *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut); void Clear(); void Decimate(); std::vector DebugGetShaderIDs(DebugShaderType type); @@ -55,9 +57,10 @@ public: private: bool CreateVertexShader(); + GLRenderManager *render_; bool useGL3_; bool vertexShaderFailed_; - GLuint vertexShader_; + GLRShader *vertexShader_; std::map cache_; std::map texCache_; }; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 7cba85b02b..24c84b616a 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -15,52 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -// Ideas for speeding things up on mobile OpenGL ES implementations -// -// Use superbuffers! Yes I just invented that name. -// -// The idea is to avoid respecifying the vertex format between every draw call (multiple glVertexAttribPointer ...) -// by combining the contents of multiple draw calls into one buffer, as long as -// they have exactly the same output vertex format. (different input formats is fine! This way -// we can combine the data for multiple draws with different numbers of bones, as we consider numbones < 4 to be = 4) -// into one VBO. -// -// This will likely be a win because I believe that between every change of VBO + glVertexAttribPointer*N, the driver will -// perform a lot of validation, probably at draw call time, while all the validation can be skipped if the only thing -// that changes between two draw calls is simple state or texture or a matrix etc, not anything vertex related. -// Also the driver will have to manage hundreds instead of thousands of VBOs in games like GTA. -// -// * Every 10 frames or something, do the following: -// - Frame 1: -// + Mark all drawn buffers with in-frame sequence numbers (alternatively, -// just log them in an array) -// - Frame 2 (beginning?): -// + Take adjacent buffers that have the same output vertex format, and add them -// to a list of buffers to combine. Create said buffers with appropriate sizes -// and precompute the offsets that the draws should be written into. -// - Frame 2 (end): -// + Actually do the work of combining the buffers. This probably means re-decoding -// the vertices into a new one. Will also have to apply index offsets. -// -// Also need to change the drawing code so that we don't glBindBuffer and respecify glVAP if -// two subsequent drawcalls come from the same superbuffer. -// -// Or we ignore all of this including vertex caching and simply find a way to do highly optimized vertex streaming, -// like Dolphin is trying to. That will likely never be able to reach the same speed as perfectly optimized -// superbuffers though. For this we will have to JIT the vertex decoder but that's not too hard. -// -// Now, when do we delete superbuffers? Maybe when half the buffers within have been killed? -// -// Another idea for GTA which switches textures a lot while not changing much other state is to use ES 3 Array -// textures, if they are the same size (even if they aren't, might be okay to simply resize the textures to match -// if they're just a multiple of 2 away) or something. Then we'd have to add a W texture coordinate to choose the -// texture within the bound texture array to the vertex data when merging into superbuffers. -// -// There are even more things to try. For games that do matrix palette skinning by quickly switching bones and -// just drawing a few triangles per call (NBA, FF:CC, Tekken 6 etc) we could even collect matrices, upload them -// all at once, writing matrix indices into the vertices in addition to the weights, and then doing a single -// draw call with specially generated shader to draw the whole mesh. This code will be seriously complex though. - #include "base/logging.h" #include "base/timeutil.h" @@ -83,7 +37,6 @@ #include "GPU/Common/SplineCommon.h" #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/Common/SoftwareTransformCommon.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/FragmentTestCacheGLES.h" #include "GPU/GLES/StateMappingGLES.h" #include "GPU/GLES/TextureCacheGLES.h" @@ -91,7 +44,7 @@ #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/GPU_GLES.h" -extern const GLuint glprim[8] = { +const GLuint glprim[8] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, @@ -115,7 +68,8 @@ enum { enum { VAI_KILL_AGE = 120, VAI_UNRELIABLE_KILL_AGE = 240, VAI_UNRELIABLE_KILL_MAX = 4 }; -DrawEngineGLES::DrawEngineGLES() : vai_(256) { +DrawEngineGLES::DrawEngineGLES(Draw::DrawContext *draw) : vai_(256), draw_(draw), inputLayoutMap_(16) { + render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); decOptions_.expandAllWeightsToFloat = false; decOptions_.expand8BitNormalsToFloat = false; @@ -133,7 +87,7 @@ DrawEngineGLES::DrawEngineGLES() : vai_(256) { InitDeviceObjects(); - tessDataTransfer = new TessellationDataTransferGLES(gl_extensions.VersionGEThan(3, 0, 0)); + tessDataTransfer = new TessellationDataTransferGLES(render_); } DrawEngineGLES::~DrawEngineGLES() { @@ -145,17 +99,6 @@ DrawEngineGLES::~DrawEngineGLES() { delete tessDataTransfer; } -void DrawEngineGLES::RestoreVAO() { - if (sharedVao_ != 0) { - glBindVertexArray(sharedVao_); - } else if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - // Note: this is here because, InitDeviceObjects() is called before GPU_SUPPORTS_VAO is setup. - // So, this establishes it if Supports() returns true and there isn't one yet. - glGenVertexArrays(1, &sharedVao_); - glBindVertexArray(sharedVao_); - } -} - void DrawEngineGLES::DeviceLost() { DestroyDeviceObjects(); } @@ -165,35 +108,66 @@ void DrawEngineGLES::DeviceRestore() { } void DrawEngineGLES::InitDeviceObjects() { - if (bufferNameCache_.empty()) { - bufferNameCache_.resize(VERTEXCACHE_NAME_CACHE_SIZE); - glGenBuffers(VERTEXCACHE_NAME_CACHE_SIZE, &bufferNameCache_[0]); - bufferNameCacheSize_ = 0; + for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { + frameData_[i].pushVertex = new GLPushBuffer(render_, GL_ARRAY_BUFFER, 1024 * 1024); + frameData_[i].pushIndex = new GLPushBuffer(render_, GL_ELEMENT_ARRAY_BUFFER, 256 * 1024); - if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - glGenVertexArrays(1, &sharedVao_); - } else { - sharedVao_ = 0; - } - } else { - ERROR_LOG(G3D, "Device objects already initialized!"); + render_->RegisterPushBuffer(i, frameData_[i].pushVertex); + render_->RegisterPushBuffer(i, frameData_[i].pushIndex); } + + int vertexSize = sizeof(TransformedVertex); + std::vector entries; + entries.push_back({ ATTR_POSITION, 4, GL_FLOAT, GL_FALSE, vertexSize, 0 }); + entries.push_back({ ATTR_TEXCOORD, 3, GL_FLOAT, GL_FALSE, vertexSize, offsetof(TransformedVertex, u) }); + entries.push_back({ ATTR_COLOR0, 4, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, offsetof(TransformedVertex, color0) }); + entries.push_back({ ATTR_COLOR1, 3, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, offsetof(TransformedVertex, color1) }); + softwareInputLayout_ = render_->CreateInputLayout(entries); } void DrawEngineGLES::DestroyDeviceObjects() { - ClearTrackedVertexArrays(); - if (!bufferNameCache_.empty()) { - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); - glDeleteBuffers((GLsizei)bufferNameCache_.size(), &bufferNameCache_[0]); - bufferNameCache_.clear(); - bufferNameInfo_.clear(); - freeSizedBuffers_.clear(); - bufferNameCacheSize_ = 0; - if (sharedVao_ != 0) { - glDeleteVertexArrays(1, &sharedVao_); - } + // Beware: this could be called twice in a row, sometimes. + for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { + if (!frameData_[i].pushVertex && !frameData_[i].pushIndex) + continue; + + render_->UnregisterPushBuffer(i, frameData_[i].pushVertex); + render_->UnregisterPushBuffer(i, frameData_[i].pushIndex); + frameData_[i].pushVertex->Destroy(); + frameData_[i].pushIndex->Destroy(); + delete frameData_[i].pushVertex; + delete frameData_[i].pushIndex; + frameData_[i].pushVertex = nullptr; + frameData_[i].pushIndex = nullptr; } + + ClearTrackedVertexArrays(); + + if (softwareInputLayout_) + render_->DeleteInputLayout(softwareInputLayout_); + softwareInputLayout_ = nullptr; + + ClearInputLayoutMap(); +} + +void DrawEngineGLES::ClearInputLayoutMap() { + inputLayoutMap_.Iterate([&](const uint32_t &key, GLRInputLayout *il) { + render_->DeleteInputLayout(il); + }); + inputLayoutMap_.Clear(); +} + +void DrawEngineGLES::BeginFrame() { + FrameData &frameData = frameData_[render_->GetCurFrame()]; + frameData.pushIndex->Begin(); + frameData.pushVertex->Begin(); +} + +void DrawEngineGLES::EndFrame() { + FrameData &frameData = frameData_[render_->GetCurFrame()]; + frameData.pushIndex->End(); + frameData.pushVertex->End(); + tessDataTransfer->EndFrame(); } struct GlTypeInfo { @@ -220,98 +194,59 @@ static const GlTypeInfo GLComp[] = { {GL_UNSIGNED_SHORT, 4, GL_TRUE},// DEC_U16_4, }; -static inline void VertexAttribSetup(int attrib, int fmt, int stride, u8 *ptr) { +static inline void VertexAttribSetup(int attrib, int fmt, int stride, int offset, std::vector &entries) { if (fmt) { const GlTypeInfo &type = GLComp[fmt]; - glVertexAttribPointer(attrib, type.count, type.type, type.normalized, stride, ptr); + GLRInputLayout::Entry entry; + entry.offset = offset; + entry.location = attrib; + entry.normalized = type.normalized; + entry.type = type.type; + entry.stride = stride; + entry.count = type.count; + entries.push_back(entry); } } // TODO: Use VBO and get rid of the vertexData pointers - with that, we will supply only offsets -static void SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt, u8 *vertexData) { - CHECK_GL_ERROR_IF_DEBUG(); - VertexAttribSetup(ATTR_W1, decFmt.w0fmt, decFmt.stride, vertexData + decFmt.w0off); - VertexAttribSetup(ATTR_W2, decFmt.w1fmt, decFmt.stride, vertexData + decFmt.w1off); - VertexAttribSetup(ATTR_TEXCOORD, decFmt.uvfmt, decFmt.stride, vertexData + decFmt.uvoff); - VertexAttribSetup(ATTR_COLOR0, decFmt.c0fmt, decFmt.stride, vertexData + decFmt.c0off); - VertexAttribSetup(ATTR_COLOR1, decFmt.c1fmt, decFmt.stride, vertexData + decFmt.c1off); - VertexAttribSetup(ATTR_NORMAL, decFmt.nrmfmt, decFmt.stride, vertexData + decFmt.nrmoff); - VertexAttribSetup(ATTR_POSITION, decFmt.posfmt, decFmt.stride, vertexData + decFmt.posoff); - CHECK_GL_ERROR_IF_DEBUG(); +GLRInputLayout *DrawEngineGLES::SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt) { + uint32_t key = decFmt.id; + GLRInputLayout *inputLayout = inputLayoutMap_.Get(key); + if (inputLayout) { + return inputLayout; + } + + std::vector entries; + VertexAttribSetup(ATTR_TEXCOORD, decFmt.uvfmt, decFmt.stride, decFmt.uvoff, entries); + VertexAttribSetup(ATTR_COLOR0, decFmt.c0fmt, decFmt.stride, decFmt.c0off, entries); + VertexAttribSetup(ATTR_COLOR1, decFmt.c1fmt, decFmt.stride, decFmt.c1off, entries); + VertexAttribSetup(ATTR_NORMAL, decFmt.nrmfmt, decFmt.stride, decFmt.nrmoff, entries); + VertexAttribSetup(ATTR_POSITION, decFmt.posfmt, decFmt.stride, decFmt.posoff, entries); + + inputLayout = render_->CreateInputLayout(entries); + inputLayoutMap_.Insert(key, inputLayout); + return inputLayout; } -void DrawEngineGLES::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) { - if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) - Flush(); +void DrawEngineGLES::DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf) { + u8 *dest = decoded; - // TODO: Is this the right thing to do? - if (prim == GE_PRIM_KEEP_PREVIOUS) { - prim = prevPrim_ != GE_PRIM_INVALID ? prevPrim_ : GE_PRIM_POINTS; - } else { - prevPrim_ = prim; - } - - SetupVertexDecoder(vertType); - - *bytesRead = vertexCount * dec_->VertexSize(); - - if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) - return; - - DeferredDrawCall &dc = drawCalls[numDrawCalls]; - dc.verts = verts; - dc.inds = inds; - dc.vertType = vertType; - dc.indexType = (vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; - dc.prim = prim; - dc.vertexCount = vertexCount; - - u32 dhash = dcid_; - dhash ^= (u32)(uintptr_t)verts; - dhash = __rotl(dhash, 13); - dhash ^= (u32)(uintptr_t)inds; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertType; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertexCount; - dhash = __rotl(dhash, 13); - dhash ^= (u32)prim; - dcid_ = dhash; - - if (inds) { - GetIndexBounds(inds, vertexCount, vertType, &dc.indexLowerBound, &dc.indexUpperBound); - } else { - dc.indexLowerBound = 0; - dc.indexUpperBound = vertexCount - 1; - } - - uvScale[numDrawCalls] = gstate_c.uv; - - numDrawCalls++; - vertexCountInDrawCalls_ += vertexCount; - - if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) { - DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); - decodeCounter_++; - } - - if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { - // Rendertarget == texture? - if (!g_Config.bDisableSlowFramebufEffects) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - Flush(); - } + // Figure out how much pushbuffer space we need to allocate. + if (push) { + int vertsToDecode = ComputeNumVertsToDecode(); + dest = (u8 *)push->Push(vertsToDecode * dec_->GetDecVtxFmt().stride, bindOffset, buf); } + DecodeVerts(dest); } void DrawEngineGLES::MarkUnreliable(VertexArrayInfo *vai) { vai->status = VertexArrayInfo::VAI_UNRELIABLE; if (vai->vbo) { - FreeBuffer(vai->vbo); + render_->DeleteBuffer(vai->vbo); vai->vbo = 0; } if (vai->ebo) { - FreeBuffer(vai->ebo); + render_->DeleteBuffer(vai->ebo); vai->ebo = 0; } } @@ -351,108 +286,55 @@ void DrawEngineGLES::DecimateTrackedVertexArrays() { vai_.Maintain(); } -GLuint DrawEngineGLES::AllocateBuffer(size_t sz) { - GLuint unused = 0; - - auto freeMatch = freeSizedBuffers_.find(sz); - if (freeMatch != freeSizedBuffers_.end()) { - unused = freeMatch->second; - _assert_(!bufferNameInfo_[unused].used); - - freeSizedBuffers_.erase(freeMatch); - } else { - for (GLuint buf : bufferNameCache_) { - const BufferNameInfo &info = bufferNameInfo_[buf]; - if (info.used) { - continue; - } - - // Just pick the first unused one, we'll have to resize it. - unused = buf; - - // Let's also remove from the free list, if it's there. - if (info.sz != 0) { - auto range = freeSizedBuffers_.equal_range(info.sz); - for (auto it = range.first; it != range.second; ++it) { - if (it->second == buf) { - // It will only be once, so remove and bail. - freeSizedBuffers_.erase(it); - break; - } - } - } - break; - } - } - - if (unused == 0) { - size_t oldSize = bufferNameCache_.size(); - bufferNameCache_.resize(oldSize + VERTEXCACHE_NAME_CACHE_SIZE); - glGenBuffers(VERTEXCACHE_NAME_CACHE_SIZE, &bufferNameCache_[oldSize]); - - unused = bufferNameCache_[oldSize]; - } - - BufferNameInfo &info = bufferNameInfo_[unused]; - - // Record the change in size. - bufferNameCacheSize_ += sz - info.sz; - info.sz = sz; - info.used = true; - return unused; -} - -void DrawEngineGLES::FreeBuffer(GLuint buf) { - // We can reuse buffers by setting new data on them, so let's actually keep it. - auto it = bufferNameInfo_.find(buf); - if (it != bufferNameInfo_.end()) { - it->second.used = false; - it->second.lastFrame = gpuStats.numFlips; - - if (it->second.sz != 0) { - freeSizedBuffers_.insert(std::make_pair(it->second.sz, buf)); - } - } else { - ERROR_LOG(G3D, "Unexpected buffer freed (%d) but not tracked", buf); - } -} - void DrawEngineGLES::FreeVertexArray(VertexArrayInfo *vai) { if (vai->vbo) { - FreeBuffer(vai->vbo); - vai->vbo = 0; + render_->DeleteBuffer(vai->vbo); + vai->vbo = nullptr; } if (vai->ebo) { - FreeBuffer(vai->ebo); - vai->ebo = 0; + render_->DeleteBuffer(vai->ebo); + vai->ebo = nullptr; } } void DrawEngineGLES::DoFlush() { PROFILE_THIS_SCOPE("flush"); - CHECK_GL_ERROR_IF_DEBUG(); + FrameData &frameData = frameData_[render_->GetCurFrame()]; + gpuStats.numFlushes++; gpuStats.numTrackedVertexArrays = (int)vai_.size(); + bool textureNeedsApply = false; + if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { + textureCache_->SetTexture(); + gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); + textureNeedsApply = true; + } + GEPrimitiveType prim = prevPrim_; - ApplyDrawState(prim); - CHECK_GL_ERROR_IF_DEBUG(); VShaderID vsid; Shader *vshader = shaderManager_->ApplyVertexShader(prim, lastVType_, &vsid); + GLRBuffer *vertexBuffer = nullptr; + GLRBuffer *indexBuffer = nullptr; + uint32_t vertexBufferOffset = 0; + uint32_t indexBufferOffset = 0; + if (vshader->UseHWTransform()) { - GLuint vbo = 0, ebo = 0; int vertexCount = 0; bool useElements = true; // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. - if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) + // Also avoid caching when skinning. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) useCache = false; + // TEMPORARY + useCache = false; + if (useCache) { u32 id = dcid_ ^ gstate.getUVGenMode(); // This can have an effect on which UV decoder we need to use! And hence what the decoded data will look like. See #9263 VertexArrayInfo *vai = vai_.Get(id); @@ -534,31 +416,27 @@ void DrawEngineGLES::DoFlush() { _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); size_t vsz = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); - vai->vbo = AllocateBuffer(vsz); - glstate.arrayBuffer.bind(vai->vbo); - glBufferData(GL_ARRAY_BUFFER, vsz, decoded, GL_STATIC_DRAW); + vai->vbo = render_->CreateBuffer(GL_ARRAY_BUFFER, vsz, GL_STATIC_DRAW); + render_->BufferSubdata(vai->vbo, 0, vsz, decoded); // If there's only been one primitive type, and it's either TRIANGLES, LINES or POINTS, // there is no need for the index buffer we built. We can then use glDrawArrays instead // for a very minor speed boost. if (useElements) { size_t esz = sizeof(short) * indexGen.VertexCount(); - vai->ebo = AllocateBuffer(esz); - glstate.elementArrayBuffer.bind(vai->ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, esz, (GLvoid *)decIndex, GL_STATIC_DRAW); + vai->ebo = render_->CreateBuffer(GL_ARRAY_BUFFER, esz, GL_STATIC_DRAW); + render_->BufferSubdata(vai->ebo, 0, esz, (uint8_t *)decIndex, false); } else { vai->ebo = 0; - glstate.elementArrayBuffer.bind(vai->ebo); + render_->BindIndexBuffer(vai->ebo); } } else { gpuStats.numCachedDrawCalls++; - glstate.arrayBuffer.bind(vai->vbo); - glstate.elementArrayBuffer.bind(vai->ebo); useElements = vai->ebo ? true : false; gpuStats.numCachedVertsDrawn += vai->numVerts; gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA; } - vbo = vai->vbo; - ebo = vai->ebo; + vertexBuffer = vai->vbo; + indexBuffer = vai->ebo; vertexCount = vai->numVerts; prim = static_cast(vai->prim); break; @@ -573,10 +451,8 @@ void DrawEngineGLES::DoFlush() { } gpuStats.numCachedDrawCalls++; gpuStats.numCachedVertsDrawn += vai->numVerts; - vbo = vai->vbo; - ebo = vai->ebo; - glstate.arrayBuffer.bind(vbo); - glstate.elementArrayBuffer.bind(ebo); + vertexBuffer = vai->vbo; + indexBuffer = vai->ebo; vertexCount = vai->numVerts; prim = static_cast(vai->prim); @@ -597,7 +473,15 @@ void DrawEngineGLES::DoFlush() { vai->lastFrame = gpuStats.numFlips; } else { - DecodeVerts(decoded); + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) { + // If skinning, we've already predecoded into "decoded". So push that content. + size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; + u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vertexBufferOffset, &vertexBuffer); + memcpy(dest, decoded, size); + } else { + // Decode directly into the pushbuffer + DecodeVertsToPushBuffer(frameData.pushVertex, &vertexBufferOffset, &vertexBuffer); + } rotateVBO: gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); @@ -606,9 +490,6 @@ rotateVBO: if (!useElements && indexGen.PureCount()) { vertexCount = indexGen.PureCount(); } - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); - prim = indexGen.Prim(); } @@ -620,26 +501,27 @@ rotateVBO: gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); } - ApplyDrawStateLate(); - - if (gstate_c.Supports(GPU_SUPPORTS_VAO) && vbo == 0) { - vbo = BindBuffer(decoded, dec_->GetDecVtxFmt().stride * indexGen.MaxIndex()); - if (useElements) { - ebo = BindElementBuffer(decIndex, sizeof(short) * indexGen.VertexCount()); - } - } + if (textureNeedsApply) + textureCache_->ApplyTexture(); + // Need to ApplyDrawState after ApplyTexture because depal can launch a render pass and that wrecks the state. + ApplyDrawState(prim); + ApplyDrawStateLate(false, 0); + LinkedShader *program = shaderManager_->ApplyFragmentShader(vsid, vshader, lastVType_, prim); - SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), vbo ? 0 : decoded); - + GLRInputLayout *inputLayout = SetupDecFmtForDraw(program, dec_->GetDecVtxFmt()); + render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset); if (useElements) { + if (!indexBuffer) { + indexBufferOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &indexBuffer); + render_->BindIndexBuffer(indexBuffer); + } if (gstate_c.bezier || gstate_c.spline) - // Instanced rendering for instanced tessellation - glDrawElementsInstanced(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, ebo ? 0 : (GLvoid*)decIndex, numPatches); + render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset, numPatches); else - glDrawElements(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, ebo ? 0 : (GLvoid*)decIndex); + render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); } else { - glDrawArrays(glprim[prim], 0, vertexCount); + render_->Draw(glprim[prim], 0, vertexCount); } } else { DecodeVerts(decoded); @@ -683,40 +565,30 @@ rotateVBO: prim, vertexCount, dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(), maxIndex, drawBuffer, numTrans, drawIndexed, ¶ms, &result); - ApplyDrawStateLate(); + + if (textureNeedsApply) + textureCache_->ApplyTexture(); + + ApplyDrawState(prim); + ApplyDrawStateLate(result.setStencil, result.stencilValue); LinkedShader *program = shaderManager_->ApplyFragmentShader(vsid, vshader, lastVType_, prim); if (result.action == SW_DRAW_PRIMITIVES) { - if (result.setStencil) { - glstate.stencilFunc.set(GL_ALWAYS, result.stencilValue, 255); - } const int vertexSize = sizeof(transformed[0]); bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX; - const uint8_t *bufferStart = (const uint8_t *)drawBuffer; - if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - bufferStart = 0; - BindBuffer(drawBuffer, vertexSize * maxIndex); - if (drawIndexed) { - BindElementBuffer(inds, sizeof(short) * numTrans); - inds = 0; - } - } else { - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); - } - - glVertexAttribPointer(ATTR_POSITION, 4, GL_FLOAT, GL_FALSE, vertexSize, bufferStart); - int attrMask = program->attrMask; - if (attrMask & (1 << ATTR_TEXCOORD)) glVertexAttribPointer(ATTR_TEXCOORD, doTextureProjection ? 3 : 2, GL_FLOAT, GL_FALSE, vertexSize, bufferStart + offsetof(TransformedVertex, u)); - if (attrMask & (1 << ATTR_COLOR0)) glVertexAttribPointer(ATTR_COLOR0, 4, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, bufferStart + offsetof(TransformedVertex, color0)); - if (attrMask & (1 << ATTR_COLOR1)) glVertexAttribPointer(ATTR_COLOR1, 3, GL_UNSIGNED_BYTE, GL_TRUE, vertexSize, bufferStart + offsetof(TransformedVertex, color1)); if (drawIndexed) { - glDrawElements(glprim[prim], numTrans, GL_UNSIGNED_SHORT, inds); + vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(drawBuffer, maxIndex * sizeof(TransformedVertex), &vertexBuffer); + indexBufferOffset = (uint32_t)frameData.pushIndex->Push(inds, sizeof(uint16_t) * numTrans, &indexBuffer); + render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset); + render_->BindIndexBuffer(indexBuffer); + render_->DrawIndexed(glprim[prim], numTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset); } else { - glDrawArrays(glprim[prim], 0, numTrans); + vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(drawBuffer, numTrans * sizeof(TransformedVertex), &vertexBuffer); + render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset); + render_->Draw(glprim[prim], 0, numTrans); } } else if (result.action == SW_CLEAR) { u32 clearColor = result.color; @@ -735,37 +607,26 @@ rotateVBO: framebufferManager_->SetDepthUpdated(); } - // Note that scissor may still apply while clearing. Turn off other tests for the clear. - glstate.stencilTest.disable(); - glstate.stencilMask.set(0xFF); - glstate.depthTest.disable(); - GLbitfield target = 0; + // Without this, we will clear RGB when clearing stencil, which breaks games. + uint8_t rgbaMask = (colorMask ? 7 : 0) | (alphaMask ? 8 : 0); if (colorMask || alphaMask) target |= GL_COLOR_BUFFER_BIT; if (alphaMask) target |= GL_STENCIL_BUFFER_BIT; if (depthMask) target |= GL_DEPTH_BUFFER_BIT; - glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask); - glClearColor(col[0], col[1], col[2], col[3]); -#ifdef USING_GLES2 - glClearDepthf(clearDepth); -#else - glClearDepth(clearDepth); -#endif - // Stencil takes alpha. - glClearStencil(clearColor >> 24); - glClear(target); - framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; + + render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH); + framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); framebufferManager_->SetSafeSize(scissorX2, scissorY2); if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } + gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied. } } @@ -791,104 +652,6 @@ rotateVBO: #ifndef MOBILE_DEVICE host->GPUNotifyDraw(); #endif - CHECK_GL_ERROR_IF_DEBUG(); -} - -GLuint DrawEngineGLES::BindBuffer(const void *p, size_t sz) { - // Get a new buffer each time we need one. - GLuint buf = AllocateBuffer(sz); - glstate.arrayBuffer.bind(buf); - - // These aren't used more than once per frame, so let's use GL_STREAM_DRAW. - glBufferData(GL_ARRAY_BUFFER, sz, p, GL_STREAM_DRAW); - buffersThisFrame_.push_back(buf); - - return buf; -} - -GLuint DrawEngineGLES::BindBuffer(const void *p1, size_t sz1, const void *p2, size_t sz2) { - GLuint buf = AllocateBuffer(sz1 + sz2); - glstate.arrayBuffer.bind(buf); - - glBufferData(GL_ARRAY_BUFFER, sz1 + sz2, nullptr, GL_STREAM_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sz1, p1); - glBufferSubData(GL_ARRAY_BUFFER, sz1, sz2, p2); - buffersThisFrame_.push_back(buf); - - return buf; -} - -GLuint DrawEngineGLES::BindElementBuffer(const void *p, size_t sz) { - GLuint buf = AllocateBuffer(sz); - glstate.elementArrayBuffer.bind(buf); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sz, p, GL_STREAM_DRAW); - buffersThisFrame_.push_back(buf); - - return buf; -} - -void DrawEngineGLES::DecimateBuffers() { - for (GLuint buf : buffersThisFrame_) { - FreeBuffer(buf); - } - buffersThisFrame_.clear(); - - if (--bufferDecimationCounter_ <= 0) { - bufferDecimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL; - } else { - return; - } - - // Let's not keep too many around, will eat up memory. - // First check if there's any to free, and only check if it seems somewhat full. - bool hasOld = false; - if (bufferNameCacheSize_ > VERTEXCACHE_NAME_CACHE_FULL_BYTES) { - for (GLuint buf : bufferNameCache_) { - const BufferNameInfo &info = bufferNameInfo_[buf]; - const int age = gpuStats.numFlips - info.lastFrame; - if (!info.used && age > VERTEXCACHE_NAME_CACHE_MAX_AGE) { - hasOld = true; - break; - } - } - } - - if (hasOld) { - // Okay, it is. Let's rebuild the array. - std::vector toFree; - std::vector toKeep; - - toKeep.reserve(bufferNameCache_.size()); - - for (size_t i = 0, n = bufferNameCache_.size(); i < n; ++i) { - const GLuint buf = bufferNameCache_[i]; - const BufferNameInfo &info = bufferNameInfo_[buf]; - const int age = gpuStats.numFlips - info.lastFrame; - if (!info.used && age > VERTEXCACHE_NAME_CACHE_MAX_AGE) { - toFree.push_back(buf); - bufferNameCacheSize_ -= bufferNameInfo_[buf].sz; - bufferNameInfo_.erase(buf); - - // If we've removed all we want to this round, keep the rest and abort. - if (toFree.size() >= VERTEXCACHE_NAME_DECIMATION_MAX && i + 1 < bufferNameCache_.size()) { - toKeep.insert(toKeep.end(), bufferNameCache_.begin() + i + 1, bufferNameCache_.end()); - break; - } - } else { - toKeep.push_back(buf); - } - } - - if (!toFree.empty()) { - bufferNameCache_ = toKeep; - // TODO: Rebuild? - freeSizedBuffers_.clear(); - - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); - glDeleteBuffers((GLsizei)toFree.size(), &toFree[0]); - } - } } bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const { @@ -896,100 +659,45 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const { } void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) { -#ifndef USING_GLES2 - if (isAllowTexture1D_) { - // Position - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_1D, data_tex[0]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSize < size) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - prevSize = size; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - } + // Removed the 1D texture support, it's unlikely to be relevant for performance. + if (data_tex[0]) + renderManager_->DeleteTexture(data_tex[0]); + uint8_t *pos_data = new uint8_t[size * sizeof(float) * 4]; + memcpy(pos_data, pos, size * sizeof(float) * 4); + data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D); + renderManager_->TextureImage(data_tex[0], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, pos_data, GLRAllocType::NEW, false); + renderManager_->FinalizeTexture(data_tex[0], 0, false); + renderManager_->BindTexture(4, data_tex[0]); - // Texcoords - if (hasTexCoords) { - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_1D, data_tex[1]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSizeTex < size) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - prevSizeTex = size; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - } - } + // Texcoords + if (hasTexCoords) { + if (data_tex[1]) + renderManager_->DeleteTexture(data_tex[1]); + uint8_t *tex_data = new uint8_t[size * sizeof(float) * 4]; + memcpy(tex_data, pos, size * sizeof(float) * 4); + data_tex[1] = renderManager_->CreateTexture(GL_TEXTURE_2D); + renderManager_->TextureImage(data_tex[1], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, tex_data, GLRAllocType::NEW, false); + renderManager_->FinalizeTexture(data_tex[1], 0, false); + renderManager_->BindTexture(5, data_tex[1]); + } - // Color - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_1D, data_tex[2]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - int sizeColor = hasColor ? size : 1; - if (prevSizeCol < sizeColor) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, sizeColor, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col); - prevSizeCol = sizeColor; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, sizeColor, GL_RGBA, GL_FLOAT, (GLfloat*)col); - } - } else -#endif - { - // Position - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, data_tex[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSize < size) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - prevSize = size; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - } + if (data_tex[2]) + renderManager_->DeleteTexture(data_tex[2]); + data_tex[2] = renderManager_->CreateTexture(GL_TEXTURE_2D); + int sizeColor = hasColor ? size : 1; + uint8_t *col_data = new uint8_t[sizeColor * sizeof(float) * 4]; + memcpy(col_data, col, sizeColor * sizeof(float) * 4); - // Texcoords - if (hasTexCoords) { - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, data_tex[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSizeTex < size) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - prevSizeTex = size; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - } - } + renderManager_->TextureImage(data_tex[2], 0, sizeColor, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, col_data, GLRAllocType::NEW, false); + renderManager_->FinalizeTexture(data_tex[2], 0, false); + renderManager_->BindTexture(6, data_tex[2]); +} - // Color - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_2D, data_tex[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - int sizeColor = hasColor ? size : 1; - if (prevSizeCol < sizeColor) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, sizeColor, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col); - prevSizeCol = sizeColor; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sizeColor, 1, GL_RGBA, GL_FLOAT, (GLfloat*)col); +void DrawEngineGLES::TessellationDataTransferGLES::EndFrame() { + for (int i = 0; i < 3; i++) { + if (data_tex[i]) { + renderManager_->DeleteTexture(data_tex[i]); + data_tex[i] = nullptr; } } - glActiveTexture(GL_TEXTURE0); - CHECK_GL_ERROR_IF_DEBUG(); } diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 037758d670..42e4ce5133 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -28,6 +28,7 @@ #include "GPU/Common/GPUStateUtils.h" #include "GPU/GLES/FragmentShaderGeneratorGLES.h" #include "gfx/gl_common.h" +#include "thin3d/GLRenderManager.h" class LinkedShader; class ShaderManagerGLES; @@ -60,8 +61,8 @@ class VertexArrayInfo { public: VertexArrayInfo() { status = VAI_NEW; - vbo = 0; - ebo = 0; + vbo = nullptr; + ebo = nullptr; prim = GE_PRIM_INVALID; numDraws = 0; numFrames = 0; @@ -81,8 +82,8 @@ public: ReliableHashType hash; u32 minihash; - u32 vbo; - u32 ebo; + GLRBuffer *vbo; + GLRBuffer *ebo; // Precalculated parameter for drawRangeElements u16 numVerts; @@ -101,11 +102,9 @@ public: // Handles transform, lighting and drawing. class DrawEngineGLES : public DrawEngineCommon { public: - DrawEngineGLES(); + DrawEngineGLES(Draw::DrawContext *draw); virtual ~DrawEngineGLES(); - void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead); - void SetShaderManager(ShaderManagerGLES *shaderManager) { shaderManager_ = shaderManager; } @@ -118,7 +117,6 @@ public: void SetFragmentTestCache(FragmentTestCacheGLES *testCache) { fragmentTestCache_ = testCache; } - void RestoreVAO(); void DeviceLost(); void DeviceRestore(); @@ -126,6 +124,10 @@ public: void ClearTrackedVertexArrays() override; void DecimateTrackedVertexArrays(); + void BeginFrame(); + void EndFrame(); + + // So that this can be inlined void Flush() { if (!numDrawCalls) @@ -136,20 +138,21 @@ public: void FinishDeferred() { if (!numDrawCalls) return; - DecodeVerts(decoded); + DoFlush(); } bool IsCodePtrVertexDecoder(const u8 *ptr) const; void DispatchFlush() override { Flush(); } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override { - SubmitPrim(verts, inds, prim, vertexCount, vertType, bytesRead); + + GLPushBuffer *GetPushVertexBuffer() { + return frameData_[render_->GetCurFrame()].pushVertex; + } + GLPushBuffer *GetPushIndexBuffer() { + return frameData_[render_->GetCurFrame()].pushIndex; } - GLuint BindBuffer(const void *p, size_t sz); - GLuint BindBuffer(const void *p1, size_t sz1, const void *p2, size_t sz2); - GLuint BindElementBuffer(const void *p, size_t sz); - void DecimateBuffers(); + void ClearInputLayoutMap(); private: void InitDeviceObjects(); @@ -157,53 +160,54 @@ private: void DoFlush(); void ApplyDrawState(int prim); - void ApplyDrawStateLate(); + void ApplyDrawStateLate(bool setStencil, int stencilValue); void ResetShaderBlending(); - GLuint AllocateBuffer(size_t sz); - void FreeBuffer(GLuint buf); + GLRInputLayout *SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt); + + void DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf); + void FreeVertexArray(VertexArrayInfo *vai); void MarkUnreliable(VertexArrayInfo *vai); + struct FrameData { + GLPushBuffer *pushVertex; + GLPushBuffer *pushIndex; + }; + FrameData frameData_[GLRenderManager::MAX_INFLIGHT_FRAMES]; + PrehashMap vai_; - // Vertex buffer objects - // Element buffer objects - struct BufferNameInfo { - BufferNameInfo() : sz(0), used(false), lastFrame(0) {} + DenseHashMap inputLayoutMap_; - size_t sz; - bool used; - int lastFrame; - }; - std::vector bufferNameCache_; - std::multimap freeSizedBuffers_; - std::unordered_map bufferNameInfo_; - std::vector buffersThisFrame_; - size_t bufferNameCacheSize_ = 0; - GLuint sharedVao_ = 0; + GLRInputLayout *softwareInputLayout_ = nullptr; + GLRenderManager *render_; // Other ShaderManagerGLES *shaderManager_ = nullptr; TextureCacheGLES *textureCache_ = nullptr; FramebufferManagerGLES *framebufferManager_ = nullptr; FragmentTestCacheGLES *fragmentTestCache_ = nullptr; + Draw::DrawContext *draw_; + + // Need to preserve the scissor for use when clearing. + ViewportAndScissor vpAndScissor; int bufferDecimationCounter_ = 0; // Hardware tessellation class TessellationDataTransferGLES : public TessellationDataTransfer { private: - int data_tex[3]; - bool isAllowTexture1D_; + GLRTexture *data_tex[3]{}; + GLRenderManager *renderManager_; public: - TessellationDataTransferGLES(bool isAllowTexture1D) : TessellationDataTransfer(), data_tex(), isAllowTexture1D_(isAllowTexture1D) { - glGenTextures(3, (GLuint*)data_tex); - } + TessellationDataTransferGLES(GLRenderManager *renderManager) + : renderManager_(renderManager) { } ~TessellationDataTransferGLES() { - glDeleteTextures(3, (GLuint*)data_tex); + EndFrame(); } void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override; + void EndFrame() override; // Queues textures for deletion. }; }; diff --git a/GPU/GLES/FragmentTestCacheGLES.cpp b/GPU/GLES/FragmentTestCacheGLES.cpp index e49f336e13..0ad098a499 100644 --- a/GPU/GLES/FragmentTestCacheGLES.cpp +++ b/GPU/GLES/FragmentTestCacheGLES.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "thin3d/thin3d.h" #include "gfx/gl_debug_log.h" #include "Core/Config.h" #include "GPU/GLES/FragmentTestCacheGLES.h" @@ -26,16 +27,15 @@ static const int FRAGTEST_TEXTURE_OLD_AGE = 307; static const int FRAGTEST_DECIMATION_INTERVAL = 113; -FragmentTestCacheGLES::FragmentTestCacheGLES() : textureCache_(NULL), lastTexture_(0), decimationCounter_(0) { - scratchpad_ = new u8[256 * 4]; +FragmentTestCacheGLES::FragmentTestCacheGLES(Draw::DrawContext *draw) { + render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); } FragmentTestCacheGLES::~FragmentTestCacheGLES() { Clear(); - delete [] scratchpad_; } -void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { +void FragmentTestCacheGLES::BindTestTexture(int slot) { if (!g_Config.bFragmentTestCache) { return; } @@ -51,17 +51,12 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { const auto cached = cache_.find(id); if (cached != cache_.end()) { cached->second.lastFrame = gpuStats.numFlips; - GLuint tex = cached->second.texture; + GLRTexture *tex = cached->second.texture; if (tex == lastTexture_) { // Already bound, hurray. return; } - CHECK_GL_ERROR_IF_DEBUG(); - glActiveTexture(unit); - glBindTexture(GL_TEXTURE_2D, tex); - // Always return to the default. - glActiveTexture(GL_TEXTURE0); - CHECK_GL_ERROR_IF_DEBUG(); + render_->BindTexture(slot, tex); lastTexture_ = tex; return; } @@ -79,13 +74,9 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { const GEComparison funcs[4] = {gstate.getColorTestFunction(), gstate.getColorTestFunction(), gstate.getColorTestFunction(), gstate.getAlphaTestFunction()}; const bool valid[4] = {gstate.isColorTestEnabled(), gstate.isColorTestEnabled(), gstate.isColorTestEnabled(), gstate.isAlphaTestEnabled()}; - glActiveTexture(unit); - // This will necessarily bind the texture. - const GLuint tex = CreateTestTexture(funcs, refs, masks, valid); - // Always return to the default. - glActiveTexture(GL_TEXTURE0); + GLRTexture *tex = CreateTestTexture(funcs, refs, masks, valid); lastTexture_ = tex; - + render_->BindTexture(slot, tex); FragmentTestTexture item; item.lastFrame = gpuStats.numFlips; item.texture = tex; @@ -106,7 +97,8 @@ FragmentTestID FragmentTestCacheGLES::GenerateTestID() const { return id; } -GLuint FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]) { +GLRTexture *FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]) { + u8 *data = new u8[256 * 4]; // TODO: Might it be better to use GL_ALPHA for simple textures? // TODO: Experiment with 4-bit/etc. textures. @@ -142,26 +134,19 @@ GLuint FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4], con break; } } - scratchpad_[color * 4 + i] = res ? 0xFF : 0; + data[color * 4 + i] = res ? 0xFF : 0; } } - GLuint tex = textureCache_->AllocTextureName(); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, scratchpad_); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - + GLRTexture *tex = render_->CreateTexture(GL_TEXTURE_2D); + render_->TextureImage(tex, 0, 256, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data); return tex; } void FragmentTestCacheGLES::Clear(bool deleteThem) { if (deleteThem) { for (auto tex = cache_.begin(); tex != cache_.end(); ++tex) { - glDeleteTextures(1, &tex->second.texture); + render_->DeleteTexture(tex->second.texture); } } cache_.clear(); @@ -172,7 +157,7 @@ void FragmentTestCacheGLES::Decimate() { if (--decimationCounter_ <= 0) { for (auto tex = cache_.begin(); tex != cache_.end(); ) { if (tex->second.lastFrame + FRAGTEST_TEXTURE_OLD_AGE < gpuStats.numFlips) { - glDeleteTextures(1, &tex->second.texture); + render_->DeleteTexture(tex->second.texture); cache_.erase(tex++); } else { ++tex; diff --git a/GPU/GLES/FragmentTestCacheGLES.h b/GPU/GLES/FragmentTestCacheGLES.h index 106258e6d0..043b236fe6 100644 --- a/GPU/GLES/FragmentTestCacheGLES.h +++ b/GPU/GLES/FragmentTestCacheGLES.h @@ -19,7 +19,6 @@ #include #include "Common/CommonTypes.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/ge_constants.h" @@ -53,33 +52,33 @@ struct FragmentTestID { }; struct FragmentTestTexture { - GLuint texture; + GLRTexture *texture; int lastFrame; }; class FragmentTestCacheGLES { public: - FragmentTestCacheGLES(); + FragmentTestCacheGLES(Draw::DrawContext *draw); ~FragmentTestCacheGLES(); void SetTextureCache(TextureCacheGLES *tc) { textureCache_ = tc; } - void BindTestTexture(GLenum unit); + void BindTestTexture(int slot); void Clear(bool deleteThem = true); void Decimate(); private: - GLuint CreateTestTexture(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]); + GLRTexture *CreateTestTexture(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]); FragmentTestID GenerateTestID() const; + GLRenderManager *render_; TextureCacheGLES *textureCache_; std::map cache_; - u8 *scratchpad_; - GLuint lastTexture_; - int decimationCounter_; + GLRTexture *lastTexture_ = nullptr; + int decimationCounter_ = 0; }; diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 9728ddd855..53cb7cd638 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -42,7 +42,6 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/Debugger/Stepping.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/DrawEngineGLES.h" @@ -81,34 +80,26 @@ const int MAX_PBO = 2; void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format); -void FramebufferManagerGLES::DisableState() { - glstate.blend.disable(); - glstate.cullFace.disable(); - glstate.depthTest.disable(); - glstate.scissorTest.disable(); - glstate.stencilTest.disable(); -#if !defined(USING_GLES2) - glstate.colorLogicOp.disable(); -#endif - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.stencilMask.set(0xFF); - - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); -} - void FramebufferManagerGLES::CompileDraw2DProgram() { if (!draw2dprogram_) { std::string errorString; static std::string vs_code, fs_code; vs_code = ApplyGLSLPrelude(basic_vs, GL_VERTEX_SHADER); fs_code = ApplyGLSLPrelude(tex_fs, GL_FRAGMENT_SHADER); - draw2dprogram_ = glsl_create_source(vs_code.c_str(), fs_code.c_str(), &errorString); - if (!draw2dprogram_) { - ERROR_LOG_REPORT(G3D, "Failed to compile draw2dprogram! This shouldn't happen.\n%s", errorString.c_str()); - } else { - glsl_bind(draw2dprogram_); - glUniform1i(draw2dprogram_->sampler0, 0); - } + std::vector shaders; + shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vs_code, "draw2d")); + shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fs_code, "draw2d")); + + std::vector queries; + queries.push_back({ &u_draw2d_tex, "u_tex" }); + std::vector initializers; + initializers.push_back({ &u_draw2d_tex, 0 }); + std::vector semantics; + semantics.push_back({ 0, "a_position" }); + semantics.push_back({ 1, "a_texcoord0" }); + draw2dprogram_ = render_->CreateProgram(shaders, semantics, queries, initializers, false); + for (auto shader : shaders) + render_->DeleteShader(shader); CompilePostShader(); } } @@ -155,7 +146,27 @@ void FramebufferManagerGLES::CompilePostShader() { } if (!translationFailed) { - postShaderProgram_ = glsl_create_source(vshader.c_str(), fshader.c_str(), &errorString); + SetNumExtraFBOs(1); + + std::vector shaders; + shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vshader, "postshader")); + shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fshader, "postshader")); + std::vector queries; + queries.push_back({ &u_postShaderTex, "tex" }); + queries.push_back({ &deltaLoc_, "u_texelDelta" }); + queries.push_back({ &pixelDeltaLoc_, "u_pixelDelta" }); + queries.push_back({ &timeLoc_, "u_time" }); + queries.push_back({ &videoLoc_, "u_video" }); + + std::vector inits; + inits.push_back({ &u_postShaderTex, 0, 0 }); + std::vector semantics; + semantics.push_back({ 0, "a_position" }); + semantics.push_back({ 1, "a_texcoord0" }); + postShaderProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false); + for (auto iter : shaders) { + render_->DeleteShader(iter); + } } else { ERROR_LOG(FRAMEBUF, "Failed to translate post shader!"); } @@ -193,24 +204,16 @@ void FramebufferManagerGLES::CompilePostShader() { } usePostShader_ = false; } else { - glsl_bind(postShaderProgram_); - glUniform1i(postShaderProgram_->sampler0, 0); - SetNumExtraFBOs(1); - deltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_texelDelta"); - pixelDeltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_pixelDelta"); - timeLoc_ = glsl_uniform_loc(postShaderProgram_, "u_time"); - videoLoc_ = glsl_uniform_loc(postShaderProgram_, "u_video"); usePostShader_ = true; } } else { postShaderProgram_ = nullptr; usePostShader_ = false; } - glsl_unbind(); } void FramebufferManagerGLES::Bind2DShader() { - glsl_bind(draw2dprogram_); + render_->BindProgram(draw2dprogram_); } void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms) { @@ -218,35 +221,25 @@ void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms) if (!postShaderProgram_) { CompileDraw2DProgram(); } - - glsl_bind(postShaderProgram_); + render_->BindProgram(postShaderProgram_); if (deltaLoc_ != -1) - glUniform2f(deltaLoc_, uniforms.texelDelta[0], uniforms.texelDelta[1]); + render_->SetUniformF(&deltaLoc_, 2, uniforms.texelDelta); if (pixelDeltaLoc_ != -1) - glUniform2f(pixelDeltaLoc_, uniforms.pixelDelta[0], uniforms.pixelDelta[1]); + render_->SetUniformF(&pixelDeltaLoc_, 2, uniforms.pixelDelta); if (timeLoc_ != -1) - glUniform4fv(timeLoc_, 1, uniforms.time); + render_->SetUniformF(&timeLoc_, 4, uniforms.time); if (videoLoc_ != -1) - glUniform1f(videoLoc_, uniforms.video); + render_->SetUniformF(&videoLoc_, 1, &uniforms.video); } -FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw) : +FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw, GLRenderManager *render) : FramebufferManagerCommon(draw), - drawPixelsTex_(0), - drawPixelsTexFormat_(GE_FORMAT_INVALID), - convBuf_(nullptr), - videoLoc_(-1), - timeLoc_(-1), - pixelDeltaLoc_(-1), - deltaLoc_(-1), - textureCacheGL_(nullptr), - shaderManagerGL_(nullptr), - pixelBufObj_(nullptr), - currentPBO_(0) + render_(render) { needBackBufferYSwap_ = true; needGLESRebinds_ = true; CreateDeviceObjects(); + render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); } void FramebufferManagerGLES::Init() { @@ -273,23 +266,33 @@ void FramebufferManagerGLES::SetDrawEngine(DrawEngineGLES *td) { void FramebufferManagerGLES::CreateDeviceObjects() { CompileDraw2DProgram(); + + std::vector entries; + entries.push_back({ 0, 3, GL_FLOAT, GL_FALSE, sizeof(Simple2DVertex), offsetof(Simple2DVertex, pos) }); + entries.push_back({ 1, 2, GL_FLOAT, GL_FALSE, sizeof(Simple2DVertex), offsetof(Simple2DVertex, uv) }); + simple2DInputLayout_ = render_->CreateInputLayout(entries); } void FramebufferManagerGLES::DestroyDeviceObjects() { + if (simple2DInputLayout_) { + render_->DeleteInputLayout(simple2DInputLayout_); + simple2DInputLayout_ = nullptr; + } + if (draw2dprogram_) { - glsl_destroy(draw2dprogram_); + render_->DeleteProgram(draw2dprogram_); draw2dprogram_ = nullptr; } if (postShaderProgram_) { - glsl_destroy(postShaderProgram_); + render_->DeleteProgram(postShaderProgram_); postShaderProgram_ = nullptr; } if (drawPixelsTex_) { - glDeleteTextures(1, &drawPixelsTex_); + render_->DeleteTexture(drawPixelsTex_); drawPixelsTex_ = 0; } if (stencilUploadProgram_) { - glsl_destroy(stencilUploadProgram_); + render_->DeleteProgram(stencilUploadProgram_); stencilUploadProgram_ = nullptr; } } @@ -297,12 +300,6 @@ void FramebufferManagerGLES::DestroyDeviceObjects() { FramebufferManagerGLES::~FramebufferManagerGLES() { DestroyDeviceObjects(); - if (pixelBufObj_) { - for (int i = 0; i < MAX_PBO; i++) { - glDeleteBuffers(1, &pixelBufObj_[i].handle); - } - delete[] pixelBufObj_; - } delete [] convBuf_; } @@ -317,95 +314,68 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma } } - if (drawPixelsTex_ && (drawPixelsTexFormat_ != srcPixelFormat || drawPixelsTexW_ != texWidth || drawPixelsTexH_ != height)) { - glDeleteTextures(1, &drawPixelsTex_); - drawPixelsTex_ = 0; + if (drawPixelsTex_) { + render_->DeleteTexture(drawPixelsTex_); } - if (!drawPixelsTex_) { - drawPixelsTex_ = textureCacheGL_->AllocTextureName(); - drawPixelsTexW_ = texWidth; - drawPixelsTexH_ = height; + drawPixelsTex_ = render_->CreateTexture(GL_TEXTURE_2D); + drawPixelsTexW_ = texWidth; + drawPixelsTexH_ = height; - // Initialize backbuffer texture for DrawPixels - glBindTexture(GL_TEXTURE_2D, drawPixelsTex_); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - drawPixelsTexFormat_ = srcPixelFormat; - } else { - glBindTexture(GL_TEXTURE_2D, drawPixelsTex_); - } + drawPixelsTexFormat_ = srcPixelFormat; // TODO: We can just change the texture format and flip some bits around instead of this. // Could share code with the texture cache perhaps. - bool useConvBuf = false; - if (srcPixelFormat != GE_FORMAT_8888 || srcStride != texWidth) { - useConvBuf = true; - u32 neededSize = texWidth * height * 4; - if (!convBuf_ || convBufSize_ < neededSize) { - delete [] convBuf_; - convBuf_ = new u8[neededSize]; - convBufSize_ = neededSize; - } - for (int y = 0; y < height; y++) { - switch (srcPixelFormat) { - case GE_FORMAT_565: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA565ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_5551: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_4444: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_8888: - { - const u8 *src = srcPixels + srcStride * 4 * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - memcpy(dst, src, 4 * width); - } - break; - - case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels()."); - break; + u32 neededSize = texWidth * height * 4; + u8 *convBuf = new u8[neededSize]; + for (int y = 0; y < height; y++) { + switch (srcPixelFormat) { + case GE_FORMAT_565: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA565ToRGBA8888((u32 *)dst, src, width); } + break; + + case GE_FORMAT_5551: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width); + } + break; + + case GE_FORMAT_4444: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width); + } + break; + + case GE_FORMAT_8888: + { + const u8 *src = srcPixels + srcStride * 4 * y; + u8 *dst = convBuf + 4 * texWidth * y; + memcpy(dst, src, 4 * width); + } + break; + + case GE_FORMAT_INVALID: + _dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels()."); + break; } } + render_->TextureImage(drawPixelsTex_, 0, texWidth, height, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, convBuf, GLRAllocType::NEW, false); + render_->FinalizeTexture(drawPixelsTex_, 0, false); - // Try to skip uploading the unnecessary parts. - if (gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE) && width != texWidth) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, texWidth); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels); - } - CHECK_GL_ERROR_IF_DEBUG(); + // TODO: Return instead? + render_->BindTexture(0, drawPixelsTex_); } void FramebufferManagerGLES::SetViewport2D(int x, int y, int w, int h) { - glstate.viewport.set(x, y, w, h); + render_->SetViewport({ (float)x, (float)y, (float)w, (float)h, 0.0f, 1.0f }); } // x, y, w, h are relative coordinates against destW/destH, which is not very intuitive. @@ -418,7 +388,7 @@ void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float u0,v1, }; - static const GLushort indices[4] = {0,1,3,2}; + static const GLushort indices[4] = { 0,1,3,2 }; if (uvRotation != ROTATION_LOCKED_HORIZONTAL) { float temp[8]; @@ -437,9 +407,9 @@ void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float float pos[12] = { x,y,0, - x+w,y,0, - x+w,y+h,0, - x,y+h,0 + x + w,y,0, + x + w,y + h,0, + x,y + h,0 }; float invDestW = 1.0f / (destW * 0.5f); @@ -449,44 +419,37 @@ void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float pos[i * 3 + 1] = pos[i * 3 + 1] * invDestH - 1.0f; } - // Upscaling postshaders doesn't look well with linear + // We always want a plain state here, well, except for when it's used by the stencil stuff... + render_->SetDepth(false, false, GL_ALWAYS); + render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE); + if (!(flags & DRAWTEX_KEEP_STENCIL_ALPHA)) { + render_->SetNoBlendAndMask(0xF); + render_->SetStencilDisabled(); + } + + // Upscaling postshaders don't look well with linear if (flags & DRAWTEX_LINEAR) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + render_->SetTextureSampler(0, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, 0.0f); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + render_->SetTextureSampler(0, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f); } - const GLSLProgram *program = glsl_get_program(); - if (!program) { - ERROR_LOG(FRAMEBUF, "Trying to DrawActiveTexture() without a program"); - return; - } + Simple2DVertex verts[4]; + memcpy(verts[0].pos, &pos[0], 12); + memcpy(verts[1].pos, &pos[3], 12); + memcpy(verts[3].pos, &pos[6], 12); + memcpy(verts[2].pos, &pos[9], 12); + memcpy(verts[0].uv, &texCoords[0], 8); + memcpy(verts[1].uv, &texCoords[2], 8); + memcpy(verts[3].uv, &texCoords[4], 8); + memcpy(verts[2].uv, &texCoords[6], 8); - glEnableVertexAttribArray(program->a_position); - glEnableVertexAttribArray(program->a_texcoord0); - if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - drawEngineGL_->BindBuffer(pos, sizeof(pos), texCoords, sizeof(texCoords)); - drawEngineGL_->BindElementBuffer(indices, sizeof(indices)); - glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, 12, 0); - glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, (void *)sizeof(pos)); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); - } else { - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); - glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, 12, pos); - glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, texCoords); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, indices); - } - glDisableVertexAttribArray(program->a_position); - glDisableVertexAttribArray(program->a_texcoord0); -} - -void FramebufferManagerGLES::RebindFramebuffer() { - FramebufferManagerCommon::RebindFramebuffer(); - if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE) - glstate.viewport.restore(); + uint32_t bindOffset; + GLRBuffer *buffer; + void *dest = drawEngineGL_->GetPushVertexBuffer()->Push(sizeof(verts), &bindOffset, &buffer); + memcpy(dest, verts, sizeof(verts)); + render_->BindVertexBuffer(simple2DInputLayout_, buffer, bindOffset); + render_->Draw(GL_TRIANGLE_STRIP, 0, 4); } void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) { @@ -505,6 +468,7 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE if (old == GE_FORMAT_565) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + gstate_c.Dirty(DIRTY_BLEND_STATE); } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); } @@ -527,17 +491,15 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) { // Let's only do this if not clearing depth. - glstate.scissorTest.force(false); draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST); dst->last_frame_depth_updated = gpuStats.numFlips; - glstate.scissorTest.restore(); } } } void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { - glBindTexture(GL_TEXTURE_2D, 0); + render_->BindTexture(stage, nullptr); gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; return; } @@ -565,48 +527,6 @@ void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFra } } -void FramebufferManagerGLES::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { - PROFILE_THIS_SCOPE("gpu-readback"); - if (sync) { - // flush async just in case when we go for synchronous update - // Doesn't actually pack when sent a null argument. - PackFramebufferAsync_(nullptr); - } - - if (vfb) { - // We'll pseudo-blit framebuffers here to get a resized version of vfb. - VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb); - OptimizeDownloadRange(vfb, x, y, w, h); - BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0); - - // PackFramebufferSync_() - Synchronous pixel data transfer using glReadPixels - // PackFramebufferAsync_() - Asynchronous pixel data transfer using glReadPixels with PBOs - - if (gl_extensions.IsGLES) { - PackFramebufferSync_(nvfb, x, y, w, h); - } else { - // TODO: Can we fall back to sync without these? - if (gl_extensions.ARB_pixel_buffer_object && gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT)) { - if (!sync) { - PackFramebufferAsync_(nvfb); - } else { - PackFramebufferSync_(nvfb, x, y, w, h); - } - } - } - - textureCacheGL_->ForgetLastTexture(); - RebindFramebuffer(); - } -} - -void FramebufferManagerGLES::DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) { - PROFILE_THIS_SCOPE("gpu-readback"); - // Flush async just in case. - PackFramebufferAsync_(nullptr); - FramebufferManagerCommon::DownloadFramebufferForClut(fb_address, loadBytes); -} - bool FramebufferManagerGLES::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) { // When updating VRAM, it need to be exact format. if (!gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD)) { @@ -641,12 +561,10 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) // Discard the previous contents of this buffer where possible. if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); - GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT }; - glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); } else if (gl_extensions.IsGLES) { draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + gstate_c.Dirty(DIRTY_BLEND_STATE); } - CHECK_GL_ERROR_IF_DEBUG(); } void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { @@ -699,12 +617,10 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2; if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) { draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT); - CHECK_GL_ERROR_IF_DEBUG(); return; } } - glstate.scissorTest.force(false); if (useBlit) { draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST); } else { @@ -714,43 +630,23 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, // Make sure our 2D drawing program is ready. Compiles only if not already compiled. CompileDraw2DProgram(); - glstate.viewport.force(0, 0, dst->renderWidth, dst->renderHeight); - glstate.blend.force(false); - glstate.cullFace.force(false); - glstate.depthTest.force(false); - glstate.stencilTest.force(false); -#if !defined(USING_GLES2) - glstate.colorLogicOp.force(false); -#endif - glstate.colorMask.force(true, true, true, true); - glstate.stencilMask.force(0xFF); + render_->SetViewport({ 0, 0, (float)dst->renderWidth, (float)dst->renderHeight, 0, 1.0f }); + render_->SetStencilDisabled(); + render_->SetDepth(false, false, GL_ALWAYS); + render_->SetNoBlendAndMask(0xF); // The first four coordinates are relative to the 6th and 7th arguments of DrawActiveTexture. // Should maybe revamp that interface. float srcW = src->bufferWidth; float srcH = src->bufferHeight; - glsl_bind(draw2dprogram_); + render_->BindProgram(draw2dprogram_); DrawActiveTexture(dstX1, dstY1, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST); - glBindTexture(GL_TEXTURE_2D, 0); textureCacheGL_->ForgetLastTexture(); - glstate.viewport.restore(); - glstate.blend.restore(); - glstate.cullFace.restore(); - glstate.depthTest.restore(); - glstate.stencilTest.restore(); -#if !defined(USING_GLES2) - glstate.colorLogicOp.restore(); -#endif - glstate.colorMask.restore(); - glstate.stencilMask.restore(); } - glstate.scissorTest.restore(); - CHECK_GL_ERROR_IF_DEBUG(); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); } -// TODO: SSE/NEON -// Could also make C fake-simd for 64-bit, two 8888 pixels fit in a register :) void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) { // Must skip stride in the cases below. Some games pack data into the cracks, like MotoGP. const u32 *src32 = (const u32 *)src; @@ -806,193 +702,6 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u } } -void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) { - CHECK_GL_ERROR_IF_DEBUG(); - GLubyte *packed = 0; - bool unbind = false; - const u8 nextPBO = (currentPBO_ + 1) % MAX_PBO; - const bool useCPU = gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD); - - // We'll prepare two PBOs to switch between readying and reading - if (!pixelBufObj_) { - if (!vfb) { - // This call is just to flush the buffers. We don't have any yet, - // so there's nothing to do. - return; - } - - GLuint pbos[MAX_PBO]; - glGenBuffers(MAX_PBO, pbos); - - pixelBufObj_ = new AsyncPBO[MAX_PBO]; - for (int i = 0; i < MAX_PBO; i++) { - pixelBufObj_[i].handle = pbos[i]; - pixelBufObj_[i].maxSize = 0; - pixelBufObj_[i].reading = false; - } - } - - // Receive previously requested data from a PBO - AsyncPBO &pbo = pixelBufObj_[nextPBO]; - if (pbo.reading) { - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo.handle); -#ifdef USING_GLES2 - // Not on desktop GL 2.x... - packed = (GLubyte *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pbo.size, GL_MAP_READ_BIT); -#else - packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); -#endif - - if (packed) { - DEBUG_LOG(FRAMEBUF, "Reading PBO to memory , bufSize = %u, packed = %p, fb_address = %08x, stride = %u, pbo = %u", - pbo.size, packed, pbo.fb_address, pbo.stride, nextPBO); - - if (useCPU) { - u8 *dst = Memory::GetPointer(pbo.fb_address); - ConvertFromRGBA8888(dst, packed, pbo.stride, pbo.stride, pbo.stride, pbo.height, pbo.format); - } else { - // We don't need to convert, GPU already did (or should have) - Memory::MemcpyUnchecked(pbo.fb_address, packed, pbo.size); - } - - pbo.reading = false; - } - - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - unbind = true; - } - - // Order packing/readback of the framebuffer - if (vfb) { - bool reverseOrder = gstate_c.Supports(GPU_PREFER_REVERSE_COLOR_ORDER); - Draw::DataFormat dataFmt = Draw::DataFormat::UNDEFINED; - switch (vfb->format) { - case GE_FORMAT_4444: - dataFmt = (reverseOrder ? Draw::DataFormat::A4R4G4B4_UNORM_PACK16 : Draw::DataFormat::B4G4R4A4_UNORM_PACK16); - break; - case GE_FORMAT_5551: - dataFmt = (reverseOrder ? Draw::DataFormat::A1R5G5B5_UNORM_PACK16 : Draw::DataFormat::B5G5R5A1_UNORM_PACK16); - break; - case GE_FORMAT_565: - dataFmt = (reverseOrder ? Draw::DataFormat::R5G6B5_UNORM_PACK16 : Draw::DataFormat::B5G6R5_UNORM_PACK16); - break; - case GE_FORMAT_8888: - dataFmt = Draw::DataFormat::R8G8B8A8_UNORM; - break; - }; - - if (useCPU) { - dataFmt = Draw::DataFormat::R8G8B8A8_UNORM; - } - - - int pixelSize = (int)DataFormatSizeInBytes(dataFmt); - int align = pixelSize; - - // If using the CPU, we need 4 bytes per pixel always. - u32 bufSize = vfb->fb_stride * vfb->height * pixelSize; - u32 fb_address = (0x04000000) | vfb->fb_address; - - if (!vfb->fbo) { - ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferAsync_: vfb->fbo == 0"); - return; - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBufObj_[currentPBO_].handle); - - if (pixelBufObj_[currentPBO_].maxSize < bufSize) { - // We reserve a buffer big enough to fit all those pixels - glBufferData(GL_PIXEL_PACK_BUFFER, bufSize, NULL, GL_DYNAMIC_READ); - pixelBufObj_[currentPBO_].maxSize = bufSize; - } - - // TODO: This is a hack since PBOs have not been implemented in Thin3D yet(and maybe shouldn't? maybe should do this internally?) - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->fb_stride, vfb->height, dataFmt, nullptr, vfb->fb_stride); - - unbind = true; - - pixelBufObj_[currentPBO_].fb_address = fb_address; - pixelBufObj_[currentPBO_].size = bufSize; - pixelBufObj_[currentPBO_].stride = vfb->fb_stride; - pixelBufObj_[currentPBO_].height = vfb->height; - pixelBufObj_[currentPBO_].format = vfb->format; - pixelBufObj_[currentPBO_].reading = true; - } - - currentPBO_ = nextPBO; - - if (unbind) { - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - } - CHECK_GL_ERROR_IF_DEBUG(); -} - -void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) { - if (!vfb->fbo) { - ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferSync_: vfb->fbo == 0"); - return; - } - - int possibleH = std::max(vfb->height - y, 0); - if (h > possibleH) { - h = possibleH; - } - - bool convert = vfb->format != GE_FORMAT_8888; - const int dstBpp = vfb->format == GE_FORMAT_8888 ? 4 : 2; - const int packWidth = std::min(vfb->fb_stride, std::min(x + w, (int)vfb->width)); - - // Pixel size always 4 here because we always request RGBA8888 - u32 bufSize = packWidth * h * 4; - u32 fb_address = 0x04000000 | vfb->fb_address; - - if (gl_extensions.IsGLES && !gl_extensions.GLES3 && packWidth != vfb->fb_stride && h != 1) { - // Need to use a temp buffer, since GLES2 doesn't support GL_PACK_ROW_LENGTH. - convert = true; - } - - int dstByteOffset = y * vfb->fb_stride * dstBpp; - u8 *dst = Memory::GetPointer(fb_address + dstByteOffset); - - u8 *packed = nullptr; - if (!convert) { - packed = (u8 *)dst; - } else { - // End result may be 16-bit but we are reading 32-bit, so there may not be enough space at fb_address - if (!convBuf_ || convBufSize_ < bufSize) { - delete [] convBuf_; - convBuf_ = new u8[bufSize]; - convBufSize_ = bufSize; - } - packed = convBuf_; - } - - if (packed) { - DEBUG_LOG(FRAMEBUF, "Reading framebuffer to mem, bufSize = %u, fb_address = %08x", bufSize, fb_address); - // Avoid reading the part between width and stride, if possible. - int packStride = convert || h == 1 ? packWidth : vfb->fb_stride; - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, packed, packStride); - - if (convert) { - ConvertFromRGBA8888(dst, packed, vfb->fb_stride, packStride, packWidth, h, vfb->format); - } - } - - // TODO: Move this into Thin3d. - if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { -#ifdef USING_GLES2 - // GLES3 doesn't support using GL_READ_FRAMEBUFFER here. - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); - const GLenum target = GL_FRAMEBUFFER; -#else - const GLenum target = GL_READ_FRAMEBUFFER; -#endif - GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; - glInvalidateFramebuffer(target, 3, attachments); - } - CHECK_GL_ERROR_IF_DEBUG(); -} - void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) { if (!vfb->fbo) { ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0"); @@ -1033,26 +742,9 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int } } } - CHECK_GL_ERROR_IF_DEBUG(); } void FramebufferManagerGLES::EndFrame() { - CHECK_GL_ERROR_IF_DEBUG(); - - // Let's explicitly invalidate any temp FBOs used during this frame. - if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { - for (auto temp : tempFBOs_) { - if (temp.second.last_frame_used < gpuStats.numFlips) { - continue; - } - - draw_->BindFramebufferAsRenderTarget(temp.second.fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); - GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT }; - glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); - } - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP , Draw::RPAction::KEEP, Draw::RPAction::KEEP }); - } - CHECK_GL_ERROR_IF_DEBUG(); } void FramebufferManagerGLES::DeviceLost() { @@ -1062,11 +754,11 @@ void FramebufferManagerGLES::DeviceLost() { void FramebufferManagerGLES::DeviceRestore(Draw::DrawContext *draw) { draw_ = draw; + render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); CreateDeviceObjects(); } void FramebufferManagerGLES::DestroyAllFBOs() { - CHECK_GL_ERROR_IF_DEBUG(); currentRenderVfb_ = 0; displayFramebuf_ = 0; prevDisplayFramebuf_ = 0; @@ -1091,27 +783,20 @@ void FramebufferManagerGLES::DestroyAllFBOs() { tempFBOs_.clear(); SetNumExtraFBOs(0); - - DisableState(); - CHECK_GL_ERROR_IF_DEBUG(); } void FramebufferManagerGLES::Resized() { FramebufferManagerCommon::Resized(); + render_->Resize(PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); if (UpdateSize()) { DestroyAllFBOs(); } -#ifndef USING_GLES2 - if (g_Config.iInternalResolution == 0) { - glLineWidth(std::max(1, (int)(renderWidth_ / 480))); - glPointSize(std::max(1.0f, (float)(renderWidth_ / 480.f))); - } else { - glLineWidth(g_Config.iInternalResolution); - glPointSize((float)g_Config.iInternalResolution); - } -#endif + // Might have a new post shader - let's compile it. + CompilePostShader(); + + // render_->SetLineWidth(renderWidth_ / 480.0f); } bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) { diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 94c87ae982..fb00c41858 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -29,28 +29,16 @@ #include "Core/Config.h" #include "GPU/GPUCommon.h" #include "GPU/Common/FramebufferCommon.h" +#include "thin3d/GLRenderManager.h" struct GLSLProgram; class TextureCacheGLES; class DrawEngineGLES; class ShaderManagerGLES; -// Simple struct for asynchronous PBO readbacks -struct AsyncPBO { - uint32_t handle; - u32 maxSize; - - u32 fb_address; - u32 stride; - u32 height; - u32 size; - GEBufferFormat format; - bool reading; -}; - class FramebufferManagerGLES : public FramebufferManagerCommon { public: - FramebufferManagerGLES(Draw::DrawContext *draw); + FramebufferManagerGLES(Draw::DrawContext *draw, GLRenderManager *render); ~FramebufferManagerGLES(); void SetTextureCache(TextureCacheGLES *tc); @@ -66,7 +54,6 @@ public: void EndFrame(); void Resized() override; void DeviceLost(); - void SetLineWidth(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; @@ -74,20 +61,14 @@ public: // For use when texturing from a framebuffer. May create a duplicate if target. void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - // Reads a rectangular subregion of a framebuffer to the right position in its backing memory. - void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) override; - void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) override; - bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; - virtual void RebindFramebuffer() override; void DeviceRestore(Draw::DrawContext *draw); protected: void SetViewport2D(int x, int y, int w, int h) override; - void DisableState() override; // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override; @@ -103,35 +84,44 @@ private: void Bind2DShader() override; void BindPostShader(const PostShaderUniforms &uniforms) override; void CompileDraw2DProgram(); - void DestroyDraw2DProgram(); void CompilePostShader(); - void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently - void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) override; void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h); + GLRenderManager *render_; + // Used by DrawPixels - unsigned int drawPixelsTex_; - GEBufferFormat drawPixelsTexFormat_; - int drawPixelsTexW_; - int drawPixelsTexH_; + GLRTexture *drawPixelsTex_ = nullptr; + GEBufferFormat drawPixelsTexFormat_ = GE_FORMAT_INVALID; + int drawPixelsTexW_ = 0; + int drawPixelsTexH_ = 0; - u8 *convBuf_; - u32 convBufSize_; - GLSLProgram *draw2dprogram_ = nullptr; - GLSLProgram *postShaderProgram_ = nullptr; - GLSLProgram *stencilUploadProgram_ = nullptr; - int plainColorLoc_; - int videoLoc_; - int timeLoc_; - int pixelDeltaLoc_; - int deltaLoc_; + u8 *convBuf_ = nullptr; + u32 convBufSize_ = 0; + GLRProgram *draw2dprogram_ = nullptr; + GLRProgram *postShaderProgram_ = nullptr; - TextureCacheGLES *textureCacheGL_; - ShaderManagerGLES *shaderManagerGL_; - DrawEngineGLES *drawEngineGL_; + GLRProgram *stencilUploadProgram_ = nullptr; + int u_stencilUploadTex = -1; + int u_stencilValue = -1; + int u_postShaderTex = -1; + + // Cached uniform locs + int u_draw2d_tex = -1; - // Not used under ES currently. - AsyncPBO *pixelBufObj_; //this isn't that large - u8 currentPBO_; + int plainColorLoc_ = -1; + int videoLoc_ = -1; + int timeLoc_ = -1; + int pixelDeltaLoc_ = -1; + int deltaLoc_ = -1; + + TextureCacheGLES *textureCacheGL_ = nullptr; + ShaderManagerGLES *shaderManagerGL_ = nullptr; + DrawEngineGLES *drawEngineGL_ = nullptr; + + struct Simple2DVertex { + float pos[3]; + float uv[2]; + }; + GLRInputLayout *simple2DInputLayout_ = nullptr; }; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index b6f112a0ae..ca64acae56 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -36,7 +36,6 @@ #include "GPU/GeDisasm.h" #include "GPU/Common/FramebufferCommon.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/GPU_GLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" @@ -52,39 +51,15 @@ #include "Windows/GPU/WindowsGLContext.h" #endif -struct GLESCommandTableEntry { - uint8_t cmd; - uint8_t flags; - uint64_t dirty; - GPU_GLES::CmdFunc func; -}; - -// This table gets crunched into a faster form by init. -// TODO: Share this table between the backends. Will have to make another indirection for the function pointers though.. -static const GLESCommandTableEntry commandTable[] = { - // Changes that dirty the current texture. - { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_TexSize0 }, - - // Changing the vertex type requires us to flush. - { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_VertexType }, - - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_GLES::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, - - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_LoadClut }, -}; - -GPU_GLES::CommandInfo GPU_GLES::cmdInfo_[256]; - GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) -: GPUCommon(gfxCtx, draw) { +: GPUCommon(gfxCtx, draw), drawEngine_(draw), fragmentTestCache_(draw), depalShaderCache_(draw) { UpdateVsyncInterval(true); CheckGPUFeatures(); - shaderManagerGL_ = new ShaderManagerGLES(); - framebufferManagerGL_ = new FramebufferManagerGLES(draw); + GLRenderManager *render = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + + shaderManagerGL_ = new ShaderManagerGLES(render); + framebufferManagerGL_ = new FramebufferManagerGLES(draw, render); framebufferManager_ = framebufferManagerGL_; textureCacheGL_ = new TextureCacheGLES(draw); textureCache_ = textureCacheGL_; @@ -111,57 +86,13 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - memset(cmdInfo_, 0, sizeof(cmdInfo_)); - - // Import both the global and local command tables, and check for dupes - std::set dupeCheck; - for (size_t i = 0; i < commonCommandTableSize; i++) { - const u8 cmd = commonCommandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); - cmdInfo_[cmd].func = commonCommandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - - for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { - const u8 cmd = commandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commandTable[i].flags | (commandTable[i].dirty << 8); - cmdInfo_[cmd].func = commandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - // Find commands missing from the table. - for (int i = 0; i < 0xEF; i++) { - if (dupeCheck.find((u8)i) == dupeCheck.end()) { - ERROR_LOG(G3D, "Command missing from table: %02x (%i)", i, i); - } - } - // No need to flush before the tex scale/offset commands if we are baking // the tex scale/offset into the vertices anyway. - UpdateCmdInfo(); - BuildReportingInfo(); // Update again after init to be sure of any silly driver problems. UpdateVsyncInterval(true); - // Some of our defaults are different from hw defaults, let's assert them. - // We restore each frame anyway, but here is convenient for tests. - glstate.Restore(); - drawEngine_.RestoreVAO(); textureCacheGL_->NotifyConfigChanged(); // Load shader cache. @@ -187,6 +118,12 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) } GPU_GLES::~GPU_GLES() { + GLRenderManager *render = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + render->Wipe(); + + // If we're here during app shutdown (exiting the Windows app in-game, for example) + // everything should already be cleared since DeviceLost has been run. + framebufferManagerGL_->DestroyAllFBOs(); shaderManagerGL_->ClearCache(true); depalShaderCache_.Clear(); @@ -298,9 +235,6 @@ void GPU_GLES::CheckGPUFeatures() { if (gl_extensions.OES_texture_npot) features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; - if (gl_extensions.EXT_unpack_subimage) - features |= GPU_SUPPORTS_UNPACK_SUBIMAGE; - if (gl_extensions.EXT_blend_minmax) features |= GPU_SUPPORTS_BLEND_MINMAX; @@ -322,8 +256,7 @@ void GPU_GLES::CheckGPUFeatures() { if (instanceRendering) features |= GPU_SUPPORTS_INSTANCE_RENDERING; - int maxVertexTextureImageUnits; - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); + int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; if (maxVertexTextureImageUnits >= 3) // At least 3 for hardware tessellation features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; @@ -368,30 +301,23 @@ bool GPU_GLES::IsReady() { return shaderManagerGL_->ContinuePrecompile(); } -// Let's avoid passing nulls into snprintf(). -static const char *GetGLStringAlways(GLenum name) { - const GLubyte *value = glGetString(name); - if (!value) - return "?"; - return (const char *)value; -} - -// Needs to be called on GPU thread, not reporting thread. void GPU_GLES::BuildReportingInfo() { - const char *glVendor = GetGLStringAlways(GL_VENDOR); - const char *glRenderer = GetGLStringAlways(GL_RENDERER); - const char *glVersion = GetGLStringAlways(GL_VERSION); - const char *glSlVersion = GetGLStringAlways(GL_SHADING_LANGUAGE_VERSION); - const char *glExtensions = nullptr; + GLRenderManager *render = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + + std::string glVendor = render->GetGLString(GL_VENDOR); + std::string glRenderer = render->GetGLString(GL_RENDERER); + std::string glVersion = render->GetGLString(GL_VERSION); + std::string glSlVersion = render->GetGLString(GL_SHADING_LANGUAGE_VERSION); + std::string glExtensions; if (gl_extensions.VersionGEThan(3, 0)) { - glExtensions = g_all_gl_extensions.c_str(); + glExtensions = g_all_gl_extensions; } else { - glExtensions = GetGLStringAlways(GL_EXTENSIONS); + glExtensions = render->GetGLString(GL_EXTENSIONS); } char temp[16384]; - snprintf(temp, sizeof(temp), "%s (%s %s), %s (extensions: %s)", glVersion, glVendor, glRenderer, glSlVersion, glExtensions); + snprintf(temp, sizeof(temp), "%s (%s %s), %s (extensions: %s)", glVersion.c_str(), glVendor.c_str(), glRenderer.c_str(), glSlVersion.c_str(), glExtensions.c_str()); reportingPrimaryInfo_ = glVendor; reportingFullInfo_ = temp; @@ -401,6 +327,10 @@ void GPU_GLES::BuildReportingInfo() { void GPU_GLES::DeviceLost() { ILOG("GPU_GLES: DeviceLost"); + // Simply drop all caches and textures. + // FBOs appear to survive? Or no? + // TransformDraw has registered as a GfxResourceHolder. + drawEngine_.ClearInputLayoutMap(); shaderManagerGL_->ClearCache(false); textureCacheGL_->Clear(false); fragmentTestCache_.Clear(false); @@ -413,7 +343,6 @@ void GPU_GLES::DeviceRestore() { draw_ = (Draw::DrawContext *)PSP_CoreParameter().graphicsContext->GetDrawContext(); ILOG("GPU_GLES: DeviceRestore"); - UpdateCmdInfo(); UpdateVsyncInterval(true); textureCacheGL_->DeviceRestore(draw_); @@ -429,19 +358,10 @@ void GPU_GLES::Reinitialize() { } void GPU_GLES::InitClear() { - bool useNonBufferedRendering = g_Config.iRenderingMode == FB_NON_BUFFERED_MODE; - if (useNonBufferedRendering) { - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClearColor(0,0,0,1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); } void GPU_GLES::BeginHostFrame() { GPUCommon::BeginHostFrame(); - UpdateCmdInfo(); if (resized_) { CheckGPUFeatures(); framebufferManager_->Resized(); @@ -449,6 +369,12 @@ void GPU_GLES::BeginHostFrame() { shaderManagerGL_->DirtyShader(); textureCacheGL_->NotifyConfigChanged(); } + + drawEngine_.BeginFrame(); +} + +void GPU_GLES::EndHostFrame() { + drawEngine_.EndFrame(); } inline void GPU_GLES::UpdateVsyncInterval(bool force) { @@ -478,19 +404,7 @@ inline void GPU_GLES::UpdateVsyncInterval(bool force) { #endif } -void GPU_GLES::UpdateCmdInfo() { - if (g_Config.bSoftwareSkinning) { - cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; - } else { - cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexType; - } -} - void GPU_GLES::ReapplyGfxState() { - drawEngine_.RestoreVAO(); - glstate.Restore(); GPUCommon::ReapplyGfxState(); } @@ -500,14 +414,13 @@ void GPU_GLES::BeginFrame() { textureCacheGL_->StartFrame(); drawEngine_.DecimateTrackedVertexArrays(); - drawEngine_.DecimateBuffers(); depalShaderCache_.Decimate(); fragmentTestCache_.Decimate(); GPUCommon::BeginFrame(); - // Save the cache from time to time. TODO: How often? - if (!shaderCachePath_.empty() && (gpuStats.numFlips & 1023) == 0) { + // Save the cache from time to time. TODO: How often? We save on exit, so shouldn't need to do this all that often. + if (!shaderCachePath_.empty() && (gpuStats.numFlips & 4095) == 0) { shaderManagerGL_->Save(shaderCachePath_); } @@ -524,26 +437,6 @@ void GPU_GLES::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat fo framebufferManagerGL_->SetDisplayFramebuffer(framebuf, stride, format); } -bool GPU_GLES::FramebufferDirty() { - VirtualFramebuffer *vfb = framebufferManagerGL_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->dirtyAfterDisplay; - vfb->dirtyAfterDisplay = false; - return dirty; - } - return true; -} - -bool GPU_GLES::FramebufferReallyDirty() { - VirtualFramebuffer *vfb = framebufferManagerGL_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->reallyDirtyAfterDisplay; - vfb->reallyDirtyAfterDisplay = false; - return dirty; - } - return true; -} - void GPU_GLES::CopyDisplayToOutput() { // Flush anything left over. framebufferManagerGL_->RebindFramebuffer(); @@ -551,9 +444,6 @@ void GPU_GLES::CopyDisplayToOutput() { shaderManagerGL_->DirtyLastShader(); - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - framebufferManagerGL_->CopyDisplayToOutput(); framebufferManagerGL_->EndFrame(); @@ -568,44 +458,6 @@ void GPU_GLES::CopyDisplayToOutput() { #endif } -// Maybe should write this in ASM... -void GPU_GLES::FastRunLoop(DisplayList &list) { - PROFILE_THIS_SCOPE("gpuloop"); - const CommandInfo *cmdInfo = cmdInfo_; - int dc = downcount; - for (; dc > 0; --dc) { - // We know that display list PCs have the upper nibble == 0 - no need to mask the pointer - const u32 op = *(const u32 *)(Memory::base + list.pc); - const u32 cmd = op >> 24; - const CommandInfo &info = cmdInfo[cmd]; - const u32 diff = op ^ gstate.cmdmem[cmd]; - if (diff == 0) { - if (info.flags & FLAG_EXECUTE) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } - } else { - uint64_t flags = info.flags; - if (flags & FLAG_FLUSHBEFOREONCHANGE) { - drawEngine_.Flush(); - } - gstate.cmdmem[cmd] = op; - if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } else { - uint64_t dirty = flags >> 8; - if (dirty) - gstate_c.Dirty(dirty); - } - } - list.pc += 4; - } - downcount = 0; -} - void GPU_GLES::FinishDeferred() { // This finishes reading any vertex data that is pending. drawEngine_.FinishDeferred(); @@ -638,81 +490,6 @@ void GPU_GLES::ExecuteOp(u32 op, u32 diff) { } } -void GPU_GLES::Execute_Prim(u32 op, u32 diff) { - // This drives all drawing. All other state we just buffer up, then we apply it only - // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. - - u32 data = op & 0xFFFFFF; - u32 count = data & 0xFFFF; - if (count == 0) - return; - - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - SetDrawType(DRAW_PRIM, prim); - - // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. - - if (gstate.isAntiAliasEnabled()) { - // Discard AA lines in DOA - if (prim == GE_PRIM_LINE_STRIP) - return; - // Discard AA lines in Summon Night 5 - if ((prim == GE_PRIM_LINES) && gstate.isSkinningEnabled()) - return; - } - - // This also makes skipping drawing very effective. This function can change the framebuffer. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - drawEngine_.SetupVertexDecoder(gstate.vertType); - // Rough estimate, not sure what's correct. - cyclesExecuted += EstimatePerVertexCost() * count; - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *inds = 0; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); - return; - } - inds = Memory::GetPointerUnchecked(gstate_c.indexAddr); - } - -#ifndef MOBILE_DEVICE - if (prim > GE_PRIM_RECTANGLES) { - ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); - } -#endif - - if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { - vertexCost_ = EstimatePerVertexCost(); - } - gpuStats.vertexGPUCycles += vertexCost_ * count; - cyclesExecuted += vertexCost_* count; - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitPrim(verts, inds, prim, count, gstate.vertType, &bytesRead); - - // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). - // Some games rely on this, they don't bother reloading VADDR and IADDR. - // The VADDR/IADDR registers are NOT updated. - AdvanceVerts(gstate.vertType, count, bytesRead); -} - -void GPU_GLES::Execute_LoadClut(u32 op, u32 diff) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - textureCacheGL_->LoadClut(gstate.getClutAddress(), gstate.getClutLoadBytes()); -} - void GPU_GLES::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, @@ -762,8 +539,6 @@ void GPU_GLES::ClearShaderCache() { void GPU_GLES::CleanupBeforeUI() { // Clear any enabled vertex arrays. shaderManagerGL_->DirtyLastShader(); - glstate.arrayBuffer.bind(0); - glstate.elementArrayBuffer.bind(0); } void GPU_GLES::DoState(PointerWrap &p) { diff --git a/GPU/GLES/GPU_GLES.h b/GPU/GLES/GPU_GLES.h index f99fe6d3e3..6789491090 100644 --- a/GPU/GLES/GPU_GLES.h +++ b/GPU/GLES/GPU_GLES.h @@ -36,7 +36,7 @@ public: ~GPU_GLES(); // This gets called on startup and when we get back from settings. - void CheckGPUFeatures(); + void CheckGPUFeatures() override; bool IsReady() override; @@ -55,34 +55,15 @@ public: void ClearShaderCache() override; void CleanupBeforeUI() override; - bool DecodeTexture(u8 *dest, const GPUgstate &state) override { - return textureCacheGL_->DecodeTexture(dest, state); - } - bool FramebufferDirty() override; - bool FramebufferReallyDirty() override; - - void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override { - primaryInfo = reportingPrimaryInfo_; - fullInfo = reportingFullInfo_; - } - - typedef void (GPU_GLES::*CmdFunc)(u32 op, u32 diff); - struct CommandInfo { - uint64_t flags; - GPU_GLES::CmdFunc func; - }; - - void Execute_Prim(u32 op, u32 diff); - void Execute_LoadClut(u32 op, u32 diff); // Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend. std::vector DebugGetShaderIDs(DebugShaderType shader) override; std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) override; void BeginHostFrame() override; + void EndHostFrame() override; protected: - void FastRunLoop(DisplayList &list) override; void FinishDeferred() override; private: @@ -98,9 +79,6 @@ private: void Reinitialize() override; inline void UpdateVsyncInterval(bool force); - void UpdateCmdInfo(); - - static CommandInfo cmdInfo_[256]; FramebufferManagerGLES *framebufferManagerGL_; TextureCacheGLES *textureCacheGL_; @@ -109,12 +87,10 @@ private: FragmentTestCacheGLES fragmentTestCache_; ShaderManagerGLES *shaderManagerGL_; + std::string shaderCachePath_; + #ifdef _WIN32 int lastVsync_; #endif int vertexCost_ = 0; - - std::string reportingPrimaryInfo_; - std::string reportingFullInfo_; - std::string shaderCachePath_; }; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index cde9d935a7..ad4ee5ead1 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -26,6 +26,8 @@ #include "base/logging.h" #include "base/timeutil.h" #include "gfx/gl_debug_log.h" +#include "gfx_es2/gpu_features.h" +#include "thin3d/GLRenderManager.h" #include "i18n/i18n.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" @@ -35,17 +37,17 @@ #include "Core/Config.h" #include "Core/Host.h" #include "Core/Reporting.h" +#include "Core/System.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/DrawEngineGLES.h" #include "GPU/Common/ShaderUniforms.h" #include "FramebufferManagerGLES.h" -Shader::Shader(const ShaderID &id, const char *code, uint32_t glShaderType, bool useHWTransform, uint32_t attrMask, uint64_t uniformMask) - : failed_(false), useHWTransform_(useHWTransform), attrMask_(attrMask), uniformMask_(uniformMask) { +Shader::Shader(GLRenderManager *render, const char *code, const std::string &desc, uint32_t glShaderType, bool useHWTransform, uint32_t attrMask, uint64_t uniformMask) + : render_(render), failed_(false), useHWTransform_(useHWTransform), attrMask_(attrMask), uniformMask_(uniformMask) { PROFILE_THIS_SCOPE("shadercomp"); isFragment_ = glShaderType == GL_FRAGMENT_SHADER; source_ = code; @@ -56,245 +58,141 @@ Shader::Shader(const ShaderID &id, const char *code, uint32_t glShaderType, bool printf("%s\n", code); #endif #endif - shader = glCreateShader(glShaderType); - glShaderSource(shader, 1, &code, 0); - glCompileShader(shader); - GLint success = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (!success) { -#define MAX_INFO_LOG_SIZE 2048 - GLchar infoLog[MAX_INFO_LOG_SIZE]; - GLsizei len; - glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog); - infoLog[len] = '\0'; -#ifdef __ANDROID__ - ELOG("Error in shader compilation! %s\n", infoLog); - ELOG("Shader source:\n%s\n", (const char *)code); -#endif - - std::string desc = GetShaderString(SHADER_STRING_SHORT_DESC, id); - ERROR_LOG(G3D, "Error in shader compilation for: %s", desc.c_str()); - ERROR_LOG(G3D, "Info log: %s", infoLog); - ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); - Reporting::ReportMessage("Error in shader compilation: info: %s\n%s\n%s", infoLog, desc.c_str(), (const char *)code); -#ifdef SHADERLOG - OutputDebugStringUTF8(infoLog); -#endif - failed_ = true; - shader = 0; - } else { - DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code); - } - CHECK_GL_ERROR_IF_DEBUG(); + shader = render->CreateShader(glShaderType, source_, desc); } Shader::~Shader() { - if (shader) - glDeleteShader(shader); + render_->DeleteShader(shader); } -LinkedShader::LinkedShader(VShaderID VSID, Shader *vs, FShaderID FSID, Shader *fs, bool useHWTransform, bool preloading) - : useHWTransform_(useHWTransform) { +LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, FShaderID FSID, Shader *fs, bool useHWTransform, bool preloading) + : render_(render), useHWTransform_(useHWTransform) { PROFILE_THIS_SCOPE("shaderlink"); - program = glCreateProgram(); vs_ = vs; - glAttachShader(program, vs->shader); - glAttachShader(program, fs->shader); - // Bind attribute locations to fixed locations so that they're - // the same in all shaders. We use this later to minimize the calls to - // glEnableVertexAttribArray and glDisableVertexAttribArray. - glBindAttribLocation(program, ATTR_POSITION, "position"); - glBindAttribLocation(program, ATTR_TEXCOORD, "texcoord"); - glBindAttribLocation(program, ATTR_NORMAL, "normal"); - glBindAttribLocation(program, ATTR_W1, "w1"); - glBindAttribLocation(program, ATTR_W2, "w2"); - glBindAttribLocation(program, ATTR_COLOR0, "color0"); - glBindAttribLocation(program, ATTR_COLOR1, "color1"); + std::vector shaders; + shaders.push_back(vs->shader); + shaders.push_back(fs->shader); -#if !defined(USING_GLES2) - if (gstate_c.Supports(GPU_SUPPORTS_DUALSOURCE_BLEND)) { - // Dual source alpha - glBindFragDataLocationIndexed(program, 0, 0, "fragColor0"); - glBindFragDataLocationIndexed(program, 0, 1, "fragColor1"); - } else if (gl_extensions.VersionGEThan(3, 3, 0)) { - glBindFragDataLocation(program, 0, "fragColor0"); - } -#elif !defined(IOS) - if (gl_extensions.GLES3) { - if (gstate_c.Supports(GPU_SUPPORTS_DUALSOURCE_BLEND)) { - glBindFragDataLocationIndexedEXT(program, 0, 0, "fragColor0"); - glBindFragDataLocationIndexedEXT(program, 0, 1, "fragColor1"); - } - } -#endif - glLinkProgram(program); + std::vector semantics; + semantics.push_back({ ATTR_POSITION, "position" }); + semantics.push_back({ ATTR_TEXCOORD, "texcoord" }); + semantics.push_back({ ATTR_NORMAL, "normal" }); + semantics.push_back({ ATTR_COLOR0, "color0" }); + semantics.push_back({ ATTR_COLOR1, "color1" }); - GLint linkStatus = GL_FALSE; - glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); - if (linkStatus != GL_TRUE) { - GLint bufLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); - if (bufLength) { - char* buf = new char[bufLength]; - glGetProgramInfoLog(program, bufLength, NULL, buf); -#ifdef __ANDROID__ - ELOG("Could not link program:\n %s", buf); -#endif - ERROR_LOG(G3D, "Could not link program:\n %s", buf); + std::vector queries; + queries.push_back({ &u_tex, "tex" }); + queries.push_back({ &u_proj, "u_proj" }); + queries.push_back({ &u_proj_through, "u_proj_through" }); - std::string vs_desc = vs->GetShaderString(SHADER_STRING_SHORT_DESC, VSID); - std::string fs_desc = fs->GetShaderString(SHADER_STRING_SHORT_DESC, FSID); - std::string vs_source = vs->GetShaderString(SHADER_STRING_SOURCE_CODE, VSID); - std::string fs_source = fs->GetShaderString(SHADER_STRING_SOURCE_CODE, FSID); + queries.push_back({ &u_proj, "u_proj" }); + queries.push_back({ &u_proj_through, "u_proj_through" }); + queries.push_back({ &u_texenv, "u_texenv" }); + queries.push_back({ &u_fogcolor, "u_fogcolor" }); + queries.push_back({ &u_fogcoef, "u_fogcoef" }); + queries.push_back({ &u_alphacolorref, "u_alphacolorref" }); + queries.push_back({ &u_alphacolormask, "u_alphacolormask" }); + queries.push_back({ &u_stencilReplaceValue, "u_stencilReplaceValue" }); + queries.push_back({ &u_testtex, "testtex" }); - ERROR_LOG(G3D, "VS desc:\n%s", vs_desc.c_str()); - ERROR_LOG(G3D, "FS desc:\n%s", fs_desc.c_str()); - ERROR_LOG(G3D, "VS:\n%s\n", vs_source.c_str()); - ERROR_LOG(G3D, "FS:\n%s\n", fs_source.c_str()); - if (preloading) { - Reporting::ReportMessage("Error in shader program link during preload: info: %s\nfs: %s\n%s\nvs: %s\n%s", buf, fs_desc.c_str(), fs_source.c_str(), vs_desc.c_str(), vs_source.c_str()); - } else { - Reporting::ReportMessage("Error in shader program link: info: %s\nfs: %s\n%s\nvs: %s\n%s", buf, fs_desc.c_str(), fs_source.c_str(), vs_desc.c_str(), vs_source.c_str()); - } -#ifdef SHADERLOG - OutputDebugStringUTF8(buf); - OutputDebugStringUTF8(vs_source.c_str()); - OutputDebugStringUTF8(fs_source.c_str()); -#endif - delete [] buf; // we're dead! - } - // Prevent a buffer overflow. - numBones = 0; - // Avoid weird attribute enables. - attrMask = 0; - availableUniforms = 0; - return; - } - - INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader); - - u_tex = glGetUniformLocation(program, "tex"); - u_proj = glGetUniformLocation(program, "u_proj"); - u_proj_through = glGetUniformLocation(program, "u_proj_through"); - u_texenv = glGetUniformLocation(program, "u_texenv"); - u_fogcolor = glGetUniformLocation(program, "u_fogcolor"); - u_fogcoef = glGetUniformLocation(program, "u_fogcoef"); - u_alphacolorref = glGetUniformLocation(program, "u_alphacolorref"); - u_alphacolormask = glGetUniformLocation(program, "u_alphacolormask"); - u_stencilReplaceValue = glGetUniformLocation(program, "u_stencilReplaceValue"); - u_testtex = glGetUniformLocation(program, "testtex"); - - u_fbotex = glGetUniformLocation(program, "fbotex"); - u_blendFixA = glGetUniformLocation(program, "u_blendFixA"); - u_blendFixB = glGetUniformLocation(program, "u_blendFixB"); - u_fbotexSize = glGetUniformLocation(program, "u_fbotexSize"); + queries.push_back({ &u_fbotex, "fbotex" }); + queries.push_back({ &u_blendFixA, "u_blendFixA" }); + queries.push_back({ &u_blendFixB, "u_blendFixB" }); + queries.push_back({ &u_fbotexSize, "u_fbotexSize" }); // Transform - u_view = glGetUniformLocation(program, "u_view"); - u_world = glGetUniformLocation(program, "u_world"); - u_texmtx = glGetUniformLocation(program, "u_texmtx"); - if (VSID.Bit(VS_BIT_ENABLE_BONES)) - numBones = TranslateNumBones(VSID.Bits(VS_BIT_BONES, 3) + 1); - else - numBones = 0; - u_depthRange = glGetUniformLocation(program, "u_depthRange"); + queries.push_back({ &u_view, "u_view" }); + queries.push_back({ &u_world, "u_world" }); + queries.push_back({ &u_texmtx, "u_texmtx" }); -#ifdef USE_BONE_ARRAY - u_bone = glGetUniformLocation(program, "u_bone"); -#else - for (int i = 0; i < 8; i++) { - char name[10]; - sprintf(name, "u_bone%i", i); - u_bone[i] = glGetUniformLocation(program, name); - } -#endif + queries.push_back({ &u_depthRange, "u_depthRange" }); // Lighting, texturing - u_ambient = glGetUniformLocation(program, "u_ambient"); - u_matambientalpha = glGetUniformLocation(program, "u_matambientalpha"); - u_matdiffuse = glGetUniformLocation(program, "u_matdiffuse"); - u_matspecular = glGetUniformLocation(program, "u_matspecular"); - u_matemissive = glGetUniformLocation(program, "u_matemissive"); - u_uvscaleoffset = glGetUniformLocation(program, "u_uvscaleoffset"); - u_texclamp = glGetUniformLocation(program, "u_texclamp"); - u_texclampoff = glGetUniformLocation(program, "u_texclampoff"); - u_guardband = glGetUniformLocation(program, "u_guardband"); + queries.push_back({ &u_ambient, "u_ambient" }); + queries.push_back({ &u_matambientalpha, "u_matambientalpha" }); + queries.push_back({ &u_matdiffuse, "u_matdiffuse" }); + queries.push_back({ &u_matspecular, "u_matspecular" }); + queries.push_back({ &u_matemissive, "u_matemissive" }); + queries.push_back({ &u_uvscaleoffset, "u_uvscaleoffset" }); + queries.push_back({ &u_texclamp, "u_texclamp" }); + queries.push_back({ &u_texclampoff, "u_texclampoff" }); + queries.push_back({ &u_guardband, "u_guardband" }); for (int i = 0; i < 4; i++) { - char temp[64]; - sprintf(temp, "u_lightpos%i", i); - u_lightpos[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightdir%i", i); - u_lightdir[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightatt%i", i); - u_lightatt[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightangle%i", i); - u_lightangle[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightspotCoef%i", i); - u_lightspotCoef[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightambient%i", i); - u_lightambient[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightdiffuse%i", i); - u_lightdiffuse[i] = glGetUniformLocation(program, temp); - sprintf(temp, "u_lightspecular%i", i); - u_lightspecular[i] = glGetUniformLocation(program, temp); + static const char * const lightPosNames[4] = { "u_lightpos0", "u_lightpos1", "u_lightpos2", "u_lightpos3", }; + queries.push_back({ &u_lightpos[i], lightPosNames[i] }); + static const char * const lightdir_names[4] = { "u_lightdir0", "u_lightdir1", "u_lightdir2", "u_lightdir3", }; + queries.push_back({ &u_lightdir[i], lightdir_names[i] }); + static const char * const lightatt_names[4] = { "u_lightatt0", "u_lightatt1", "u_lightatt2", "u_lightatt3", }; + queries.push_back({ &u_lightatt[i], lightatt_names[i] }); + static const char * const lightangle_spotCoef_names[4] = { "u_lightangle_spotCoef0", "u_lightangle_spotCoef1", "u_lightangle_spotCoef2", "u_lightangle_spotCoef3", }; + queries.push_back({ &u_lightangle_spotCoef[i], lightangle_spotCoef_names[i] }); + + static const char * const lightambient_names[4] = { "u_lightambient0", "u_lightambient1", "u_lightambient2", "u_lightambient3", }; + queries.push_back({ &u_lightambient[i], lightambient_names[i] }); + static const char * const lightdiffuse_names[4] = { "u_lightdiffuse0", "u_lightdiffuse1", "u_lightdiffuse2", "u_lightdiffuse3", }; + queries.push_back({ &u_lightdiffuse[i], lightdiffuse_names[i] }); + static const char * const lightspecular_names[4] = { "u_lightspecular0", "u_lightspecular1", "u_lightspecular2", "u_lightspecular3", }; + queries.push_back({ &u_lightspecular[i], lightspecular_names[i] }); } // We need to fetch these unconditionally, gstate_c.spline or bezier will not be set if we // create this shader at load time from the shader cache. - u_tess_pos_tex = glGetUniformLocation(program, "u_tess_pos_tex"); - u_tess_tex_tex = glGetUniformLocation(program, "u_tess_tex_tex"); - u_tess_col_tex = glGetUniformLocation(program, "u_tess_col_tex"); - u_spline_count_u = glGetUniformLocation(program, "u_spline_count_u"); - u_spline_count_v = glGetUniformLocation(program, "u_spline_count_v"); - u_spline_type_u = glGetUniformLocation(program, "u_spline_type_u"); - u_spline_type_v = glGetUniformLocation(program, "u_spline_type_v"); + queries.push_back({ &u_tess_pos_tex, "u_tess_pos_tex" }); + queries.push_back({ &u_tess_tex_tex, "u_tess_tex_tex" }); + queries.push_back({ &u_tess_col_tex, "u_tess_col_tex" }); + queries.push_back({ &u_spline_count_u, "u_spline_count_u" }); + queries.push_back({ &u_spline_count_v, "u_spline_count_v" }); + queries.push_back({ &u_spline_type_u, "u_spline_type_u" }); + queries.push_back({ &u_spline_type_v, "u_spline_type_v" }); attrMask = vs->GetAttrMask(); availableUniforms = vs->GetUniformMask() | fs->GetUniformMask(); - glUseProgram(program); + std::vector initialize; + initialize.push_back({ &u_tex, 0, 0 }); + initialize.push_back({ &u_fbotex, 0, 1 }); + initialize.push_back({ &u_testtex, 0, 2 }); + initialize.push_back({ &u_tess_pos_tex, 0, 4 }); // Texture unit 4 + initialize.push_back({ &u_tess_tex_tex, 0, 5 }); // Texture unit 5 + initialize.push_back({ &u_tess_col_tex, 0, 6 }); // Texture unit 6 - // Default uniform values - glUniform1i(u_tex, 0); - glUniform1i(u_fbotex, 1); - glUniform1i(u_testtex, 2); - - if (u_tess_pos_tex != -1) - glUniform1i(u_tess_pos_tex, 4); // Texture unit 4 - if (u_tess_tex_tex != -1) - glUniform1i(u_tess_tex_tex, 5); // Texture unit 5 - if (u_tess_col_tex != -1) - glUniform1i(u_tess_col_tex, 6); // Texture unit 6 + program = render->CreateProgram(shaders, semantics, queries, initialize, gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND); // The rest, use the "dirty" mechanism. dirtyUniforms = DIRTY_ALL_UNIFORMS; - CHECK_GL_ERROR_IF_DEBUG(); } LinkedShader::~LinkedShader() { - // Shaders are automatically detached by glDeleteProgram. - glDeleteProgram(program); + render_->DeleteProgram(program); } // Utility -static void SetColorUniform3(int uniform, u32 color) { - float f[4]; - Uint8x4ToFloat4(f, color); - glUniform3fv(uniform, 1, f); +static inline void SetFloatUniform(GLRenderManager *render, GLint *uniform, float value) { + render->SetUniformF(uniform, 1, &value); } -static void SetColorUniform3Alpha(int uniform, u32 color, u8 alpha) { +static inline void SetFloatUniform2(GLRenderManager *render, GLint *uniform, float value[2]) { + render->SetUniformF(uniform, 2, value); +} + +static inline void SetColorUniform3(GLRenderManager *render, GLint *uniform, u32 color) { + float f[4]; + Uint8x4ToFloat4(f, color); + render->SetUniformF(uniform, 3, f); +} + +static void SetColorUniform3Alpha(GLRenderManager *render, GLint *uniform, u32 color, u8 alpha) { float f[4]; Uint8x3ToFloat4_AlphaUint8(f, color, alpha); - glUniform4fv(uniform, 1, f); + render->SetUniformF(uniform, 4, f); } // This passes colors unscaled (e.g. 0 - 255 not 0 - 1.) -static void SetColorUniform3Alpha255(int uniform, u32 color, u8 alpha) { +static void SetColorUniform3Alpha255(GLRenderManager *render, GLint *uniform, u32 color, u8 alpha) { if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) { const float col[4] = { (float)((color & 0xFF) >> 0) * (1.0f / 255.0f), @@ -302,7 +200,7 @@ static void SetColorUniform3Alpha255(int uniform, u32 color, u8 alpha) { (float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f), (float)alpha * (1.0f / 255.0f) }; - glUniform4fv(uniform, 1, col); + render->SetUniformF(uniform, 4, col); } else { const float col[4] = { (float)((color & 0xFF) >> 0), @@ -310,44 +208,44 @@ static void SetColorUniform3Alpha255(int uniform, u32 color, u8 alpha) { (float)((color & 0xFF0000) >> 16), (float)alpha }; - glUniform4fv(uniform, 1, col); + render->SetUniformF(uniform, 4, col); } } -static void SetColorUniform3iAlpha(int uniform, u32 color, u8 alpha) { +static void SetColorUniform3iAlpha(GLRenderManager *render, GLint *uniform, u32 color, u8 alpha) { const int col[4] = { (int)((color & 0xFF) >> 0), (int)((color & 0xFF00) >> 8), (int)((color & 0xFF0000) >> 16), (int)alpha, }; - glUniform4iv(uniform, 1, col); + render->SetUniformI(uniform, 4, col); } -static void SetColorUniform3ExtraFloat(int uniform, u32 color, float extra) { +static void SetColorUniform3ExtraFloat(GLRenderManager *render, GLint *uniform, u32 color, float extra) { const float col[4] = { ((color & 0xFF)) / 255.0f, ((color & 0xFF00) >> 8) / 255.0f, ((color & 0xFF0000) >> 16) / 255.0f, extra }; - glUniform4fv(uniform, 1, col); + render->SetUniformF(uniform, 4, col); } -static void SetFloat24Uniform3(int uniform, const uint32_t data[3]) { +static void SetFloat24Uniform3(GLRenderManager *render, GLint *uniform, const uint32_t data[3]) { float f[4]; ExpandFloat24x3ToFloat4(f, data); - glUniform3fv(uniform, 1, f); + render->SetUniformF(uniform, 3, f); } -static void SetFloatUniform4(int uniform, float data[4]) { - glUniform4fv(uniform, 1, data); +static void SetFloatUniform4(GLRenderManager *render, GLint *uniform, float data[4]) { + render->SetUniformF(uniform, 4, data); } -static void SetMatrix4x3(int uniform, const float *m4x3) { +static void SetMatrix4x3(GLRenderManager *render, GLint *uniform, const float *m4x3) { float m4x4[16]; ConvertMatrix4x3To4x4(m4x4, m4x3); - glUniformMatrix4fv(uniform, 1, GL_FALSE, m4x4); + render->SetUniformM4x4(uniform, m4x4); } static inline void ScaleProjMatrix(Matrix4x4 &in) { @@ -361,34 +259,12 @@ static inline void ScaleProjMatrix(Matrix4x4 &in) { in.translateAndScale(trans, scale); } -void LinkedShader::use(const VShaderID &VSID, LinkedShader *previous) { - glUseProgram(program); - int enable, disable; - if (previous) { - enable = attrMask & ~previous->attrMask; - disable = (~attrMask) & previous->attrMask; - } else { - enable = attrMask; - disable = ~attrMask; - } - for (int i = 0; i < ATTR_COUNT; i++) { - if (enable & (1 << i)) - glEnableVertexAttribArray(i); - else if (disable & (1 << i)) - glDisableVertexAttribArray(i); - } +void LinkedShader::use(const ShaderID &VSID) { + render_->BindProgram(program); + // Note that we no longer track attr masks here - we do it for the input layouts instead. } -void LinkedShader::stop() { - for (int i = 0; i < ATTR_COUNT; i++) { - if (attrMask & (1 << i)) - glDisableVertexAttribArray(i); - } -} - -void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { - CHECK_GL_ERROR_IF_DEBUG(); - +void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) { u64 dirty = dirtyUniforms & availableUniforms; dirtyUniforms = 0; if (!dirty) @@ -450,7 +326,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { ScaleProjMatrix(flippedMatrix); - glUniformMatrix4fv(u_proj, 1, GL_FALSE, flippedMatrix.m); + render_->SetUniformM4x4(&u_proj, flippedMatrix.m); } if (dirty & DIRTY_PROJTHROUGHMATRIX) { @@ -461,19 +337,19 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { } else { proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0.0f, 0.0f, 1.0f); } - glUniformMatrix4fv(u_proj_through, 1, GL_FALSE, proj_through.getReadPtr()); + render_->SetUniformM4x4(&u_proj_through, proj_through.getReadPtr()); } if (dirty & DIRTY_TEXENV) { - SetColorUniform3(u_texenv, gstate.texenvcolor); + SetColorUniform3(render_, &u_texenv, gstate.texenvcolor); } if (dirty & DIRTY_ALPHACOLORREF) { - SetColorUniform3Alpha255(u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask()); + SetColorUniform3Alpha255(render_, &u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask()); } if (dirty & DIRTY_ALPHACOLORMASK) { - SetColorUniform3iAlpha(u_alphacolormask, gstate.colortestmask, gstate.getAlphaTestMask()); + SetColorUniform3iAlpha(render_, &u_alphacolormask, gstate.colortestmask, gstate.getAlphaTestMask()); } if (dirty & DIRTY_FOGCOLOR) { - SetColorUniform3(u_fogcolor, gstate.fogcolor); + SetColorUniform3(render_, &u_fogcolor, gstate.fogcolor); } if (dirty & DIRTY_FOGCOEF) { float fogcoef[2] = { @@ -496,7 +372,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { ERROR_LOG_REPORT_ONCE(fognan, G3D, "Unhandled fog NaN/INF combo: %f %f", fogcoef[0], fogcoef[1]); } #endif - glUniform2fv(u_fogcoef, 1, fogcoef); + render_->SetUniformF(&u_fogcoef, 2, fogcoef); } if (dirty & DIRTY_UVSCALEOFFSET) { @@ -520,7 +396,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { uvscaleoff[2] = 0.0f; uvscaleoff[3] = 0.0f; } - glUniform4fv(u_uvscaleoffset, 1, uvscaleoff); + render_->SetUniformF(&u_uvscaleoffset, 4, uvscaleoff); } if ((dirty & DIRTY_TEXCLAMP) && u_texclamp != -1) { @@ -542,27 +418,27 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { gstate_c.curTextureXOffset * invW, gstate_c.curTextureYOffset * invH, }; - glUniform4fv(u_texclamp, 1, texclamp); + render_->SetUniformF(&u_texclamp, 4, texclamp); if (u_texclampoff != -1) { - glUniform2fv(u_texclampoff, 1, texclampoff); + render_->SetUniformF(&u_texclampoff, 2, texclampoff); } } // Transform if (dirty & DIRTY_WORLDMATRIX) { - SetMatrix4x3(u_world, gstate.worldMatrix); + SetMatrix4x3(render_, &u_world, gstate.worldMatrix); } if (dirty & DIRTY_VIEWMATRIX) { - SetMatrix4x3(u_view, gstate.viewMatrix); + SetMatrix4x3(render_, &u_view, gstate.viewMatrix); } if (dirty & DIRTY_TEXMATRIX) { - SetMatrix4x3(u_texmtx, gstate.tgenMatrix); + SetMatrix4x3(render_, &u_texmtx, gstate.tgenMatrix); } if (dirty & DIRTY_GUARDBAND) { float gb[4]; ComputeGuardband(gb, 0.0f); - SetFloatUniform4(u_guardband, gb); + SetFloatUniform4(render_, &u_guardband, gb); } if ((dirty & DIRTY_DEPTHRANGE) && u_depthRange != -1) { @@ -589,53 +465,20 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { } float data[4] = { viewZScale, viewZCenter, viewZCenter, viewZInvScale }; - SetFloatUniform4(u_depthRange, data); + SetFloatUniform4(render_, &u_depthRange, data); } if (dirty & DIRTY_STENCILREPLACEVALUE) { - glUniform1f(u_stencilReplaceValue, (float)gstate.getStencilTestRef() * (1.0f / 255.0f)); + float f = (float)gstate.getStencilTestRef() * (1.0f / 255.0f); + render_->SetUniformF(&u_stencilReplaceValue, 1, &f); } - // TODO: Could even set all bones in one go if they're all dirty. -#ifdef USE_BONE_ARRAY - if (u_bone != -1) { - float allBones[8 * 16]; - - bool allDirty = true; - for (int i = 0; i < numBones; i++) { - if (dirty & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i); - } else { - allDirty = false; - } - } - if (allDirty) { - // Set them all with one call - glUniformMatrix4fv(u_bone, numBones, GL_FALSE, allBones); - } else { - // Set them one by one. Could try to coalesce two in a row etc but too lazy. - for (int i = 0; i < numBones; i++) { - if (dirty & (DIRTY_BONEMATRIX0 << i)) { - glUniformMatrix4fv(u_bone + i, 1, GL_FALSE, allBones + 16 * i); - } - } - } - } -#else - float bonetemp[16]; - for (int i = 0; i < numBones; i++) { - if (dirty & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(bonetemp, gstate.boneMatrix + 12 * i); - glUniformMatrix4fv(u_bone[i], 1, GL_FALSE, bonetemp); - } - } -#endif if (dirty & DIRTY_SHADERBLEND) { if (u_blendFixA != -1) { - SetColorUniform3(u_blendFixA, gstate.getFixA()); + SetColorUniform3(render_, &u_blendFixA, gstate.getFixA()); } if (u_blendFixB != -1) { - SetColorUniform3(u_blendFixB, gstate.getFixB()); + SetColorUniform3(render_, &u_blendFixB, gstate.getFixB()); } const float fbotexSize[2] = { @@ -643,25 +486,25 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { 1.0f / (float)gstate_c.curRTRenderHeight, }; if (u_fbotexSize != -1) { - glUniform2fv(u_fbotexSize, 1, fbotexSize); + render_->SetUniformF(&u_fbotexSize, 2, fbotexSize); } } // Lighting if (dirty & DIRTY_AMBIENT) { - SetColorUniform3Alpha(u_ambient, gstate.ambientcolor, gstate.getAmbientA()); + SetColorUniform3Alpha(render_, &u_ambient, gstate.ambientcolor, gstate.getAmbientA()); } if (dirty & DIRTY_MATAMBIENTALPHA) { - SetColorUniform3Alpha(u_matambientalpha, gstate.materialambient, gstate.getMaterialAmbientA()); + SetColorUniform3Alpha(render_, &u_matambientalpha, gstate.materialambient, gstate.getMaterialAmbientA()); } if (dirty & DIRTY_MATDIFFUSE) { - SetColorUniform3(u_matdiffuse, gstate.materialdiffuse); + SetColorUniform3(render_, &u_matdiffuse, gstate.materialdiffuse); } if (dirty & DIRTY_MATEMISSIVE) { - SetColorUniform3(u_matemissive, gstate.materialemissive); + SetColorUniform3(render_, &u_matemissive, gstate.materialemissive); } if (dirty & DIRTY_MATSPECULAR) { - SetColorUniform3ExtraFloat(u_matspecular, gstate.materialspecular, getFloat24(gstate.materialspecularcoef)); + SetColorUniform3ExtraFloat(render_, &u_matspecular, gstate.materialspecular, getFloat24(gstate.materialspecularcoef)); } for (int i = 0; i < 4; i++) { @@ -677,34 +520,35 @@ void LinkedShader::UpdateUniforms(u32 vertType, const VShaderID &vsid) { else len = 1.0f / len; float vec[3] = { x * len, y * len, z * len }; - glUniform3fv(u_lightpos[i], 1, vec); + render_->SetUniformF(&u_lightpos[i], 3, vec); } else { - SetFloat24Uniform3(u_lightpos[i], &gstate.lpos[i * 3]); + SetFloat24Uniform3(render_, &u_lightpos[i], &gstate.lpos[i * 3]); } - if (u_lightdir[i] != -1) SetFloat24Uniform3(u_lightdir[i], &gstate.ldir[i * 3]); - if (u_lightatt[i] != -1) SetFloat24Uniform3(u_lightatt[i], &gstate.latt[i * 3]); - if (u_lightangle[i] != -1) glUniform1f(u_lightangle[i], getFloat24(gstate.lcutoff[i])); - if (u_lightspotCoef[i] != -1) glUniform1f(u_lightspotCoef[i], getFloat24(gstate.lconv[i])); - if (u_lightambient[i] != -1) SetColorUniform3(u_lightambient[i], gstate.lcolor[i * 3]); - if (u_lightdiffuse[i] != -1) SetColorUniform3(u_lightdiffuse[i], gstate.lcolor[i * 3 + 1]); - if (u_lightspecular[i] != -1) SetColorUniform3(u_lightspecular[i], gstate.lcolor[i * 3 + 2]); + if (u_lightdir[i] != -1) SetFloat24Uniform3(render_, &u_lightdir[i], &gstate.ldir[i * 3]); + if (u_lightatt[i] != -1) SetFloat24Uniform3(render_, &u_lightatt[i], &gstate.latt[i * 3]); + if (u_lightangle_spotCoef[i] != -1) { + float lightangle_spotCoef[2] = { getFloat24(gstate.lcutoff[i]), getFloat24(gstate.lconv[i]) }; + SetFloatUniform2(render_, &u_lightangle_spotCoef[i], lightangle_spotCoef); + } + if (u_lightambient[i] != -1) SetColorUniform3(render_, &u_lightambient[i], gstate.lcolor[i * 3]); + if (u_lightdiffuse[i] != -1) SetColorUniform3(render_, &u_lightdiffuse[i], gstate.lcolor[i * 3 + 1]); + if (u_lightspecular[i] != -1) SetColorUniform3(render_, &u_lightspecular[i], gstate.lcolor[i * 3 + 2]); } } if (dirty & DIRTY_BEZIERSPLINE) { - glUniform1i(u_spline_count_u, gstate_c.spline_count_u); + render_->SetUniformI1(&u_spline_count_u, gstate_c.spline_count_u); if (u_spline_count_v != -1) - glUniform1i(u_spline_count_v, gstate_c.spline_count_v); + render_->SetUniformI1(&u_spline_count_v, gstate_c.spline_count_v); if (u_spline_type_u != -1) - glUniform1i(u_spline_type_u, gstate_c.spline_type_u); + render_->SetUniformI1(&u_spline_type_u, gstate_c.spline_type_u); if (u_spline_type_v != -1) - glUniform1i(u_spline_type_v, gstate_c.spline_type_v); + render_->SetUniformI1(&u_spline_type_v, gstate_c.spline_type_v); } - CHECK_GL_ERROR_IF_DEBUG(); } -ShaderManagerGLES::ShaderManagerGLES() - : lastShader_(nullptr), shaderSwitchDirtyUniforms_(0), diskCacheDirty_(false), fsCache_(16), vsCache_(16) { +ShaderManagerGLES::ShaderManagerGLES(GLRenderManager *render) + : render_(render), lastShader_(nullptr), shaderSwitchDirtyUniforms_(0), diskCacheDirty_(false), fsCache_(16), vsCache_(16) { codeBuffer_ = new char[16384]; lastFSID_.set_invalid(); lastVSID_.set_invalid(); @@ -746,8 +590,6 @@ void ShaderManagerGLES::DirtyShader() { } void ShaderManagerGLES::DirtyLastShader() { // disables vertex arrays - if (lastShader_) - lastShader_->stop(); lastShader_ = nullptr; lastVShaderSame_ = false; } @@ -757,7 +599,8 @@ Shader *ShaderManagerGLES::CompileFragmentShader(FShaderID FSID) { if (!GenerateFragmentShader(FSID, codeBuffer_, &uniformMask)) { return nullptr; } - return new Shader(FSID, codeBuffer_, GL_FRAGMENT_SHADER, false, 0, uniformMask); + std::string desc = FragmentShaderDesc(FSID); + return new Shader(render_, codeBuffer_, desc, GL_FRAGMENT_SHADER, false, 0, uniformMask); } Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) { @@ -765,7 +608,8 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) { uint32_t attrMask; uint64_t uniformMask; GenerateVertexShader(VSID, codeBuffer_, &attrMask, &uniformMask); - return new Shader(VSID, codeBuffer_, GL_VERTEX_SHADER, useHWTransform, attrMask, uniformMask); + std::string desc = VertexShaderDesc(VSID); + return new Shader(render_, codeBuffer_, desc, GL_VERTEX_SHADER, useHWTransform, attrMask, uniformMask); } Shader *ShaderManagerGLES::ApplyVertexShader(int prim, u32 vertType, VShaderID *VSID) { @@ -815,7 +659,7 @@ Shader *ShaderManagerGLES::ApplyVertexShader(int prim, u32 vertType, VShaderID * uint32_t attrMask; uint64_t uniformMask; GenerateVertexShader(vsidTemp, codeBuffer_, &attrMask, &uniformMask); - vs = new Shader(vsidTemp, codeBuffer_, GL_VERTEX_SHADER, false, attrMask, uniformMask); + vs = new Shader(render_, codeBuffer_, VertexShaderDesc(vsidTemp), GL_VERTEX_SHADER, false, attrMask, uniformMask); } vsCache_.Insert(*VSID, vs); @@ -869,12 +713,12 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs, _dbg_assert_(G3D, FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE)); // Check if we can link these. - ls = new LinkedShader(VSID, vs, FSID, fs, vs->UseHWTransform()); - ls->use(VSID, lastShader_); + ls = new LinkedShader(render_, VSID, vs, FSID, fs, vs->UseHWTransform()); + ls->use(VSID); const LinkedShaderCacheEntry entry(vs, fs, ls); linkedShaderCache_.push_back(entry); } else { - ls->use(VSID, lastShader_); + ls->use(VSID); } ls->UpdateUniforms(vertType, VSID); @@ -953,7 +797,7 @@ std::string ShaderManagerGLES::DebugGetShaderString(std::string id, DebugShaderT // as sometimes these features might have an effect on the ID bits. #define CACHE_HEADER_MAGIC 0x83277592 -#define CACHE_VERSION 5 +#define CACHE_VERSION 7 struct CacheHeader { uint32_t magic; uint32_t version; @@ -1033,6 +877,8 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { return true; } + PSP_SetLoading("Compiling shaders..."); + double start = real_time_now(); // Let's try to keep it under sliceTime if possible. double end = start + sliceTime; @@ -1092,7 +938,7 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { Shader *vs = vsCache_.Get(vsid); Shader *fs = fsCache_.Get(fsid); if (vs && fs) { - LinkedShader *ls = new LinkedShader(vsid, vs, fsid, fs, vs->UseHWTransform(), true); + LinkedShader *ls = new LinkedShader(render_, vsid, vs, fsid, fs, vs->UseHWTransform(), true); LinkedShaderCacheEntry entry(vs, fs, ls); linkedShaderCache_.push_back(entry); } diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index 38e8a097ec..ae0a42fead 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -21,6 +21,7 @@ #include "base/basictypes.h" #include "Common/Hashmaps.h" +#include "thin3d/GLRenderManager.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" #include "GPU/GLES/VertexShaderGeneratorGLES.h" @@ -33,28 +34,26 @@ enum { ATTR_POSITION = 0, ATTR_TEXCOORD = 1, ATTR_NORMAL = 2, - ATTR_W1 = 3, - ATTR_W2 = 4, - ATTR_COLOR0 = 5, - ATTR_COLOR1 = 6, + ATTR_COLOR0 = 3, + ATTR_COLOR1 = 4, ATTR_COUNT, }; class LinkedShader { public: - LinkedShader(VShaderID VSID, Shader *vs, FShaderID FSID, Shader *fs, bool useHWTransform, bool preloading = false); + LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, FShaderID FSID, Shader *fs, bool useHWTransform, bool preloading = false); ~LinkedShader(); - void use(const VShaderID &VSID, LinkedShader *previous); - void stop(); - void UpdateUniforms(u32 vertType, const VShaderID &VSID); + void use(const ShaderID &VSID); + void UpdateUniforms(u32 vertType, const ShaderID &VSID); + GLRenderManager *render_; Shader *vs_; // Set to false if the VS failed, happens on Mali-400 a lot for complex shaders. bool useHWTransform_; - uint32_t program = 0; + GLRProgram *program; uint64_t availableUniforms; uint64_t dirtyUniforms = 0; @@ -71,13 +70,6 @@ public: int u_world; int u_depthRange; // x,y = viewport xscale/xcenter. z,w=clipping minz/maxz (?) -#ifdef USE_BONE_ARRAY - int u_bone; // array, size is numBones -#else - int u_bone[8]; -#endif - int numBones; - // Shader blending. int u_fbotex; int u_blendFixA; @@ -108,8 +100,7 @@ public: int u_lightpos[4]; int u_lightdir[4]; int u_lightatt[4]; // attenuation - int u_lightangle[4]; // spotlight cone angle (cosine) - int u_lightspotCoef[4]; // spotlight dropoff + int u_lightangle_spotCoef[4]; // spotlight cone angle (cosine) (x), spotlight dropoff (y) int u_lightdiffuse[4]; // each light consist of vec4[3] int u_lightspecular[4]; // attenuation int u_lightambient[4]; // attenuation @@ -127,12 +118,12 @@ public: class Shader { public: - Shader(const ShaderID &id, const char *code, uint32_t glShaderType, bool useHWTransform, uint32_t attrMask, uint64_t uniformMask); + Shader(GLRenderManager *render, const char *code, const std::string &desc, uint32_t glShaderType, bool useHWTransform, uint32_t attrMask, uint64_t uniformMask); ~Shader(); - uint32_t shader; + GLRShader *shader; bool Failed() const { return failed_; } - bool UseHWTransform() const { return useHWTransform_; } // only relevant for vtx shaders + bool UseHWTransform() const { return useHWTransform_; } // only relevant for vtx shaders std::string GetShaderString(DebugShaderStringType type, ShaderID id) const; @@ -140,6 +131,7 @@ public: uint64_t GetUniformMask() const { return uniformMask_; } private: + GLRenderManager *render_; std::string source_; bool failed_; bool useHWTransform_; @@ -150,7 +142,7 @@ private: class ShaderManagerGLES : public ShaderManagerCommon { public: - ShaderManagerGLES(); + ShaderManagerGLES(GLRenderManager *render); ~ShaderManagerGLES(); void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected @@ -189,6 +181,7 @@ private: }; typedef std::vector LinkedShaderCache; + GLRenderManager *render_; LinkedShaderCache linkedShaderCache_; bool lastVShaderSame_; diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 195c21d1b9..5a5fc1f071 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -23,6 +23,7 @@ #include "StateMappingGLES.h" #include "profiler/profiler.h" #include "gfx/gl_debug_log.h" +#include "thin3d/GLRenderManager.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" @@ -31,7 +32,6 @@ #include "Core/Config.h" #include "Core/Reporting.h" #include "GPU/GLES/GPU_GLES.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" @@ -123,18 +123,14 @@ static const GLushort logicOps[] = { inline void DrawEngineGLES::ResetShaderBlending() { if (fboTexBound_) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); + GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + renderManager->BindTexture(1, nullptr); fboTexBound_ = false; } } void DrawEngineGLES::ApplyDrawState(int prim) { - if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { - textureCache_->SetTexture(); - gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - } + GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); if (!gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE)) { // Nothing to do, let's early-out @@ -163,17 +159,10 @@ void DrawEngineGLES::ApplyDrawState(int prim) { gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { - glstate.blend.disable(); // Color Test bool colorMask = gstate.isClearModeColorMask(); bool alphaMask = gstate.isClearModeAlphaMask(); - glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask); -#ifndef USING_GLES2 - if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { - // Logic Ops - glstate.colorLogicOp.disable(); - } -#endif + renderManager->SetNoBlendAndMask((colorMask ? 7 : 0) | (alphaMask ? 8 : 0)); } else { // Do the large chunks of state conversion. We might be able to hide these two behind a dirty-flag each, // to avoid recomputing heavy stuff unnecessarily every draw call. @@ -184,6 +173,21 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (ApplyShaderBlending()) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); + + // We copy the framebuffer here, as doing so will wipe any blend state if we do it later. + if (fboTexNeedBind_) { + // Note that this is positions, not UVs, that we need the copy from. + // TODO: If the device doesn't support blit, this will corrupt the currently applied texture. + framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); + // If we are rendering at a higher resolution, linear is probably best for the dest color. + renderManager->SetTextureSampler(1, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, 0.0f); + fboTexBound_ = true; + fboTexNeedBind_ = false; + + framebufferManager_->RebindFramebuffer(); + // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. + gstate_c.Dirty(DIRTY_BLEND_STATE); + } } else { // Until next time, force it off. ResetShaderBlending(); @@ -194,11 +198,6 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } if (blendState.enabled) { - glstate.blend.enable(); - glstate.blendEquationSeparate.set(glBlendEqLookup[(size_t)blendState.eqColor], glBlendEqLookup[(size_t)blendState.eqAlpha]); - glstate.blendFuncSeparate.set( - glBlendFactorLookup[(size_t)blendState.srcColor], glBlendFactorLookup[(size_t)blendState.dstColor], - glBlendFactorLookup[(size_t)blendState.srcAlpha], glBlendFactorLookup[(size_t)blendState.dstAlpha]); if (blendState.dirtyShaderBlend) { gstate_c.Dirty(DIRTY_SHADERBLEND); } @@ -210,10 +209,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) { (float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f), (float)((color & 0xFF000000) >> 24) * (1.0f / 255.0f), }; - glstate.blendColor.set(col); + renderManager->SetBlendFactor(col); } - } else { - glstate.blend.disable(); } // PSP color/alpha mask is per bit but we can only support per byte. @@ -235,19 +232,20 @@ void DrawEngineGLES::ApplyDrawState(int prim) { WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits); } #endif - - glstate.colorMask.set(rmask, gmask, bmask, amask); + int mask = (int)rmask | ((int)gmask << 1) | ((int)bmask << 2) | ((int)amask << 3); + if (blendState.enabled) { + renderManager->SetBlendAndMask(mask, blendState.enabled, + glBlendFactorLookup[(size_t)blendState.srcColor], glBlendFactorLookup[(size_t)blendState.dstColor], + glBlendFactorLookup[(size_t)blendState.srcAlpha], glBlendFactorLookup[(size_t)blendState.dstAlpha], + glBlendEqLookup[(size_t)blendState.eqColor], glBlendEqLookup[(size_t)blendState.eqAlpha]); + } else { + renderManager->SetNoBlendAndMask(mask); + } #ifndef USING_GLES2 if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { - // TODO: Make this dynamic - // Logic Ops - if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) { - glstate.colorLogicOp.enable(); - glstate.logicOp.set(logicOps[gstate.getLogicOp()]); - } else { - glstate.colorLogicOp.disable(); - } + renderManager->SetLogicOp(gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY, + logicOps[gstate.getLogicOp()]); } #endif } @@ -257,26 +255,18 @@ void DrawEngineGLES::ApplyDrawState(int prim) { gstate_c.Clean(DIRTY_RASTER_STATE); // Dither - if (gstate.isDitherEnabled()) { - glstate.dither.enable(); - glstate.dither.set(true); - } else { - glstate.dither.disable(); - } + bool dither = gstate.isDitherEnabled(); + bool cullEnable; + GLenum cullMode = cullingMode[gstate.getCullMode() ^ !useBufferedRendering]; if (gstate.isModeClear()) { // Culling - glstate.cullFace.disable(); + cullEnable = false; } else { // Set cull - bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); - if (cullEnabled) { - glstate.cullFace.enable(); - glstate.cullFaceMode.set(cullingMode[gstate.getCullMode() ^ !useBufferedRendering]); - } else { - glstate.cullFace.disable(); - } + cullEnable = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); } + renderManager->SetRaster(cullEnable, GL_CCW, cullMode, dither); } if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) { @@ -284,77 +274,43 @@ void DrawEngineGLES::ApplyDrawState(int prim) { bool enableStencilTest = !g_Config.bDisableStencilTest; if (gstate.isModeClear()) { // Depth Test - glstate.depthTest.enable(); - glstate.depthFunc.set(GL_ALWAYS); - glstate.depthWrite.set(gstate.isClearModeDepthMask() ? GL_TRUE : GL_FALSE); if (gstate.isClearModeDepthMask()) { framebufferManager_->SetDepthUpdated(); } - - // Stencil Test - if (gstate.isClearModeAlphaMask() && enableStencilTest) { - glstate.stencilTest.enable(); - glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE); - // TODO: In clear mode, the stencil value is set to the alpha value of the vertex. - // A normal clear will be 2 points, the second point has the color. - // We should set "ref" to that value instead of 0. - // In case of clear rectangles, we set it again once we know what the color is. - glstate.stencilFunc.set(GL_ALWAYS, 255, 0xFF); - glstate.stencilMask.set(0xFF); - } else { - glstate.stencilTest.disable(); - } + renderManager->SetStencilFunc(gstate.isClearModeAlphaMask() && enableStencilTest, GL_ALWAYS, 0xFF, 0xFF); + renderManager->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { // Depth Test - if (gstate.isDepthTestEnabled()) { - glstate.depthTest.enable(); - glstate.depthFunc.set(compareOps[gstate.getDepthTestFunction()]); - glstate.depthWrite.set(gstate.isDepthWriteEnabled() ? GL_TRUE : GL_FALSE); - if (gstate.isDepthWriteEnabled()) { - framebufferManager_->SetDepthUpdated(); - } - } else { - glstate.depthTest.disable(); + renderManager->SetDepth(gstate.isDepthTestEnabled(), gstate.isDepthWriteEnabled(), compareOps[gstate.getDepthTestFunction()]); + if (gstate.isDepthTestEnabled() && gstate.isDepthWriteEnabled()) { + framebufferManager_->SetDepthUpdated(); } GenericStencilFuncState stencilState; ConvertStencilFuncState(stencilState); - // Stencil Test if (stencilState.enabled) { - glstate.stencilTest.enable(); - glstate.stencilFunc.set(compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask); - glstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]); - glstate.stencilMask.set(stencilState.writeMask); + renderManager->SetStencilFunc(stencilState.enabled, compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask); + renderManager->SetStencilOp(stencilState.writeMask, stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]); } else { - glstate.stencilTest.disable(); + renderManager->SetStencilDisabled(); } } } if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) { gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE); - ViewportAndScissor vpAndScissor; ConvertViewportAndScissor(useBufferedRendering, framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(), framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), vpAndScissor); - if (vpAndScissor.scissorEnable) { - glstate.scissorTest.enable(); - if (!useBufferedRendering) { - vpAndScissor.scissorY = PSP_CoreParameter().pixelHeight - vpAndScissor.scissorH - vpAndScissor.scissorY; - } - glstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH); - } else { - glstate.scissorTest.disable(); - } - - if (!useBufferedRendering) { - vpAndScissor.viewportY = PSP_CoreParameter().pixelHeight - vpAndScissor.viewportH - vpAndScissor.viewportY; - } - glstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH); - glstate.depthRange.set(vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax); + renderManager->SetScissor(GLRect2D{ vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH }); + renderManager->SetViewport({ + vpAndScissor.viewportX, vpAndScissor.viewportY, + vpAndScissor.viewportW, vpAndScissor.viewportH, + vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax }); if (vpAndScissor.dirtyProj) { gstate_c.Dirty(DIRTY_PROJMATRIX); @@ -363,40 +319,19 @@ void DrawEngineGLES::ApplyDrawState(int prim) { gstate_c.Dirty(DIRTY_DEPTHRANGE); } } - CHECK_GL_ERROR_IF_DEBUG(); } -void DrawEngineGLES::ApplyDrawStateLate() { +void DrawEngineGLES::ApplyDrawStateLate(bool setStencil, int stencilValue) { + if (setStencil) { + render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, stencilValue, 255); + } + // At this point, we know if the vertices are full alpha or not. // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? if (!gstate.isModeClear()) { - if (fboTexNeedBind_) { - CHECK_GL_ERROR_IF_DEBUG(); - // Note that this is positions, not UVs, that we need the copy from. - framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); - framebufferManager_->RebindFramebuffer(); - CHECK_GL_ERROR_IF_DEBUG(); - - glActiveTexture(GL_TEXTURE1); - // If we are rendering at a higher resolution, linear is probably best for the dest color. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glActiveTexture(GL_TEXTURE0); - fboTexBound_ = true; - fboTexNeedBind_ = false; - CHECK_GL_ERROR_IF_DEBUG(); - } - CHECK_GL_ERROR_IF_DEBUG(); - - // Apply the texture after the FBO tex, since it might unbind the texture. - // TODO: Could use a separate texture unit to be safer? - textureCache_->ApplyTexture(); - CHECK_GL_ERROR_IF_DEBUG(); - // Apply last, once we know the alpha params of the texture. if (gstate.isAlphaTestEnabled() || gstate.isColorTestEnabled()) { - fragmentTestCache_->BindTestTexture(GL_TEXTURE2); + fragmentTestCache_->BindTestTexture(2); } - CHECK_GL_ERROR_IF_DEBUG(); } } diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 01dfcf254e..4b59b60b96 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -17,7 +17,6 @@ #include "gfx_es2/glsl_program.h" #include "Core/Reporting.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/Common/StencilCommon.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/ShaderManagerGLES.h" @@ -111,12 +110,10 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe } // Let's not bother with the shader if it's just zero. - glstate.scissorTest.disable(); - glstate.colorMask.set(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - glClearColor(0, 0, 0, 0); - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - + if (dstBuffer->fbo) { + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + } + render_->Clear(0, 0, 0, GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT, 0x8, 0, 0, 0, 0); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); return true; } @@ -126,27 +123,25 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe static std::string vs_code, fs_code; vs_code = ApplyGLSLPrelude(stencil_vs, GL_VERTEX_SHADER); fs_code = ApplyGLSLPrelude(stencil_fs, GL_FRAGMENT_SHADER); - stencilUploadProgram_ = glsl_create_source(vs_code.c_str(), fs_code.c_str(), &errorString); + std::vector shaders; + shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vs_code, "stencil")); + shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fs_code, "stencil")); + std::vector queries; + queries.push_back({ &u_stencilUploadTex, "tex" }); + queries.push_back({ &u_stencilValue, "u_stencilValue" }); + std::vector inits; + inits.push_back({ &u_stencilUploadTex, 0, 0 }); + stencilUploadProgram_ = render_->CreateProgram(shaders, {}, queries, inits, false); + for (auto iter : shaders) { + render_->DeleteShader(iter); + } if (!stencilUploadProgram_) { ERROR_LOG_REPORT(G3D, "Failed to compile stencilUploadProgram! This shouldn't happen.\n%s", errorString.c_str()); - } else { - glsl_bind(stencilUploadProgram_); } - - GLint u_tex = glsl_uniform_loc(stencilUploadProgram_, "tex"); - glUniform1i(u_tex, 0); - } else { - glsl_bind(stencilUploadProgram_); } shaderManagerGL_->DirtyLastShader(); - DisableState(); - glstate.colorMask.set(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - glstate.stencilTest.enable(); - glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT); // Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x. @@ -164,43 +159,44 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe } else if (dstBuffer->fbo) { draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); } - glViewport(0, 0, w, h); - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + render_->SetViewport({ 0, 0, (float)w, (float)h, 0.0f, 1.0f }); float u1 = 1.0f; float v1 = 1.0f; MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1); textureCacheGL_->ForgetLastTexture(); - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT); + // We must bind the program after starting the render pass, and set the color mask after clearing. + render_->SetDepth(false, false, GL_ALWAYS); + render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 0x8, 0, 0, 0, 0); + render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, 0xFF, 0xFF); + render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE); + render_->BindProgram(stencilUploadProgram_); + render_->SetNoBlendAndMask(0x8); - glstate.stencilFunc.set(GL_ALWAYS, 0xFF, 0xFF); - - GLint u_stencilValue = glsl_uniform_loc(stencilUploadProgram_, "u_stencilValue"); for (int i = 1; i < values; i += i) { if (!(usedBits & i)) { // It's already zero, let's skip it. continue; } if (dstBuffer->format == GE_FORMAT_4444) { - glstate.stencilMask.set((i << 4) | i); - glUniform1f(u_stencilValue, i * (16.0f / 255.0f)); + render_->SetStencilOp((i << 4) | i, GL_REPLACE, GL_REPLACE, GL_REPLACE); + render_->SetUniformF1(&u_stencilValue, i * (16.0f / 255.0f)); } else if (dstBuffer->format == GE_FORMAT_5551) { - glstate.stencilMask.set(0xFF); - glUniform1f(u_stencilValue, i * (128.0f / 255.0f)); + render_->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + render_->SetUniformF1(&u_stencilValue, i * (128.0f / 255.0f)); } else { - glstate.stencilMask.set(i); - glUniform1f(u_stencilValue, i * (1.0f / 255.0f)); + render_->SetStencilOp(i, GL_REPLACE, GL_REPLACE, GL_REPLACE); + render_->SetUniformF1(&u_stencilValue, i * (1.0f / 255.0f)); } - DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST); + DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST | DRAWTEX_KEEP_STENCIL_ALPHA); } - glstate.stencilMask.set(0xFF); if (useBlit) { draw_->BlitFramebuffer(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, Draw::FB_STENCIL_BIT, Draw::FB_BLIT_NEAREST); } + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); RebindFramebuffer(); return true; } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 8aff3fa645..c265c12d4d 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -23,6 +23,7 @@ #include "i18n/i18n.h" #include "math/math_util.h" #include "profiler/profiler.h" +#include "thin3d/GLRenderManager.h" #include "Common/ColorConv.h" #include "Core/Config.h" @@ -31,7 +32,6 @@ #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" -#include "ext/native/gfx/GLStateCache.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/FragmentShaderGeneratorGLES.h" @@ -44,24 +44,23 @@ #include #endif -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif - -#define TEXCACHE_NAME_CACHE_SIZE 16 - TextureCacheGLES::TextureCacheGLES(Draw::DrawContext *draw) : TextureCacheCommon(draw) { timesInvalidatedAllThisFrame_ = 0; - lastBoundTexture = INVALID_TEX; + lastBoundTexture = nullptr; + render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel); SetupTextureDecoder(); nextTexture_ = nullptr; + std::vector entries; + entries.push_back({ 0, 3, GL_FLOAT, GL_FALSE, 20, 0 }); + entries.push_back({ 1, 2, GL_FLOAT, GL_FALSE, 20, 12 }); + shadeInputLayout_ = render_->CreateInputLayout(entries); } TextureCacheGLES::~TextureCacheGLES() { + render_->DeleteInputLayout(shadeInputLayout_); Clear(true); } @@ -71,23 +70,17 @@ void TextureCacheGLES::SetFramebufferManager(FramebufferManagerGLES *fbManager) } void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %i", entry->textureName); + DEBUG_LOG(G3D, "Deleting texture %08x", entry->addr); if (delete_them) { - if (entry->textureName != 0) { - glDeleteTextures(1, &entry->textureName); + if (entry->textureName) { + render_->DeleteTexture(entry->textureName); } } - entry->textureName = 0; + entry->textureName = nullptr; } void TextureCacheGLES::Clear(bool delete_them) { TextureCacheCommon::Clear(delete_them); - if (delete_them) { - if (!nameCache_.empty()) { - glDeleteTextures((GLsizei)nameCache_.size(), &nameCache_[0]); - nameCache_.clear(); - } - } } GLenum getClutDestFormat(GEPaletteFormat format) { @@ -122,7 +115,6 @@ static const GLuint MagFiltGL[2] = { // This should not have to be done per texture! OpenGL is silly yo void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { - CHECK_GL_ERROR_IF_DEBUG(); int minFilt; int magFilt; bool sClamp; @@ -133,59 +125,37 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode); if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { + float minLod = 0.0f; + float maxLod = 0.0f; if (maxLevel != 0) { // TODO: What about a swap of autoMip mode? - if (force || entry.lodBias != lodBias) { + if (true) { if (mode == GE_TEXLEVEL_MODE_AUTO) { -#ifndef USING_GLES2 - // Sigh, LOD_BIAS is not even in ES 3.0.. but we could do it in the shader via texture()... - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias); -#endif - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel); + minLod = 0.0f; + maxLod = (float)maxLevel; } else if (mode == GE_TEXLEVEL_MODE_CONST) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, std::max(0.0f, std::min((float)maxLevel, lodBias))); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, std::max(0.0f, std::min((float)maxLevel, lodBias))); + minLod = std::max(0.0f, std::min((float)maxLevel, lodBias)); + maxLod = std::max(0.0f, std::min((float)maxLevel, lodBias)); } else { // mode == GE_TEXLEVEL_MODE_SLOPE) { // It's incorrect to use the slope as a bias. Instead it should be passed // into the shader directly as an explicit lod level, with the bias on top. For now, we just kill the // lodBias in this mode, working around #9772. #ifndef USING_GLES2 - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f); + lodBias = 0.0f; #endif - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel); + minLod = 0.0f; + maxLod = (float)maxLevel; } - entry.lodBias = lodBias; } } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0.0f); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0.0f); + minLod = 0.0f; + maxLod = 0.0f; } + render_->SetTextureLod(0, minLod, maxLod, lodBias); } - if (force || entry.minFilt != minFilt) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFiltGL[minFilt]); - entry.minFilt = minFilt; - } - if (force || entry.magFilt != magFilt) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFiltGL[magFilt]); - entry.magFilt = magFilt; - } - - if (entry.framebuffer) { - WARN_LOG_REPORT_ONCE(wrongFramebufAttach, G3D, "Framebuffer still attached in UpdateSamplingParams()?"); - } - - if (force || entry.sClamp != sClamp) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); - entry.sClamp = sClamp; - } - if (force || entry.tClamp != tClamp) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); - entry.tClamp = tClamp; - } - CHECK_GL_ERROR_IF_DEBUG(); + float aniso = 0.0f; + render_->SetTextureSampler(0, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso); } void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { @@ -199,8 +169,8 @@ void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferH minFilt &= 1; // framebuffers can't mipmap. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFiltGL[minFilt]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFiltGL[magFilt]); + float aniso = 0.0f; + render_->SetTextureSampler(0, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso); // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. @@ -209,9 +179,6 @@ void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferH if (w != bufferWidth || h != bufferHeight) { return; } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); } static void ConvertColors(void *dstBuf, const void *srcBuf, GLuint dstFmt, int numPixels) { @@ -240,6 +207,19 @@ void TextureCacheGLES::StartFrame() { InvalidateLastTexture(); timesInvalidatedAllThisFrame_ = 0; + GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + if (!lowMemoryMode_ && renderManager->SawOutOfMemory()) { + lowMemoryMode_ = true; + decimationCounter_ = 0; + + I18NCategory *err = GetI18NCategory("Error"); + if (standardScaleFactor_ > 1) { + host->NotifyUserMessage(err->T("Warning: Video memory FULL, reducing upscaling and switching to slow caching mode"), 2.0f); + } else { + host->NotifyUserMessage(err->T("Warning: Video memory FULL, switching to slow caching mode"), 2.0f); + } + } + if (texelsScaledThisFrame_) { // INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); } @@ -336,39 +316,26 @@ bool SetDebugTexture() { #endif void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { - CHECK_GL_ERROR_IF_DEBUG(); if (entry->textureName != lastBoundTexture) { - glBindTexture(GL_TEXTURE_2D, entry->textureName); + render_->BindTexture(0, entry->textureName); lastBoundTexture = entry->textureName; } - CHECK_GL_ERROR_IF_DEBUG(); UpdateSamplingParams(*entry, false); - CHECK_GL_ERROR_IF_DEBUG(); } void TextureCacheGLES::Unbind() { - glBindTexture(GL_TEXTURE_2D, 0); + render_->BindTexture(0, nullptr); InvalidateLastTexture(); } class TextureShaderApplier { public: struct Pos { - Pos(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { - } - Pos() { - } - float x; float y; float z; }; struct UV { - UV(float u_, float v_) : u(u_), v(v_) { - } - UV() { - } - float u; float v; }; @@ -411,66 +378,44 @@ public: const float top = v1 * invHalfHeight - 1.0f; const float bottom = v2 * invHalfHeight - 1.0f; // Points are: BL, BR, TR, TL. - pos_[0] = Pos(left, bottom, -1.0f); - pos_[1] = Pos(right, bottom, -1.0f); - pos_[2] = Pos(right, top, -1.0f); - pos_[3] = Pos(left, top, -1.0f); + pos_[0] = Pos{ left, bottom, -1.0f }; + pos_[1] = Pos{ right, bottom, -1.0f }; + pos_[2] = Pos{ right, top, -1.0f }; + pos_[3] = Pos{ left, top, -1.0f }; // And also the UVs, same order. const float uvleft = u1 * invWidth; const float uvright = u2 * invWidth; const float uvtop = v1 * invHeight; const float uvbottom = v2 * invHeight; - uv_[0] = UV(uvleft, uvbottom); - uv_[1] = UV(uvright, uvbottom); - uv_[2] = UV(uvright, uvtop); - uv_[3] = UV(uvleft, uvtop); + uv_[0] = UV{ uvleft, uvbottom }; + uv_[1] = UV{ uvright, uvbottom }; + uv_[2] = UV{ uvright, uvtop }; + uv_[3] = UV{ uvleft, uvtop }; } } - void Use(DrawEngineGLES *transformDraw) { - glUseProgram(shader_->program); - - // Restore will rebind all of the state below. - if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - static const GLubyte indices[4] = { 0, 1, 3, 2 }; - transformDraw->BindBuffer(pos_, sizeof(pos_), uv_, sizeof(uv_)); - transformDraw->BindElementBuffer(indices, sizeof(indices)); - } else { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + void Use(GLRenderManager *render, DrawEngineGLES *transformDraw, GLRInputLayout *inputLayout) { + render->BindProgram(shader_->program); + struct SimpleVertex { + float pos[3]; + float uv[2]; + }; + uint32_t bindOffset; + GLRBuffer *bindBuffer; + SimpleVertex *verts = (SimpleVertex *)transformDraw->GetPushVertexBuffer()->Push(sizeof(SimpleVertex) * 4, &bindOffset, &bindBuffer); + int order[4] = { 0 ,1, 3, 2 }; + for (int i = 0; i < 4; i++) { + memcpy(verts[i].pos, &pos_[order[i]], sizeof(Pos)); + memcpy(verts[i].uv, &uv_[order[i]], sizeof(UV)); } - glEnableVertexAttribArray(shader_->a_position); - glEnableVertexAttribArray(shader_->a_texcoord0); + render->BindVertexBuffer(inputLayout, bindBuffer, bindOffset); } - void Shade() { + void Shade(GLRenderManager *render) { static const GLubyte indices[4] = { 0, 1, 3, 2 }; - - glstate.blend.force(false); - glstate.colorMask.force(true, true, true, true); - glstate.scissorTest.force(false); - glstate.cullFace.force(false); - glstate.depthTest.force(false); - glstate.stencilTest.force(false); -#if !defined(USING_GLES2) - glstate.colorLogicOp.force(false); -#endif - glViewport(0, 0, renderW_, renderH_); - - if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { - glVertexAttribPointer(shader_->a_position, 3, GL_FLOAT, GL_FALSE, 12, 0); - glVertexAttribPointer(shader_->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, (void *)sizeof(pos_)); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0); - } else { - glVertexAttribPointer(shader_->a_position, 3, GL_FLOAT, GL_FALSE, 12, pos_); - glVertexAttribPointer(shader_->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, uv_); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices); - } - glDisableVertexAttribArray(shader_->a_position); - glDisableVertexAttribArray(shader_->a_texcoord0); - - glstate.Restore(); + render->SetViewport(GLRViewport{ 0, 0, (float)renderW_, (float)renderH_, 0.0f, 1.0f }); + render->Draw(GL_TRIANGLE_STRIP, 0, 4); } protected: @@ -491,31 +436,29 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram } if (depal) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); - GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); + GLRTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); Draw::Framebuffer *depalFBO = framebufferManagerGL_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); shaderManager_->DirtyLastShader(); + render_->SetScissor(GLRect2D{ 0, 0, (int)framebuffer->renderWidth, (int)framebuffer->renderHeight }); + render_->SetViewport(GLRViewport{ 0.0f, 0.0f, (float)framebuffer->renderWidth, (float)framebuffer->renderHeight, 0.0f, 1.0f }); TextureShaderApplier shaderApply(depal, framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight); shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset); - shaderApply.Use(drawEngine_); - - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, clutTexture); - glActiveTexture(GL_TEXTURE0); + shaderApply.Use(render_, drawEngine_, shadeInputLayout_); framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + render_->BindTexture(3, clutTexture); + render_->SetTextureSampler(3, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f); - shaderApply.Shade(); + shaderApply.Shade(render_); draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor; - TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); + TexCacheEntry::TexStatus alphaStatus = CheckAlpha((const uint8_t *)clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; @@ -528,9 +471,10 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram framebufferManagerGL_->RebindFramebuffer(); SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); - CHECK_GL_ERROR_IF_DEBUG(); - InvalidateLastTexture(); + + // Since we started/ended render passes, might need these. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } ReplacedTextureFormat FromGLESFormat(GLenum fmt) { @@ -555,6 +499,10 @@ GLenum ToGLESFormat(ReplacedTextureFormat fmt) { void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImages) { entry->status &= ~TexCacheEntry::STATUS_ALPHA_MASK; + // Never replace images in-place - there's no such thing, drivers have to fake it anyway, at least if + // the image has been in use within the last frame or two. + replaceImages = false; + // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); @@ -566,7 +514,7 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag // Always generate a texture name unless it's a framebuffer, we might need it if the texture is replaced later. if (!replaceImages) { if (!entry->textureName) { - entry->textureName = AllocTextureName(); + entry->textureName = render_->CreateTexture(GL_TEXTURE_2D); } } @@ -635,8 +583,8 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag if (replaced.GetSize(0, w, h)) { if (replaceImages) { // Since we're replacing the texture, we can't replace the image inside. - glDeleteTextures(1, &entry->textureName); - entry->textureName = AllocTextureName(); + render_->DeleteTexture(entry->textureName); + entry->textureName = render_->CreateTexture(GL_TEXTURE_2D); replaceImages = false; } @@ -670,31 +618,9 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag } } - glBindTexture(GL_TEXTURE_2D, entry->textureName); + // glBindTexture(GL_TEXTURE_2D, entry->textureName); lastBoundTexture = entry->textureName; - - // Disabled this due to issue #6075: https://github.com/hrydgard/ppsspp/issues/6075 - // This breaks Dangan Ronpa 2 with mipmapping enabled. Why? No idea, it shouldn't. - // glTexStorage2D probably has few benefits for us anyway. - if (false && gl_extensions.GLES3 && maxLevel > 0) { - // glTexStorage2D requires the use of sized formats. - GLenum actualFmt = replaced.Valid() ? ToGLESFormat(replaced.Format(0)) : dstFmt; - GLenum storageFmt = GL_RGBA8; - switch (actualFmt) { - case GL_UNSIGNED_BYTE: storageFmt = GL_RGBA8; break; - case GL_UNSIGNED_SHORT_5_6_5: storageFmt = GL_RGB565; break; - case GL_UNSIGNED_SHORT_4_4_4_4: storageFmt = GL_RGBA4; break; - case GL_UNSIGNED_SHORT_5_5_5_1: storageFmt = GL_RGB5_A1; break; - default: - ERROR_LOG(G3D, "Unknown dstfmt %i", (int)actualFmt); - break; - } - // TODO: This may cause bugs, since it hard-sets the texture w/h, and we might try to reuse it later with a different size. - glTexStorage2D(GL_TEXTURE_2D, maxLevel + 1, storageFmt, w * scaleFactor, h * scaleFactor); - // Make sure we don't use glTexImage2D after glTexStorage2D. - replaceImages = true; - } - + // GLES2 doesn't have support for a "Max lod" which is critical as PSP games often // don't specify mips all the way down. As a result, we either need to manually generate // the bottom few levels or rely on OpenGL's autogen mipmaps instead, which might not @@ -709,33 +635,35 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag LoadTextureLevel(*entry, replaced, 0, replaceImages, scaleFactor, dstFmt); // Mipmapping only enable when texture scaling disable + int texMaxLevel = 0; + bool genMips = false; if (maxLevel > 0 && scaleFactor == 1) { if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { if (badMipSizes) { // WARN_LOG(G3D, "Bad mipmap for texture sized %dx%dx%d - autogenerating", w, h, (int)format); if (canAutoGen) { - glGenerateMipmap(GL_TEXTURE_2D); + genMips = true; } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + texMaxLevel = 0; maxLevel = 0; } } else { for (int i = 1; i <= maxLevel; i++) { LoadTextureLevel(*entry, replaced, i, replaceImages, scaleFactor, dstFmt); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel); + texMaxLevel = maxLevel; } } else { // Avoid PowerVR driver bug if (canAutoGen && w > 1 && h > 1 && !(h > w && (gl_extensions.bugs & BUG_PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width // NOTICE_LOG(G3D, "Generating mipmap for texture sized %dx%d%d", w, h, (int)format); - glGenerateMipmap(GL_TEXTURE_2D); + genMips = true; } else { maxLevel = 0; } } } else if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + texMaxLevel = 0; } if (maxLevel == 0) { @@ -747,32 +675,12 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag entry->SetAlphaStatus(TexCacheEntry::TexStatus(replaced.AlphaStatus())); } - if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY)) { - int aniso = 1 << g_Config.iAnisotropyLevel; - float anisotropyLevel = (float) aniso > maxAnisotropyLevel ? maxAnisotropyLevel : (float) aniso; - if (anisotropyLevel > 1.0f) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropyLevel); - } - } + render_->FinalizeTexture(entry->textureName, texMaxLevel, genMips); // This will rebind it, but that's okay. + // Need to actually bind it now - it might only have gotten bound in the init phase. + render_->BindTexture(0, entry->textureName); UpdateSamplingParams(*entry, true); - - //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - //glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - CHECK_GL_ERROR_IF_DEBUG(); -} - -u32 TextureCacheGLES::AllocTextureName() { - if (nameCache_.empty()) { - nameCache_.resize(TEXCACHE_NAME_CACHE_SIZE); - glGenTextures(TEXCACHE_NAME_CACHE_SIZE, &nameCache_[0]); - } - u32 name = nameCache_.back(); - nameCache_.pop_back(); - return name; } GLenum TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { @@ -797,44 +705,21 @@ GLenum TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat c } } -void *TextureCacheGLES::DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufwout) { - void *finalBuf = nullptr; - u32 texaddr = gstate.getTextureAddress(level); - int bufw = GetTextureBufw(level, texaddr, format); - if (bufwout) - *bufwout = bufw; - - int w = gstate.getTextureWidth(level); - int h = gstate.getTextureHeight(level); - - int decPitch = 0; - int pixelSize = dstFmt == GL_UNSIGNED_BYTE ? 4 : 2; - if (!(scaleFactor == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE)) && w != bufw) { - decPitch = w * pixelSize; - } else { - decPitch = bufw * pixelSize; - } - - tmpTexBufRearrange_.resize(std::max(w, bufw) * h); - DecodeTextureLevel((u8 *)tmpTexBufRearrange_.data(), decPitch, format, clutformat, texaddr, level, bufw, true, false, false); - return tmpTexBufRearrange_.data(); -} - -TexCacheEntry::TexStatus TextureCacheGLES::CheckAlpha(const u32 *pixelData, GLenum dstFmt, int stride, int w, int h) { +TexCacheEntry::TexStatus TextureCacheGLES::CheckAlpha(const uint8_t *pixelData, GLenum dstFmt, int stride, int w, int h) { CheckAlphaResult res; switch (dstFmt) { case GL_UNSIGNED_SHORT_4_4_4_4: - res = CheckAlphaABGR4444Basic(pixelData, stride, w, h); + res = CheckAlphaABGR4444Basic((const uint32_t *)pixelData, stride, w, h); break; case GL_UNSIGNED_SHORT_5_5_5_1: - res = CheckAlphaABGR1555Basic(pixelData, stride, w, h); + res = CheckAlphaABGR1555Basic((const uint32_t *)pixelData, stride, w, h); break; case GL_UNSIGNED_SHORT_5_6_5: // Never has any alpha. res = CHECKALPHA_FULL; break; default: - res = CheckAlphaRGBA8888Basic(pixelData, stride, w, h); + res = CheckAlphaRGBA8888Basic((const uint32_t *)pixelData, stride, w, h); break; } @@ -845,9 +730,7 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r int w = gstate.getTextureWidth(level); int h = gstate.getTextureHeight(level); bool useUnpack = false; - u32 *pixelData; - - CHECK_GL_ERROR_IF_DEBUG(); + uint8_t *pixelData; // TODO: only do this once u32 texByteAlign = 1; @@ -857,10 +740,10 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r if (replaced.GetSize(level, w, h)) { PROFILE_THIS_SCOPE("replacetex"); - tmpTexBufRearrange_.resize(w * h); int bpp = replaced.Format(level) == ReplacedTextureFormat::F_8888 ? 4 : 2; - replaced.Load(level, tmpTexBufRearrange_.data(), bpp * w); - pixelData = tmpTexBufRearrange_.data(); + uint8_t *rearrange = (uint8_t *)AllocateAlignedMemory(w * h * bpp, 16); + replaced.Load(level, rearrange, bpp * w); + pixelData = rearrange; dstFmt = ToGLESFormat(replaced.Format(level)); @@ -869,22 +752,14 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r PROFILE_THIS_SCOPE("decodetex"); GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); - int bufw; - void *finalBuf = DecodeTextureLevelOld(GETextureFormat(entry.format), clutformat, level, dstFmt, scaleFactor, &bufw); - if (finalBuf == NULL) { - return; - } + u32 texaddr = gstate.getTextureAddress(level); + int bufw = GetTextureBufw(level, texaddr, GETextureFormat(entry.format)); - // Can restore these and remove the fixup at the end of DecodeTextureLevel on desktop GL and GLES 3. - if (scaleFactor == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE) && w != bufw) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, bufw); - useUnpack = true; - } + int pixelSize = dstFmt == GL_UNSIGNED_BYTE ? 4 : 2; + int decPitch = w * pixelSize; - // Textures are always aligned to 16 bytes bufw, so this could safely be 4 always. - texByteAlign = dstFmt == GL_UNSIGNED_BYTE ? 4 : 2; - - pixelData = (u32 *)finalBuf; + pixelData = (uint8_t *)AllocateAlignedMemory(decPitch * h * pixelSize, 16); + DecodeTextureLevel(pixelData, decPitch, GETextureFormat(entry.format), clutformat, texaddr, level, bufw, true, false, false); // We check before scaling since scaling shouldn't invent alpha from a full alpha texture. if ((entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) { @@ -894,8 +769,15 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r entry.SetAlphaStatus(TexCacheEntry::STATUS_ALPHA_UNKNOWN); } - if (scaleFactor > 1) - scaler.Scale(pixelData, dstFmt, w, h, scaleFactor); + if (scaleFactor > 1) { + uint8_t *rearrange = (uint8_t *)AllocateAlignedMemory(w * scaleFactor * h * scaleFactor * 4, 16); + scaler.ScaleAlways((u32 *)rearrange, (u32 *)pixelData, dstFmt, w, h, scaleFactor); + FreeAlignedMemory(pixelData); + pixelData = rearrange; + } + + // Textures are always aligned to 16 bytes bufw, so this could safely be 4 always. + texByteAlign = dstFmt == GL_UNSIGNED_BYTE ? 4 : 2; if (replacer_.Enabled()) { ReplacedTextureDecodeInfo replacedInfo; @@ -912,133 +794,21 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r } } - glPixelStorei(GL_UNPACK_ALIGNMENT, texByteAlign); - - CHECK_GL_ERROR_IF_DEBUG(); - GLuint components = dstFmt == GL_UNSIGNED_SHORT_5_6_5 ? GL_RGB : GL_RGBA; GLuint components2 = components; if (replaceImages) { PROFILE_THIS_SCOPE("repltex"); - glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData); + Crash(); + // glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData); } else { PROFILE_THIS_SCOPE("loadtex"); - // Avoid misleading errors in texture upload, these are common. - GLenum err = glGetError(); - if (err) { - WARN_LOG(G3D, "Got an error BEFORE texture upload: %08x (%s)", err, GLEnumToString(err).c_str()); - } if (IsFakeMipmapChange()) - glTexImage2D(GL_TEXTURE_2D, 0, components, w, h, 0, components2, dstFmt, pixelData); + render_->TextureImage(entry.textureName, 0, w, h, components, components2, dstFmt, pixelData, GLRAllocType::ALIGNED); else - glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData); - if (!lowMemoryMode_) { - // TODO: We really, really should avoid calling glGetError. - GLenum err = glGetError(); - if (err == GL_OUT_OF_MEMORY) { - WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode"); - lowMemoryMode_ = true; - decimationCounter_ = 0; - Decimate(); - // Try again, now that we've cleared out textures in lowMemoryMode_. - glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData); - - I18NCategory *err = GetI18NCategory("Error"); - if (scaleFactor > 1) { - host->NotifyUserMessage(err->T("Warning: Video memory FULL, reducing upscaling and switching to slow caching mode"), 2.0f); - } else { - host->NotifyUserMessage(err->T("Warning: Video memory FULL, switching to slow caching mode"), 2.0f); - } - } else if (err != GL_NO_ERROR) { - // We checked the err anyway, might as well log if there is one. - WARN_LOG(G3D, "Got an error in texture upload: %08x (%s) (components=%s components2=%s dstFmt=%s w=%d h=%d level=%d)", - err, GLEnumToString(err).c_str(), GLEnumToString(components).c_str(), GLEnumToString(components2).c_str(), GLEnumToString(dstFmt).c_str(), - w, h, level); - } - } + render_->TextureImage(entry.textureName, level, w, h, components, components2, dstFmt, pixelData, GLRAllocType::ALIGNED); } - - if (useUnpack) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - } -} - -// Only used by Qt UI? -bool TextureCacheGLES::DecodeTexture(u8* output, const GPUgstate &state) { - GPUgstate oldState = gstate; - gstate = state; - - u32 texaddr = gstate.getTextureAddress(0); - - if (!Memory::IsValidAddress(texaddr)) { - return false; - } - - GLenum dstFmt = 0; - - GETextureFormat format = gstate.getTextureFormat(); - GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); - u8 level = 0; - - int bufw = GetTextureBufw(level, texaddr, format); - int w = gstate.getTextureWidth(level); - int h = gstate.getTextureHeight(level); - - void *finalBuf = DecodeTextureLevelOld(format, clutformat, level, dstFmt, 1); - if (finalBuf == NULL) { - return false; - } - - switch (dstFmt) { - case GL_UNSIGNED_SHORT_4_4_4_4: - for (int y = 0; y < h; y++) - for (int x = 0; x < bufw; x++) { - u32 val = ((u16*)finalBuf)[y*bufw + x]; - u32 r = ((val>>12) & 0xF) * 17; - u32 g = ((val>> 8) & 0xF) * 17; - u32 b = ((val>> 4) & 0xF) * 17; - u32 a = ((val>> 0) & 0xF) * 17; - ((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - - case GL_UNSIGNED_SHORT_5_5_5_1: - for (int y = 0; y < h; y++) - for (int x = 0; x < bufw; x++) { - u32 val = ((u16*)finalBuf)[y*bufw + x]; - u32 r = Convert5To8((val>>11) & 0x1F); - u32 g = Convert5To8((val>> 6) & 0x1F); - u32 b = Convert5To8((val>> 1) & 0x1F); - u32 a = (val & 0x1) * 255; - ((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - - case GL_UNSIGNED_SHORT_5_6_5: - for (int y = 0; y < h; y++) - for (int x = 0; x < bufw; x++) { - u32 val = ((u16*)finalBuf)[y*bufw + x]; - u32 a = 0xFF; - u32 r = Convert5To8((val>>11) & 0x1F); - u32 g = Convert6To8((val>> 5) & 0x3F); - u32 b = Convert5To8((val ) & 0x1F); - ((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b; - } - break; - - default: - for (int y = 0; y < h; y++) - for (int x = 0; x < bufw; x++) { - u32 val = ((u32*)finalBuf)[y*bufw + x]; - ((u32*)output)[y*w + x] = ((val & 0xFF000000)) | ((val & 0x00FF0000)>>16) | ((val & 0x0000FF00)) | ((val & 0x000000FF)<<16); - } - break; - } - - gstate = oldState; - return true; } bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { @@ -1054,19 +824,40 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) } SetTexture(true); + if (!nextTexture_) + return false; + + // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. + TexCacheEntry *entry = nextTexture_; ApplyTexture(); + + // TODO: Centralize? + if (entry->framebuffer) { + VirtualFramebuffer *vfb = entry->framebuffer; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); + // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. + // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); + // We may have blitted to a temp FBO. + framebufferManager_->RebindFramebuffer(); + return retval; + } + + GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + + // Not a framebuffer, so let's assume these are right. int w = gstate.getTextureWidth(level); int h = gstate.getTextureHeight(level); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); if (level != 0) { gstate = saved; } buffer.Allocate(w, h, GE_FORMAT_8888, false); - glPixelStorei(GL_PACK_ALIGNMENT, 4); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.GetData()); + renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w); + gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); + framebufferManager_->RebindFramebuffer(); return true; #else diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 9e894e2476..82756af4f6 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -21,6 +21,7 @@ #include "gfx_es2/gpu_features.h" #include "gfx/gl_common.h" +#include "thin3d/GLRenderManager.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" #include "GPU/GLES/TextureScalerGLES.h" @@ -31,6 +32,7 @@ class FramebufferManagerGLES; class DepalShaderCacheGLES; class ShaderManagerGLES; class DrawEngineGLES; +class GLRTexture; class TextureCacheGLES : public TextureCacheCommon { public: @@ -52,20 +54,15 @@ public: } void ForgetLastTexture() override { - lastBoundTexture = INVALID_TEX; + lastBoundTexture = nullptr; gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override { if (!entry || entry->textureName == lastBoundTexture) { - lastBoundTexture = INVALID_TEX; + lastBoundTexture = nullptr; } } - u32 AllocTextureName(); - - // Only used by Qt UI? - bool DecodeTexture(u8 *output, const GPUgstate &state); - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; @@ -80,25 +77,26 @@ private: void UpdateSamplingParams(TexCacheEntry &entry, bool force); void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, bool replaceImages, int scaleFactor, GLenum dstFmt); GLenum GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; - void *DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufw = 0); - TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, GLenum dstFmt, int stride, int w, int h); + + TexCacheEntry::TexStatus CheckAlpha(const uint8_t *pixelData, GLenum dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; void BuildTexture(TexCacheEntry *const entry, bool replaceImages) override; - std::vector nameCache_; + GLRenderManager *render_; TextureScalerGLES scaler; - u32 lastBoundTexture; - float maxAnisotropyLevel; + GLRTexture *lastBoundTexture; FramebufferManagerGLES *framebufferManagerGL_; DepalShaderCacheGLES *depalShaderCache_; ShaderManagerGLES *shaderManager_; DrawEngineGLES *drawEngine_; + GLRInputLayout *shadeInputLayout_; + enum { INVALID_TEX = -1 }; }; diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index a7c82651b7..fffe826c30 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -39,30 +39,6 @@ #define WRITE p+=sprintf -static const char * const boneWeightAttrDecl[9] = { - "#ERROR#", - "attribute mediump float w1;\n", - "attribute mediump vec2 w1;\n", - "attribute mediump vec3 w1;\n", - "attribute mediump vec4 w1;\n", - "attribute mediump vec4 w1;\nattribute mediump float w2;\n", - "attribute mediump vec4 w1;\nattribute mediump vec2 w2;\n", - "attribute mediump vec4 w1;\nattribute mediump vec3 w2;\n", - "attribute mediump vec4 w1, w2;\n", -}; - -static const char * const boneWeightInDecl[9] = { - "#ERROR#", - "in mediump float w1;\n", - "in mediump vec2 w1;\n", - "in mediump vec3 w1;\n", - "in mediump vec4 w1;\n", - "in mediump vec4 w1;\nin mediump float w2;\n", - "in mediump vec4 w1;\nin mediump vec2 w2;\n", - "in mediump vec4 w1;\nin mediump vec3 w2;\n", - "in mediump vec4 w1, w2;\n", -}; - enum DoLightComputation { LIGHT_OFF, LIGHT_SHADE, @@ -113,9 +89,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, bool glslES30 = false; const char *varying = "varying"; const char *attribute = "attribute"; - const char * const * boneWeightDecl = boneWeightAttrDecl; const char *texelFetch = NULL; - bool isAllowTexture1D = false; bool highpFog = false; bool highpTexcoord = false; @@ -143,13 +117,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, glslES30 = true; WRITE(p, "#version 330\n"); texelFetch = "texelFetch"; - isAllowTexture1D = true; } else if (gl_extensions.VersionGEThan(3, 0, 0)) { WRITE(p, "#version 130\n"); if (gl_extensions.EXT_gpu_shader4) { WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n"); texelFetch = "texelFetch"; - isAllowTexture1D = true; } } else { WRITE(p, "#version 110\n"); @@ -169,7 +141,6 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (glslES30 || gl_extensions.IsCoreContext) { attribute = "in"; varying = "out"; - boneWeightDecl = boneWeightInDecl; } bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH); @@ -193,7 +164,6 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, bool flipNormal = id.Bit(VS_BIT_NORM_REVERSE); int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); - bool enableBones = id.Bit(VS_BIT_ENABLE_BONES); bool enableLighting = id.Bit(VS_BIT_LIGHTING_ENABLE); int matUpdate = id.Bits(VS_BIT_MATERIAL_UPDATE, 3); @@ -219,16 +189,6 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, } } - int numBoneWeights = 0; - int boneWeightScale = id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2); - if (enableBones) { - numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); - WRITE(p, "%s", boneWeightDecl[numBoneWeights]); - *attrMask |= 1 << ATTR_W1; - if (numBoneWeights >= 5) - *attrMask |= 1 << ATTR_W2; - } - if (useHWTransform) WRITE(p, "%s vec3 position;\n", attribute); else @@ -281,17 +241,6 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, WRITE(p, "uniform mediump mat4 u_texmtx;\n"); *uniformMask |= DIRTY_TEXMATRIX; } - if (enableBones) { -#ifdef USE_BONE_ARRAY - WRITE(p, "uniform mediump mat4 u_bone[%i];\n", numBoneWeights); - *uniformMask |= DIRTY_BONE_UNIFORMS; -#else - for (int i = 0; i < numBoneWeights; i++) { - WRITE(p, "uniform mat4 u_bone%i;\n", i); - *uniformMask |= DIRTY_BONEMATRIX0 << i; - } -#endif - } if (doTexture) { WRITE(p, "uniform vec4 u_uvscaleoffset;\n"); *uniformMask |= DIRTY_UVSCALEOFFSET; @@ -312,8 +261,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN) { WRITE(p, "uniform mediump vec3 u_lightdir%i;\n", i); - WRITE(p, "uniform mediump float u_lightangle%i;\n", i); - WRITE(p, "uniform mediump float u_lightspotCoef%i;\n", i); + WRITE(p, "uniform mediump vec2 u_lightangle_spotCoef%i;\n", i); } WRITE(p, "uniform lowp vec3 u_lightambient%i;\n", i); WRITE(p, "uniform lowp vec3 u_lightdiffuse%i;\n", i); @@ -387,10 +335,9 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (doBezier || doSpline) { *uniformMask |= DIRTY_BEZIERSPLINE; - const char *sampler = !isAllowTexture1D ? "sampler2D" : "sampler1D"; - WRITE(p, "uniform %s u_tess_pos_tex;\n", sampler); - WRITE(p, "uniform %s u_tess_tex_tex;\n", sampler); - WRITE(p, "uniform %s u_tess_col_tex;\n", sampler); + WRITE(p, "uniform sampler2D u_tess_pos_tex;\n"); + WRITE(p, "uniform sampler2D u_tess_tex_tex;\n"); + WRITE(p, "uniform sampler2D u_tess_col_tex;\n"); WRITE(p, "uniform int u_spline_count_u;\n"); @@ -504,190 +451,111 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, WriteGuardBand(p); WRITE(p, " gl_Position = outPos;\n"); } else { - // Step 1: World Transform / Skinning - if (!enableBones) { - // Hardware tessellation - if (doBezier || doSpline) { - WRITE(p, " vec3 _pos[16];\n"); - WRITE(p, " vec2 _tex[16];\n"); - WRITE(p, " vec4 _col[16];\n"); - WRITE(p, " int num_patches_u = %s;\n", doBezier ? "(u_spline_count_u - 1) / 3" : "u_spline_count_u - 3"); - WRITE(p, " int u = int(mod(float(gl_InstanceID), float(num_patches_u)));\n"); - WRITE(p, " int v = gl_InstanceID / num_patches_u;\n"); - WRITE(p, " ivec2 patch_pos = ivec2(u, v);\n"); - WRITE(p, " for (int i = 0; i < 4; i++) {\n"); - WRITE(p, " for (int j = 0; j < 4; j++) {\n"); - WRITE(p, " int index = (i + v%s) * u_spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : ""); - const char *index = !isAllowTexture1D ? "ivec2(index, 0)" : "index"; - WRITE(p, " _pos[i * 4 + j] = %s(u_tess_pos_tex, %s, 0).xyz;\n", texelFetch, index); - if (doTexture && hasTexcoord && hasTexcoordTess) - WRITE(p, " _tex[i * 4 + j] = %s(u_tess_tex_tex, %s, 0).xy;\n", texelFetch, index); - if (hasColor && hasColorTess) - WRITE(p, " _col[i * 4 + j] = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, index); - WRITE(p, " }\n"); - WRITE(p, " }\n"); - WRITE(p, " vec2 tess_pos = position.xy;\n"); - WRITE(p, " vec2 weights[4];\n"); - if (doBezier) { - // Bernstein 3D - WRITE(p, " weights[0] = (1.0 - tess_pos) * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); - WRITE(p, " weights[1] = 3.0 * tess_pos * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); - WRITE(p, " weights[2] = 3.0 * tess_pos * tess_pos * (1.0 - tess_pos);\n"); - WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); - } else { // Spline - WRITE(p, " ivec2 spline_num_patches = ivec2(u_spline_count_u - 3, u_spline_count_v - 3);\n"); - WRITE(p, " ivec2 spline_type = ivec2(u_spline_type_u, u_spline_type_v);\n"); - WRITE(p, " vec2 knots[6];\n"); - WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); - WRITE(p, " spline_weight(tess_pos + vec2(patch_pos), knots, weights);\n"); - } - WRITE(p, " vec3 pos = tess_sample(_pos, weights);\n"); - if (doTexture && hasTexcoord) { - if (hasTexcoordTess) - WRITE(p, " vec2 tex = tess_sample(_tex, weights);\n"); - else - WRITE(p, " vec2 tex = tess_pos + vec2(patch_pos);\n"); - } - if (hasColor) { - if (hasColorTess) - WRITE(p, " vec4 col = tess_sample(_col, weights);\n"); - else - WRITE(p, " vec4 col = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, !isAllowTexture1D ? "ivec2(0, 0)" : "0"); - } - if (hasNormal) { - // Curved surface is probably always need to compute normal(not sampling from control points) - if (doBezier) { - // Bernstein derivative - WRITE(p, " vec2 bernderiv[4];\n"); - WRITE(p, " bernderiv[0] = -3.0 * (tess_pos - 1.0) * (tess_pos - 1.0); \n"); - WRITE(p, " bernderiv[1] = 9.0 * tess_pos * tess_pos - 12.0 * tess_pos + 3.0; \n"); - WRITE(p, " bernderiv[2] = 3.0 * (2.0 - 3.0 * tess_pos) * tess_pos; \n"); - WRITE(p, " bernderiv[3] = 3.0 * tess_pos * tess_pos; \n"); - - WRITE(p, " vec2 bernderiv_u[4];\n"); - WRITE(p, " vec2 bernderiv_v[4];\n"); - WRITE(p, " for (int i = 0; i < 4; i++) {\n"); - WRITE(p, " bernderiv_u[i] = vec2(bernderiv[i].x, weights[i].y);\n"); - WRITE(p, " bernderiv_v[i] = vec2(weights[i].x, bernderiv[i].y);\n"); - WRITE(p, " }\n"); - - WRITE(p, " vec3 du = tess_sample(_pos, bernderiv_u);\n"); - WRITE(p, " vec3 dv = tess_sample(_pos, bernderiv_v);\n"); - } else { // Spline - WRITE(p, " vec2 tess_next_u = vec2(normal.x, 0.0);\n"); - WRITE(p, " vec2 tess_next_v = vec2(0.0, normal.y);\n"); - // Right - WRITE(p, " vec2 tess_pos_r = tess_pos + tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_r + vec2(patch_pos), knots, weights);\n"); - WRITE(p, " vec3 pos_r = tess_sample(_pos, weights);\n"); - // Left - WRITE(p, " vec2 tess_pos_l = tess_pos - tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_l + vec2(patch_pos), knots, weights);\n"); - WRITE(p, " vec3 pos_l = tess_sample(_pos, weights);\n"); - // Down - WRITE(p, " vec2 tess_pos_d = tess_pos + tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_d + vec2(patch_pos), knots, weights);\n"); - WRITE(p, " vec3 pos_d = tess_sample(_pos, weights);\n"); - // Up - WRITE(p, " vec2 tess_pos_u = tess_pos - tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_u + vec2(patch_pos), knots, weights);\n"); - WRITE(p, " vec3 pos_u = tess_sample(_pos, weights);\n"); - - WRITE(p, " vec3 du = pos_r - pos_l;\n"); - WRITE(p, " vec3 dv = pos_d - pos_u;\n"); - } - WRITE(p, " vec3 nrm = cross(du, dv);\n"); - WRITE(p, " nrm = normalize(nrm);\n"); - } - WRITE(p, " vec3 worldpos = (u_world * vec4(pos.xyz, 1.0)).xyz;\n"); - if (hasNormal) { - WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snrm, 0.0)).xyz);\n", flipNormalTess ? "-" : ""); - } else { - WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); - } - } else { - // No skinning, just standard T&L. - WRITE(p, " vec3 worldpos = (u_world * vec4(position.xyz, 1.0)).xyz;\n"); - if (hasNormal) - WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snormal, 0.0)).xyz);\n", flipNormal ? "-" : ""); + // Step 1: World Transform + // Hardware tessellation + if (doBezier || doSpline) { + WRITE(p, " vec3 _pos[16];\n"); + WRITE(p, " vec2 _tex[16];\n"); + WRITE(p, " vec4 _col[16];\n"); + WRITE(p, " int num_patches_u = %s;\n", doBezier ? "(u_spline_count_u - 1) / 3" : "u_spline_count_u - 3"); + WRITE(p, " int u = int(mod(float(gl_InstanceID), float(num_patches_u)));\n"); + WRITE(p, " int v = gl_InstanceID / num_patches_u;\n"); + WRITE(p, " ivec2 patch_pos = ivec2(u, v);\n"); + WRITE(p, " for (int i = 0; i < 4; i++) {\n"); + WRITE(p, " for (int j = 0; j < 4; j++) {\n"); + WRITE(p, " int index = (i + v%s) * u_spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : ""); + WRITE(p, " _pos[i * 4 + j] = %s(u_tess_pos_tex, ivec2(index, 0), 0).xyz;\n", texelFetch); + if (doTexture && hasTexcoord && hasTexcoordTess) + WRITE(p, " _tex[i * 4 + j] = %s(u_tess_tex_tex, ivec2(index, 0), 0).xy;\n", texelFetch); + if (hasColor && hasColorTess) + WRITE(p, " _col[i * 4 + j] = %s(u_tess_col_tex, ivec2(index, 0), 0).rgba;\n", texelFetch); + WRITE(p, " }\n"); + WRITE(p, " }\n"); + WRITE(p, " vec2 tess_pos = position.xy;\n"); + WRITE(p, " vec2 weights[4];\n"); + if (doBezier) { + // Bernstein 3D + WRITE(p, " weights[0] = (1.0 - tess_pos) * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); + WRITE(p, " weights[1] = 3.0 * tess_pos * (1.0 - tess_pos) * (1.0 - tess_pos);\n"); + WRITE(p, " weights[2] = 3.0 * tess_pos * tess_pos * (1.0 - tess_pos);\n"); + WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); + } else { // Spline + WRITE(p, " ivec2 spline_num_patches = ivec2(u_spline_count_u - 3, u_spline_count_v - 3);\n"); + WRITE(p, " ivec2 spline_type = ivec2(u_spline_type_u, u_spline_type_v);\n"); + WRITE(p, " vec2 knots[6];\n"); + WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); + WRITE(p, " spline_weight(tess_pos + vec2(patch_pos), knots, weights);\n"); + } + WRITE(p, " vec3 pos = tess_sample(_pos, weights);\n"); + if (doTexture && hasTexcoord) { + if (hasTexcoordTess) + WRITE(p, " vec2 tex = tess_sample(_tex, weights);\n"); else - WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); + WRITE(p, " vec2 tex = tess_pos + vec2(patch_pos);\n"); + } + if (hasColor) { + if (hasColorTess) + WRITE(p, " vec4 col = tess_sample(_col, weights);\n"); + else + WRITE(p, " vec4 col = %s(u_tess_col_tex, ivec2(0, 0), 0).rgba;\n", texelFetch); + } + if (hasNormal) { + // Curved surface is probably always need to compute normal(not sampling from control points) + if (doBezier) { + // Bernstein derivative + WRITE(p, " vec2 bernderiv[4];\n"); + WRITE(p, " bernderiv[0] = -3.0 * (tess_pos - 1.0) * (tess_pos - 1.0); \n"); + WRITE(p, " bernderiv[1] = 9.0 * tess_pos * tess_pos - 12.0 * tess_pos + 3.0; \n"); + WRITE(p, " bernderiv[2] = 3.0 * (2.0 - 3.0 * tess_pos) * tess_pos; \n"); + WRITE(p, " bernderiv[3] = 3.0 * tess_pos * tess_pos; \n"); + + WRITE(p, " vec2 bernderiv_u[4];\n"); + WRITE(p, " vec2 bernderiv_v[4];\n"); + WRITE(p, " for (int i = 0; i < 4; i++) {\n"); + WRITE(p, " bernderiv_u[i] = vec2(bernderiv[i].x, weights[i].y);\n"); + WRITE(p, " bernderiv_v[i] = vec2(weights[i].x, bernderiv[i].y);\n"); + WRITE(p, " }\n"); + + WRITE(p, " vec3 du = tess_sample(_pos, bernderiv_u);\n"); + WRITE(p, " vec3 dv = tess_sample(_pos, bernderiv_v);\n"); + } else { // Spline + WRITE(p, " vec2 tess_next_u = vec2(normal.x, 0.0);\n"); + WRITE(p, " vec2 tess_next_v = vec2(0.0, normal.y);\n"); + // Right + WRITE(p, " vec2 tess_pos_r = tess_pos + tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_r + vec2(patch_pos), knots, weights);\n"); + WRITE(p, " vec3 pos_r = tess_sample(_pos, weights);\n"); + // Left + WRITE(p, " vec2 tess_pos_l = tess_pos - tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_l + vec2(patch_pos), knots, weights);\n"); + WRITE(p, " vec3 pos_l = tess_sample(_pos, weights);\n"); + // Down + WRITE(p, " vec2 tess_pos_d = tess_pos + tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_d + vec2(patch_pos), knots, weights);\n"); + WRITE(p, " vec3 pos_d = tess_sample(_pos, weights);\n"); + // Up + WRITE(p, " vec2 tess_pos_u = tess_pos - tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_u + vec2(patch_pos), knots, weights);\n"); + WRITE(p, " vec3 pos_u = tess_sample(_pos, weights);\n"); + + WRITE(p, " vec3 du = pos_r - pos_l;\n"); + WRITE(p, " vec3 dv = pos_d - pos_u;\n"); + } + WRITE(p, " vec3 nrm = cross(du, dv);\n"); + WRITE(p, " nrm = normalize(nrm);\n"); + } + WRITE(p, " vec3 worldpos = (u_world * vec4(pos.xyz, 1.0)).xyz;\n"); + if (hasNormal) { + WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snrm, 0.0)).xyz);\n", flipNormalTess ? "-" : ""); + } else { + WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } } else { - static const char *rescale[4] = {"", " * 1.9921875", " * 1.999969482421875", ""}; // 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f}; - const char *factor = rescale[boneWeightScale]; - - static const char * const boneWeightAttr[8] = { - "w1.x", "w1.y", "w1.z", "w1.w", - "w2.x", "w2.y", "w2.z", "w2.w", - }; - -#if defined(USE_FOR_LOOP) && defined(USE_BONE_ARRAY) - - // To loop through the weights, we unfortunately need to put them in a float array. - // GLSL ES sucks - no way to directly initialize an array! - switch (numBoneWeights) { - case 1: WRITE(p, " float w[1]; w[0] = w1;\n"); break; - case 2: WRITE(p, " float w[2]; w[0] = w1.x; w[1] = w1.y;\n"); break; - case 3: WRITE(p, " float w[3]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z;\n"); break; - case 4: WRITE(p, " float w[4]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w;\n"); break; - case 5: WRITE(p, " float w[5]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2;\n"); break; - case 6: WRITE(p, " float w[6]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y;\n"); break; - case 7: WRITE(p, " float w[7]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y; w[6] = w2.z;\n"); break; - case 8: WRITE(p, " float w[8]; w[0] = w1.x; w[1] = w1.y; w[2] = w1.z; w[3] = w1.w; w[4] = w2.x; w[5] = w2.y; w[6] = w2.z; w[7] = w2.w;\n"); break; - } - - WRITE(p, " mat4 skinMatrix = w[0] * u_bone[0];\n"); - if (numBoneWeights > 1) { - WRITE(p, " for (int i = 1; i < %i; i++) {\n", numBoneWeights); - WRITE(p, " skinMatrix += w[i] * u_bone[i];\n"); - WRITE(p, " }\n"); - } - -#else - -#ifdef USE_BONE_ARRAY - if (numBoneWeights == 1) - WRITE(p, " mat4 skinMatrix = w1 * u_bone[0]"); + WRITE(p, " vec3 worldpos = (u_world * vec4(position.xyz, 1.0)).xyz;\n"); + if (hasNormal) + WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snormal, 0.0)).xyz);\n", flipNormal ? "-" : ""); else - WRITE(p, " mat4 skinMatrix = w1.x * u_bone[0]"); - for (int i = 1; i < numBoneWeights; i++) { - const char *weightAttr = boneWeightAttr[i]; - // workaround for "cant do .x of scalar" issue - if (numBoneWeights == 1 && i == 0) weightAttr = "w1"; - if (numBoneWeights == 5 && i == 4) weightAttr = "w2"; - WRITE(p, " + %s * u_bone[%i]", weightAttr, i); - } -#else - // Uncomment this to screw up bone shaders to check the vertex shader software fallback - // WRITE(p, "THIS SHOULD ERROR! #error"); - if (numBoneWeights == 1) - WRITE(p, " mat4 skinMatrix = w1 * u_bone0"); - else - WRITE(p, " mat4 skinMatrix = w1.x * u_bone0"); - for (int i = 1; i < numBoneWeights; i++) { - const char *weightAttr = boneWeightAttr[i]; - // workaround for "cant do .x of scalar" issue - if (numBoneWeights == 1 && i == 0) weightAttr = "w1"; - if (numBoneWeights == 5 && i == 4) weightAttr = "w2"; - WRITE(p, " + %s * u_bone%i", weightAttr, i); - } -#endif - -#endif - - WRITE(p, ";\n"); - - // Trying to simplify this results in bugs in LBP... - WRITE(p, " vec3 skinnedpos = (skinMatrix * vec4(position, 1.0)).xyz %s;\n", factor); - WRITE(p, " vec3 worldpos = (u_world * vec4(skinnedpos, 1.0)).xyz;\n"); - - if (hasNormal) { - WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(%snormal, 0.0)).xyz %s;\n", flipNormal ? "-" : "", factor); - } else { - WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(0.0, 0.0, %s1.0, 0.0)).xyz %s;\n", flipNormal ? "-" : "", factor); - } - WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(skinnednormal, 0.0)).xyz);\n"); + WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } WRITE(p, " vec4 viewPos = u_view * vec4(worldpos, 1.0);\n"); @@ -796,8 +664,8 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: WRITE(p, " angle = dot(normalize(u_lightdir%i), toLight);\n", i); - WRITE(p, " if (angle >= u_lightangle%i) {\n", i); - WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle, u_lightspotCoef%i);\n", i, i); + WRITE(p, " if (angle >= u_lightangle_spotCoef%i.x) {\n", i); + WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle, u_lightangle_spotCoef%i.y);\n", i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); diff --git a/GPU/GLES/VertexShaderGeneratorGLES.h b/GPU/GLES/VertexShaderGeneratorGLES.h index 7801b2cd6f..ae78cad767 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.h +++ b/GPU/GLES/VertexShaderGeneratorGLES.h @@ -19,8 +19,6 @@ #include "Common/CommonTypes.h" -// #define USE_BONE_ARRAY - struct VShaderID; void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask); diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp index 847e25661f..abccdf6da9 100644 --- a/GPU/GPU.cpp +++ b/GPU/GPU.cpp @@ -110,6 +110,6 @@ bool GPU_Init(GraphicsContext *ctx, Draw::DrawContext *draw) { void GPU_Shutdown() { delete gpu; - gpu = 0; + gpu = nullptr; gpuDebug = 0; } diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index ddc5b0ff12..7dc2f25cad 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -270,7 +270,9 @@ D3D11 - + + Vulkan + @@ -537,6 +539,8 @@ Common - + + Vulkan + \ No newline at end of file diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index d75625a94a..1762edffbb 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -42,6 +42,15 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BJump }, // EXECUTE { GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to? + { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPUCommon::Execute_Prim }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, + + // Changing the vertex type does not always require us to flush so handle that in Execute_VertexType. + { GE_CMD_VERTEXTYPE, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_VertexType }, + + { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_LoadClut }, + // These two are actually processed in CMD_END. Not sure if FLAG_FLUSHBEFORE matters. { GE_CMD_SIGNAL, FLAG_FLUSHBEFORE }, { GE_CMD_FINISH, FLAG_FLUSHBEFORE }, @@ -121,7 +130,7 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_TEXOFFSETU }, { GE_CMD_TEXOFFSETV }, - // TEXSIZE0 is handled by each backend. + { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_TexSize0 }, { GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, { GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, { GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, @@ -343,6 +352,9 @@ const CommonCommandTableEntry commonCommandTable[] = { }; size_t commonCommandTableSize = ARRAY_SIZE(commonCommandTable); +// TODO: Make class member? +GPUCommon::CommandInfo GPUCommon::cmdInfo_[256]; + void GPUCommon::Flush() { drawEngineCommon_->DispatchFlush(); } @@ -366,6 +378,31 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : gstate.Reset(); gstate_c.Reset(); gpuStats.Reset(); + + memset(cmdInfo_, 0, sizeof(cmdInfo_)); + + // Convert the command table to a faster format, and check for dupes. + std::set dupeCheck; + for (size_t i = 0; i < commonCommandTableSize; i++) { + const u8 cmd = commonCommandTable[i].cmd; + if (dupeCheck.find(cmd) != dupeCheck.end()) { + ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); + } else { + dupeCheck.insert(cmd); + } + cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); + cmdInfo_[cmd].func = commonCommandTable[i].func; + if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { + // Can't have FLAG_EXECUTE commands without a function pointer to execute. + Crash(); + } + } + // Find commands missing from the table. + for (int i = 0; i < 0xEF; i++) { + if (dupeCheck.find((u8)i) == dupeCheck.end()) { + ERROR_LOG(G3D, "Command missing from table: %02x (%i)", i, i); + } + } } GPUCommon::~GPUCommon() { @@ -923,6 +960,46 @@ bool GPUCommon::InterpretList(DisplayList &list) { return gpuState == GPUSTATE_DONE || gpuState == GPUSTATE_ERROR; } +// Maybe should write this in ASM... +void GPUCommon::FastRunLoop(DisplayList &list) { + PROFILE_THIS_SCOPE("gpuloop"); + const CommandInfo *cmdInfo = cmdInfo_; + int dc = downcount; + for (; dc > 0; --dc) { + // We know that display list PCs have the upper nibble == 0 - no need to mask the pointer + const u32 op = *(const u32 *)(Memory::base + list.pc); + const u32 cmd = op >> 24; + const CommandInfo &info = cmdInfo[cmd]; + const u32 diff = op ^ gstate.cmdmem[cmd]; + if (diff == 0) { + if (info.flags & FLAG_EXECUTE) { + downcount = dc; + (this->*info.func)(op, diff); + dc = downcount; + } + } else { + uint64_t flags = info.flags; + if (flags & FLAG_FLUSHBEFOREONCHANGE) { + if (drawEngineCommon_->GetNumDrawCalls()) { + drawEngineCommon_->DispatchFlush(); + } + } + gstate.cmdmem[cmd] = op; + if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) { + downcount = dc; + (this->*info.func)(op, diff); + dc = downcount; + } else { + uint64_t dirty = flags >> 8; + if (dirty) + gstate_c.Dirty(dirty); + } + } + list.pc += 4; + } + downcount = 0; +} + void GPUCommon::BeginFrame() { immCount_ = 0; if (dumpNextFrame_) { @@ -980,7 +1057,6 @@ void GPUCommon::UpdatePC(u32 currentPC, u32 newPC) { } // Exit the runloop and recalculate things. This happens a lot in some games. - // No need to lock, this function is always called under listLock. if (currentList) downcount = currentList->stall == 0 ? 0x0FFFFFFF : (currentList->stall - newPC) / 4; else @@ -1321,8 +1397,9 @@ void GPUCommon::Execute_End(u32 op, u32 diff) { } void GPUCommon::Execute_TexLevel(u32 op, u32 diff) { - if (diff == 0xFFFFFFFF) return; - + // TODO: If you change the rules here, don't forget to update the inner interpreter in Execute_Prim. + if (diff == 0xFFFFFFFF) + return; gstate.texlevel ^= diff; if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0) { Flush(); @@ -1343,37 +1420,216 @@ void GPUCommon::Execute_TexSize0(u32 op, u32 diff) { } } -void GPUCommon::Execute_VertexType(u32 op, u32 diff) { - if (diff) - gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); - if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - if (diff & GE_VTYPE_THROUGH_MASK) - gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); - } +void GPUCommon::Execute_LoadClut(u32 op, u32 diff) { + gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); + textureCache_->LoadClut(gstate.getClutAddress(), gstate.getClutLoadBytes()); } -void GPUCommon::Execute_VertexTypeSkinning(u32 op, u32 diff) { - // Don't flush when weight count changes, unless morph is enabled. - if ((diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) || (op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { +void GPUCommon::Execute_VertexType(u32 op, u32 diff) { + // Don't flush when weight count changes. + if (diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) { // Restore and flush gstate.vertType ^= diff; Flush(); gstate.vertType ^= diff; if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) gstate_c.Dirty(DIRTY_UVSCALEOFFSET); - // In this case, we may be doing weights and morphs. - // Update any bone matrix uniforms so it uses them correctly. - if ((op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { - gstate_c.Dirty(gstate_c.deferredVertTypeDirty); - gstate_c.deferredVertTypeDirty = 0; - } gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); } if (diff & GE_VTYPE_THROUGH_MASK) gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); } + +void GPUCommon::Execute_Prim(u32 op, u32 diff) { + // This drives all drawing. All other state we just buffer up, then we apply it only + // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. + + PROFILE_THIS_SCOPE("execprim"); + + u32 data = op & 0xFFFFFF; + u32 count = data & 0xFFFF; + if (count == 0) + return; + + // Upper bits are ignored. + GEPrimitiveType prim = static_cast((data >> 16) & 7); + SetDrawType(DRAW_PRIM, prim); + + // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. + if (gstate.isAntiAliasEnabled()) { + // Discard AA lines in DOA + if (prim == GE_PRIM_LINE_STRIP) + return; + // Discard AA lines in Summon Night 5 + if ((prim == GE_PRIM_LINES) && gstate.isSkinningEnabled()) + return; + } + + // This also makes skipping drawing very effective. + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); + + if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { + // Rough estimate, not sure what's correct. + cyclesExecuted += EstimatePerVertexCost() * count; + return; + } + + if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { + ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); + return; + } + + void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + void *inds = 0; + u32 vertexType = gstate.vertType; + if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { + u32 indexAddr = gstate_c.indexAddr; + if (!Memory::IsValidAddress(indexAddr)) { + ERROR_LOG_REPORT(G3D, "Bad index address %08x!", indexAddr); + return; + } + inds = Memory::GetPointerUnchecked(indexAddr); + } + +#ifndef MOBILE_DEVICE + if (prim > GE_PRIM_RECTANGLES) { + ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); + } +#endif + + if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { + vertexCost_ = EstimatePerVertexCost(); + } + + int bytesRead = 0; + UpdateUVScaleOffset(); + + uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode()); + drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, &bytesRead); + // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). + // Some games rely on this, they don't bother reloading VADDR and IADDR. + // The VADDR/IADDR registers are NOT updated. + AdvanceVerts(vertexType, count, bytesRead); + int totalVertCount = count; + + // PRIMs are often followed by more PRIMs. Save some work and submit them immediately. + const u32 *src = (const u32 *)Memory::GetPointerUnchecked(currentList->pc + 4); + const u32 *stall = currentList->stall ? (const u32 *)Memory::GetPointerUnchecked(currentList->stall) : 0; + int cmdCount = 0; + + // Optimized submission of sequences of PRIM. Allows us to avoid going through all the mess + // above for each one. This can be expanded to support additional games that intersperse + // PRIM commands with other commands. A special case that might be interesting is that game + // that changes culling mode between each prim, we could just change the triangle winding + // right here to still be able to join draw calls. +#ifndef MOBILE_DEVICE + if (debugRecording_ || host->GPUDebuggingActive()) + goto bail; +#endif + + while (src != stall) { + uint32_t data = *src; + switch (data >> 24) { + case GE_CMD_PRIM: + { + u32 count = data & 0xFFFF; + if (count == 0) { + // Ignore. + break; + } + + GEPrimitiveType newPrim = static_cast((data >> 16) & 7); + // TODO: more efficient updating of verts/inds + verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); + inds = 0; + if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { + inds = Memory::GetPointerUnchecked(gstate_c.indexAddr); + } + + drawEngineCommon_->SubmitPrim(verts, inds, newPrim, count, vertTypeID, &bytesRead); + AdvanceVerts(vertexType, count, bytesRead); + totalVertCount += count; + break; + } + case GE_CMD_VERTEXTYPE: + { + uint32_t diff = data ^ vertexType; + // don't mask upper bits, vertexType is unmasked + if (diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) { + goto bail; + } else { + vertexType = data; + vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode()); + } + break; + } + case GE_CMD_VADDR: + gstate_c.vertexAddr = gstate_c.getRelativeAddress(data & 0x00FFFFFF); + break; + case GE_CMD_OFFSETADDR: + gstate.cmdmem[GE_CMD_OFFSETADDR] = data; + gstate_c.offsetAddr = data << 8; + break; + case GE_CMD_BASE: + gstate.cmdmem[GE_CMD_BASE] = data; + break; + case GE_CMD_NOP: + case GE_CMD_NOP_FF: + break; + case GE_CMD_BONEMATRIXNUMBER: + gstate.cmdmem[GE_CMD_BONEMATRIXNUMBER] = data; + break; + case GE_CMD_TEXSCALEU: + gstate.cmdmem[GE_CMD_TEXSCALEU] = data; + gstate_c.uv.uScale = getFloat24(data); + break; + case GE_CMD_TEXSCALEV: + gstate.cmdmem[GE_CMD_TEXSCALEV] = data; + gstate_c.uv.vScale = getFloat24(data); + break; + case GE_CMD_TEXLEVEL: + // Same Gran Turismo hack from Execute_TexLevel + if ((data & 3) != GE_TEXLEVEL_MODE_AUTO && (0x00FF0000 & data) != 0) { + goto bail; + } + gstate.cmdmem[GE_CMD_TEXLEVEL] = data; + break; + case GE_CMD_CALL: + { + // A bone matrix probably. If not we bail. + const u32 target = gstate_c.getRelativeAddress(data & 0x00FFFFFC); + if ((Memory::ReadUnchecked_U32(target) >> 24) == GE_CMD_BONEMATRIXDATA && + (Memory::ReadUnchecked_U32(target + 11 * 4) >> 24) == GE_CMD_BONEMATRIXDATA && + (Memory::ReadUnchecked_U32(target + 12 * 4) >> 24) == GE_CMD_RET && + (target > currentList->stall || target + 12 * 4 < currentList->stall)) { + FastLoadBoneMatrix(target); + } else { + goto bail; + } + break; + } + + default: + // All other commands might need a flush or something, stop this inner loop. + goto bail; + } + cmdCount++; + src++; + } + +bail: + gstate.cmdmem[GE_CMD_VERTEXTYPE] = vertexType; + // Skip over the commands we just read out manually. + if (cmdCount > 0) { + UpdatePC(currentList->pc, currentList->pc + cmdCount * 4); + currentList->pc += cmdCount * 4; + } + + gpuStats.vertexGPUCycles += vertexCost_ * totalVertCount; + cyclesExecuted += vertexCost_ * totalVertCount; +} + void GPUCommon::Execute_Bezier(u32 op, u32 diff) { drawEngineCommon_->DispatchFlush(); @@ -1402,10 +1658,6 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); @@ -1464,10 +1716,6 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - int sp_ucount = op & 0xFF; int sp_vcount = (op >> 8) & 0xFF; int sp_utype = (op >> 16) & 0x3; @@ -1748,34 +1996,10 @@ void GPUCommon::Execute_BoneMtxNum(u32 op, u32 diff) { } if (fastLoad) { - // If we can't use software skinning, we have to flush and dirty. - if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) { - while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { - const u32 newVal = src[i] << 8; - if (dst[i] != newVal) { - Flush(); - dst[i] = newVal; - } - if (++i >= end) { - break; - } - } - - const unsigned int numPlusCount = (op & 0x7F) + i; - for (unsigned int num = op & 0x7F; num < numPlusCount; num += 12) { - gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12)); - } - } else { - while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { - dst[i] = src[i] << 8; - if (++i >= end) { - break; - } - } - - const unsigned int numPlusCount = (op & 0x7F) + i; - for (unsigned int num = op & 0x7F; num < numPlusCount; num += 12) { - gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); + while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { + dst[i] = src[i] << 8; + if (++i >= end) { + break; } } } @@ -1793,13 +2017,6 @@ void GPUCommon::Execute_BoneMtxData(u32 op, u32 diff) { int num = gstate.boneMatrixNumber & 0x7F; u32 newVal = op << 8; if (num < 96 && newVal != ((const u32 *)gstate.boneMatrix)[num]) { - // Bone matrices should NOT flush when software skinning is enabled! - if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) { - Flush(); - gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12)); - } else { - gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); - } ((u32 *)gstate.boneMatrix)[num] = newVal; } num++; @@ -1878,7 +2095,8 @@ void GPUCommon::FlushImm() { int vtype = GE_VTYPE_POS_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_THROUGH; int bytesRead; - drawEngineCommon_->DispatchSubmitPrim(temp, nullptr, immPrim_, immCount_, vtype, &bytesRead); + uint32_t vertTypeID = GetVertTypeID(vtype, 0); + drawEngineCommon_->DispatchSubmitPrim(temp, nullptr, immPrim_, immCount_, vertTypeID, &bytesRead); drawEngineCommon_->DispatchFlush(); // TOOD: In the future, make a special path for these. // drawEngineCommon_->DispatchSubmitImm(immBuffer_, immCount_); @@ -1939,17 +2157,6 @@ void GPUCommon::Execute_Unknown(u32 op, u32 diff) { void GPUCommon::FastLoadBoneMatrix(u32 target) { const int num = gstate.boneMatrixNumber & 0x7F; const int mtxNum = num / 12; - uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; - if ((num - 12 * mtxNum) != 0) { - uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); - } - - if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) { - Flush(); - gstate_c.Dirty(uniformsToDirty); - } else { - gstate_c.deferredVertTypeDirty |= uniformsToDirty; - } gstate.FastLoadBoneMatrix(target); } @@ -2442,3 +2649,23 @@ bool GPUCommon::DescribeCodePtr(const u8 *ptr, std::string &name) { } return false; } + +bool GPUCommon::FramebufferDirty() { + VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); + if (vfb) { + bool dirty = vfb->dirtyAfterDisplay; + vfb->dirtyAfterDisplay = false; + return dirty; + } + return true; +} + +bool GPUCommon::FramebufferReallyDirty() { + VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); + if (vfb) { + bool dirty = vfb->reallyDirtyAfterDisplay; + vfb->reallyDirtyAfterDisplay = false; + return dirty; + } + return true; +} diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index e73986a9ff..632399d1b8 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -32,7 +32,7 @@ enum DrawType { enum { FLAG_FLUSHBEFORE = 1, FLAG_FLUSHBEFOREONCHANGE = 2, - FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. + FLAG_EXECUTE = 4, FLAG_EXECUTEONCHANGE = 8, FLAG_READS_PC = 16, FLAG_WRITES_PC = 32, @@ -70,6 +70,8 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } + virtual void CheckGPUFeatures() = 0; + bool IsReady() override { return true; } @@ -127,13 +129,15 @@ public: void Execute_End(u32 op, u32 diff); void Execute_VertexType(u32 op, u32 diff); - void Execute_VertexTypeSkinning(u32 op, u32 diff); + void Execute_Prim(u32 op, u32 diff); void Execute_Bezier(u32 op, u32 diff); void Execute_Spline(u32 op, u32 diff); void Execute_BoundingBox(u32 op, u32 diff); void Execute_BlockTransferStart(u32 op, u32 diff); + void Execute_LoadClut(u32 op, u32 diff); + void Execute_TexSize0(u32 op, u32 diff); void Execute_TexLevel(u32 op, u32 diff); @@ -228,9 +232,6 @@ public: const std::list& GetDisplayLists() override { return dlQueue; } - bool DecodeTexture(u8* dest, const GPUgstate &state) override { - return false; - } std::vector GetFramebufferList() override; void ClearShaderCache() override {} void CleanupBeforeUI() override {} @@ -242,8 +243,16 @@ public: return -1; } + bool FramebufferDirty() override; + bool FramebufferReallyDirty() override; + typedef void (GPUCommon::*CmdFunc)(u32 op, u32 diff); + void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override { + primaryInfo = reportingPrimaryInfo_; + fullInfo = reportingFullInfo_; + } + protected: void SetDrawType(DrawType type, GEPrimitiveType prim) { if (type != lastDraw_) { @@ -262,8 +271,8 @@ protected: void BeginFrame() override; - // To avoid virtual calls to PreExecuteOp(). - virtual void FastRunLoop(DisplayList &list) = 0; + virtual void FastRunLoop(DisplayList &list); + void SlowRunLoop(DisplayList &list); void UpdatePC(u32 currentPC, u32 newPC); void UpdateState(GPURunState state); @@ -294,6 +303,13 @@ protected: GraphicsContext *gfxCtx_; Draw::DrawContext *draw_; + struct CommandInfo { + uint64_t flags; + GPUCommon::CmdFunc func; + }; + + static CommandInfo cmdInfo_[256]; + typedef std::list DisplayListQueue; int nextListID; @@ -320,6 +336,8 @@ protected: DrawType lastDraw_; GEPrimitiveType lastPrim_; + int vertexCost_ = 0; + // No idea how big this buffer needs to be. enum { MAX_IMMBUFFER_SIZE = 32, @@ -329,6 +347,9 @@ protected: int immCount_ = 0; GEPrimitiveType immPrim_; + std::string reportingPrimaryInfo_; + std::string reportingFullInfo_; + private: void FlushImm(); // Debug stats. diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index eeaa7c87a6..101f73e14b 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -241,7 +241,6 @@ public: virtual void DumpNextFrame() = 0; virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0; virtual const std::list& GetDisplayLists() = 0; - virtual bool DecodeTexture(u8* dest, const GPUgstate &state) = 0; virtual std::vector GetFramebufferList() = 0; virtual s64 GetListTicks(int listid) = 0; diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index ad71b4ce75..19ae21706d 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -17,7 +17,6 @@ #include "GPU/ge_constants.h" #include "GPU/GPUState.h" -#include "GPU/GLES/ShaderManagerGLES.h" #include "Common/ChunkFile.h" #include "Core/CoreParameter.h" @@ -241,13 +240,6 @@ void GPUgstate::Restore(u32_le *ptr) { } } -bool vertTypeIsSkinningEnabled(u32 vertType) { - if (g_Config.bSoftwareSkinning && ((vertType & GE_VTYPE_MORPHCOUNT_MASK) == 0)) - return false; - else - return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE); -} - struct GPUStateCache_v0 { u32 vertexAddr; u32 indexAddr; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 811f1fa621..8e6a7c8665 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -441,12 +441,6 @@ struct GPUgstate { void Restore(u32_le *ptr); }; -bool vertTypeIsSkinningEnabled(u32 vertType); - -inline int vertTypeGetNumBoneWeights(u32 vertType) { return 1 + ((vertType & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT); } -inline int vertTypeGetWeightMask(u32 vertType) { return vertType & GE_VTYPE_WEIGHT_MASK; } -inline int vertTypeGetTexCoordMask(u32 vertType) { return vertType & GE_VTYPE_TC_MASK; } - // The rest is cached simplified/converted data for fast access. // Does not need to be saved when saving/restoring context. // @@ -559,7 +553,6 @@ struct GPUStateCache { bool allowShaderBlend; float morphWeights[8]; - u32 deferredVertTypeDirty; u32 curTextureWidth; u32 curTextureHeight; diff --git a/GPU/Math3D.h b/GPU/Math3D.h index 081701da6f..ba01d31600 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -821,7 +821,7 @@ typedef Math3D::Vec3 Vec3f; typedef Math3D::Vec3Packed Vec3Packedf; typedef Math3D::Vec4 Vec4f; - +// v and vecOut must point to different memory. inline void Vec3ByMatrix43(float vecOut[3], const float v[3], const float m[12]) { vecOut[0] = v[0] * m[0] + v[1] * m[3] + v[2] * m[6] + m[9]; vecOut[1] = v[0] * m[1] + v[1] * m[4] + v[2] * m[7] + m[10]; diff --git a/GPU/Null/NullGpu.cpp b/GPU/Null/NullGpu.cpp index 2772718ec9..a240840496 100644 --- a/GPU/Null/NullGpu.cpp +++ b/GPU/Null/NullGpu.cpp @@ -29,7 +29,7 @@ class NullDrawEngine : public DrawEngineCommon { public: void DispatchFlush() override { } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override { + void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) override { } }; diff --git a/GPU/Null/NullGpu.h b/GPU/Null/NullGpu.h index 59b920723c..12deca5d41 100644 --- a/GPU/Null/NullGpu.h +++ b/GPU/Null/NullGpu.h @@ -26,6 +26,8 @@ class NullGPU : public GPUCommon { public: NullGPU(); ~NullGPU(); + + void CheckGPUFeatures() override {} void InitClear() override {} void ExecuteOp(u32 op, u32 diff) override; diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index b490659829..39c13a0b71 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -395,10 +395,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); @@ -443,10 +439,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - int sp_ucount = op & 0xFF; int sp_vcount = (op >> 8) & 0xFF; int sp_utype = (op >> 16) & 0x3; diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 7d5750b043..92762a487f 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -52,6 +52,8 @@ class SoftGPU : public GPUCommon { public: SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D); ~SoftGPU(); + + void CheckGPUFeatures() override {} void InitClear() override {} void ExecuteOp(u32 op, u32 diff) override; diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 8f5505aa79..e6bc3fbba0 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -53,8 +53,8 @@ SoftwareDrawEngine::~SoftwareDrawEngine() { void SoftwareDrawEngine::DispatchFlush() { } -void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) { - transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertType, bytesRead, this); +void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) { + transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this); } VertexDecoder *SoftwareDrawEngine::FindVertexDecoder(u32 vtype) { @@ -167,27 +167,6 @@ VertexData TransformUnit::ReadVertex(VertexReader& vreader) vertex.normal = -vertex.normal; } - if (vertTypeIsSkinningEnabled(gstate.vertType) && !gstate.isModeThrough()) { - float W[8] = { 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f }; - vreader.ReadWeights(W); - - Vec3 tmppos(0.f, 0.f, 0.f); - Vec3 tmpnrm(0.f, 0.f, 0.f); - - for (int i = 0; i < vertTypeGetNumBoneWeights(gstate.vertType); ++i) { - Mat3x3 bone(&gstate.boneMatrix[12*i]); - tmppos += (bone * ModelCoords(pos[0], pos[1], pos[2]) + Vec3(gstate.boneMatrix[12*i+9], gstate.boneMatrix[12*i+10], gstate.boneMatrix[12*i+11])) * W[i]; - if (vreader.hasNormal()) - tmpnrm += (bone * vertex.normal) * W[i]; - } - - pos[0] = tmppos.x; - pos[1] = tmppos.y; - pos[2] = tmppos.z; - if (vreader.hasNormal()) - vertex.normal = tmpnrm; - } - if (vreader.hasColor0()) { float col[4]; vreader.ReadColor0(col); diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index cc62294d4a..9002f82a7d 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -58,7 +58,7 @@ void DrawAllocatorVis(UIContext *ui, GPUInterface *gpu) { uint32_t *wideData = (uint32_t *)initData.data(); // Convert to nice colors. If we really wanted to save on memory, we could use a 16-bit texture... - for (int j = 0; j < usage.size(); j++) { + for (size_t j = 0; j < usage.size(); j++) { switch (usage[j]) { case 0: wideData[j] = 0xFF333333; break; case 1: wideData[j] = 0xFF33FF33; break; @@ -81,6 +81,8 @@ void DrawAllocatorVis(UIContext *ui, GPUInterface *gpu) { UI::Drawable white(0xFFFFFFFF); draw->BindTexture(0, tex); + // Cheap black border. + ui->Draw()->Rect(x-2, y-2, w+4, h+4, 0xE0000000); ui->Draw()->Rect(x, y, w, h, 0xFFFFFFFF); ui->Flush(); texturesToDelete.push_back(tex); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index a11e02d27e..a394275262 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -66,8 +66,7 @@ enum { DRAW_BINDING_2ND_TEXTURE = 1, DRAW_BINDING_DYNUBO_BASE = 2, DRAW_BINDING_DYNUBO_LIGHT = 3, - DRAW_BINDING_DYNUBO_BONE = 4, - DRAW_BINDING_TESS_STORAGE_BUF = 5, + DRAW_BINDING_TESS_STORAGE_BUF = 4, }; enum { @@ -95,83 +94,47 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *dra void DrawEngineVulkan::InitDeviceObjects() { // All resources we need for PSP drawing. Usually only bindings 0 and 2-4 are populated. - VkDescriptorSetLayoutBinding bindings[6]; + VkDescriptorSetLayoutBinding bindings[5]{}; bindings[0].descriptorCount = 1; - bindings[0].pImmutableSamplers = nullptr; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; bindings[0].binding = DRAW_BINDING_TEXTURE; bindings[1].descriptorCount = 1; - bindings[1].pImmutableSamplers = nullptr; bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; bindings[1].binding = DRAW_BINDING_2ND_TEXTURE; bindings[2].descriptorCount = 1; - bindings[2].pImmutableSamplers = nullptr; bindings[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[2].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; bindings[2].binding = DRAW_BINDING_DYNUBO_BASE; bindings[3].descriptorCount = 1; - bindings[3].pImmutableSamplers = nullptr; bindings[3].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[3].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; bindings[3].binding = DRAW_BINDING_DYNUBO_LIGHT; - bindings[4].descriptorCount = 1; - bindings[4].pImmutableSamplers = nullptr; - bindings[4].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - bindings[4].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - bindings[4].binding = DRAW_BINDING_DYNUBO_BONE; // Used only for hardware tessellation. - bindings[5].descriptorCount = 1; - bindings[5].pImmutableSamplers = nullptr; - bindings[5].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - bindings[5].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - bindings[5].binding = DRAW_BINDING_TESS_STORAGE_BUF; + bindings[4].descriptorCount = 1; + bindings[4].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + bindings[4].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + bindings[4].binding = DRAW_BINDING_TESS_STORAGE_BUF; VkDevice device = vulkan_->GetDevice(); - VkDescriptorSetLayoutCreateInfo dsl = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + VkDescriptorSetLayoutCreateInfo dsl{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); assert(VK_SUCCESS == res); - VkDescriptorPoolSize dpTypes[3]; - dpTypes[0].descriptorCount = 8192; - dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - dpTypes[1].descriptorCount = 8192 + 4096; // Due to the tess stuff, we need a LOT of these. Most will be empty... - dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - dpTypes[2].descriptorCount = 2048; - dpTypes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - - VkDescriptorPoolCreateInfo dp = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; - dp.pNext = nullptr; - dp.flags = 0; // Don't want to mess around with individually freeing these. - // We zap the whole pool every few frames. - dp.maxSets = 2048; - dp.pPoolSizes = dpTypes; - dp.poolSizeCount = ARRAY_SIZE(dpTypes); - // We are going to use one-shot descriptors in the initial implementation. Might look into caching them // if creating and updating them turns out to be expensive. for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { - // If we run out of memory, try with less descriptors. - for (int tries = 0; tries < 3; ++tries) { - VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frame_[i].descPool); - if (res == VK_SUCCESS) { - break; - } - // Let's try to reduce the counts. - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY); - dpTypes[0].descriptorCount /= 2; - dpTypes[1].descriptorCount /= 2; - } - frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024); + // We now create descriptor pools on demand, so removed from here. + frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 4 * 1024 * 1024); frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024); frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024); } - VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pl.pPushConstantRanges = nullptr; pl.pushConstantRangeCount = 0; pl.setLayoutCount = 1; @@ -180,7 +143,7 @@ void DrawEngineVulkan::InitDeviceObjects() { res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_); assert(VK_SUCCESS == res); - VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; + VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -292,9 +255,7 @@ void DrawEngineVulkan::BeginFrame() { // TODO: How can we make this nicer... ((TessellationDataTransferVulkan *)tessDataTransfer)->SetPushBuffer(frame->pushUBO); - // TODO : Find a better place to do this. if (!nullTexture_) { - ILOG("INIT : Creating null texture"); VkCommandBuffer cmdInit = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); nullTexture_ = new VulkanTexture(vulkan_, textureCache_->GetAllocator()); int w = 8; @@ -326,10 +287,11 @@ void DrawEngineVulkan::BeginFrame() { vertexCache_->BeginNoReset(); - // TODO: Need a better way to keep the number of descriptors under control. - if (--descDecimationCounter_ <= 0 || frame->descSets.size() > 1024) { - vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); + if (--descDecimationCounter_ <= 0) { + if (frame->descPool != VK_NULL_HANDLE) + vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); frame->descSets.Clear(); + frame->descCount = 0; descDecimationCounter_ = DESCRIPTORSET_DECIMATION_INTERVAL; } @@ -368,72 +330,6 @@ void DrawEngineVulkan::EndFrame() { vertexCache_->End(); } -void DrawEngineVulkan::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) { - if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) { - Flush(); - } - - // TODO: Is this the right thing to do? - if (prim == GE_PRIM_KEEP_PREVIOUS) { - prim = prevPrim_ != GE_PRIM_INVALID ? prevPrim_ : GE_PRIM_POINTS; - } else { - prevPrim_ = prim; - } - - SetupVertexDecoder(vertType); - - *bytesRead = vertexCount * dec_->VertexSize(); - if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) - return; - - DeferredDrawCall &dc = drawCalls[numDrawCalls]; - dc.verts = verts; - dc.inds = inds; - dc.vertType = vertType; - dc.indexType = (vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; - dc.prim = prim; - dc.vertexCount = vertexCount; - - if (g_Config.bVertexCache) { - u32 dhash = dcid_; - dhash ^= (u32)(uintptr_t)verts; - dhash = __rotl(dhash, 13); - dhash ^= (u32)(uintptr_t)inds; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertType; - dhash = __rotl(dhash, 13); - dhash ^= (u32)vertexCount; - dhash = __rotl(dhash, 13); - dhash ^= (u32)prim; - dcid_ = dhash; - } - - if (inds) { - GetIndexBounds(inds, vertexCount, vertType, &dc.indexLowerBound, &dc.indexUpperBound); - } else { - dc.indexLowerBound = 0; - dc.indexUpperBound = vertexCount - 1; - } - - uvScale[numDrawCalls] = gstate_c.uv; - - numDrawCalls++; - vertexCountInDrawCalls_ += vertexCount; - - if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) { - DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); - decodeCounter_++; - } - - if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { - // Rendertarget == texture? - if (!g_Config.bDisableSlowFramebufEffects) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - Flush(); - } - } -} - void DrawEngineVulkan::DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf) { u8 *dest = decoded; @@ -449,38 +345,83 @@ void DrawEngineVulkan::SetLineWidth(float lineWidth) { pipelineManager_->SetLineWidth(lineWidth); } -VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess) { +VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) { + // Reallocate this desc pool larger, and "wipe" the cache. We might lose a tiny bit of descriptor set reuse but + // only for this frame. + if (frame.descPool) { + DEBUG_LOG(G3D, "Reallocating desc pool from %d to %d", frame.descPoolSize, newSize); + vulkan_->Delete().QueueDeleteDescriptorPool(frame.descPool); + frame.descSets.Clear(); + frame.descCount = 0; + } + frame.descPoolSize = newSize; + + VkDescriptorPoolSize dpTypes[3]; + dpTypes[0].descriptorCount = frame.descPoolSize * 2; + dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + dpTypes[1].descriptorCount = frame.descPoolSize * 2; // Don't use these for tess anymore, need max two per set. + dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + dpTypes[2].descriptorCount = frame.descPoolSize; + dpTypes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + + VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + dp.flags = 0; // Don't want to mess around with individually freeing these. + // We zap the whole pool every few frames. + dp.maxSets = frame.descPoolSize; + dp.pPoolSizes = dpTypes; + dp.poolSizeCount = ARRAY_SIZE(dpTypes); + + VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frame.descPool); + return res; +} + +VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, bool tess) { DescriptorSetKey key; key.imageView_ = imageView; key.sampler_ = sampler; key.secondaryImageView_ = boundSecondary_; key.base_ = base; key.light_ = light; - key.bone_ = bone; _dbg_assert_(G3D, base != VK_NULL_HANDLE); _dbg_assert_(G3D, light != VK_NULL_HANDLE); - _dbg_assert_(G3D, bone != VK_NULL_HANDLE); - FrameData *frame = &frame_[vulkan_->GetCurFrame()]; + FrameData &frame = frame_[vulkan_->GetCurFrame()]; // See if we already have this descriptor set cached. if (!tess) { // Don't cache descriptors for HW tessellation. - VkDescriptorSet d = frame->descSets.Get(key); + VkDescriptorSet d = frame.descSets.Get(key); if (d != VK_NULL_HANDLE) return d; } + if (!frame.descPool || frame.descPoolSize < frame.descCount + 1) { + VkResult res = RecreateDescriptorPool(frame, frame.descPoolSize * 2); + assert(res == VK_SUCCESS); + } + // Didn't find one in the frame descriptor set cache, let's make a new one. // We wipe the cache on every frame. VkDescriptorSet desc; - VkDescriptorSetAllocateInfo descAlloc = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; + VkDescriptorSetAllocateInfo descAlloc{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descAlloc.pNext = nullptr; descAlloc.pSetLayouts = &descriptorSetLayout_; - descAlloc.descriptorPool = frame->descPool; + descAlloc.descriptorPool = frame.descPool; descAlloc.descriptorSetCount = 1; VkResult result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); + + if (result == VK_ERROR_FRAGMENTED_POOL || result < 0) { + // There seems to have been a spec revision. Here we should apparently recreate the descriptor pool, + // so let's do that. See https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkAllocateDescriptorSets.html + // Fragmentation shouldn't really happen though since we wipe the pool every frame.. + VkResult res = RecreateDescriptorPool(frame, frame.descPoolSize); + _assert_msg_(G3D, res == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to recreate a descriptor pool. sz=%d res=%d", (int)frame.descSets.size(), (int)res); + descAlloc.descriptorPool = frame.descPool; // Need to update this pointer since we have allocated a new one. + result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); + _assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to allocate after recreating a descriptor pool. res=%d", (int)result); + } + // Even in release mode, this is bad. - _assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d res=%d", (int)frame->descSets.size(), (int)result); + _assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d res=%d", (int)frame.descSets.size(), (int)result); // We just don't write to the slots we don't care about. // We need 8 now that we support secondary texture bindings. @@ -489,8 +430,11 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView int n = 0; VkDescriptorImageInfo tex[2]{}; if (imageView) { - // TODO: Also support LAYOUT_GENERAL to be able to texture from framebuffers without transitioning them? +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + tex[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; +#else tex[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +#endif tex[0].imageView = imageView; tex[0].sampler = sampler; writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -504,8 +448,11 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView } if (boundSecondary_) { - // TODO: Also support LAYOUT_GENERAL to be able to texture from framebuffers without transitioning them? +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + tex[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; +#else tex[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +#endif tex[1].imageView = boundSecondary_; tex[1].sampler = samplerSecondary_; writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -544,7 +491,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView } // Uniform buffer objects - VkDescriptorBufferInfo buf[3]{}; + VkDescriptorBufferInfo buf[2]{}; int count = 0; buf[count].buffer = base; buf[count].offset = 0; @@ -554,10 +501,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView buf[count].offset = 0; buf[count].range = sizeof(UB_VS_Lights); count++; - buf[count].buffer = bone; - buf[count].offset = 0; - buf[count].range = sizeof(UB_VS_Bones); - count++; for (int i = 0; i < count; i++) { writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[n].pNext = nullptr; @@ -573,18 +516,17 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView vkUpdateDescriptorSets(vulkan_->GetDevice(), n, writes, 0, nullptr); if (!tess) // Again, avoid caching when HW tessellation. - frame->descSets.Insert(key, desc); + frame.descSets.Insert(key, desc); + frame.descCount++; return desc; } void DrawEngineVulkan::DirtyAllUBOs() { baseUBOOffset = 0; lightUBOOffset = 0; - boneUBOOffset = 0; baseBuf = VK_NULL_HANDLE; lightBuf = VK_NULL_HANDLE; - boneBuf = VK_NULL_HANDLE; - dirtyUniforms_ = DIRTY_BASE_UNIFORMS | DIRTY_LIGHT_UNIFORMS | DIRTY_BONE_UNIFORMS; + dirtyUniforms_ = DIRTY_BASE_UNIFORMS | DIRTY_LIGHT_UNIFORMS; imageView = VK_NULL_HANDLE; sampler = VK_NULL_HANDLE; gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); @@ -640,10 +582,10 @@ void DrawEngineVulkan::DoFlush() { // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. + // Also avoid caching when skinning. VkBuffer vbuf = VK_NULL_HANDLE; VkBuffer ibuf = VK_NULL_HANDLE; - if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) { useCache = false; } @@ -785,8 +727,8 @@ void DrawEngineVulkan::DoFlush() { break; } } else { - if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { - // If software skinning, we've already predecoded into "decoded". So push that content. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) { + // If skinning, we've already predecoded into "decoded". So push that content. VkDeviceSize size = decodedVerts_ * dec_->GetDecVtxFmt().stride; u8 *dest = (u8 *)frame->pushVertex->Push(size, &vbOffset, &vbuf); memcpy(dest, decoded, size); @@ -832,33 +774,37 @@ void DrawEngineVulkan::DoFlush() { Draw::NativeObject object = g_Config.iRenderingMode != 0 ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; VkRenderPass renderPass = (VkRenderPass)draw_->GetNativeObject(object); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, renderPass, pipelineKey_, &dec_->decFmt, vshader, fshader, true); - if (!pipeline) { + if (!pipeline || !pipeline->pipeline) { // Already logged, let's bail out. return; } BindShaderBlendTex(); // This might cause copies so important to do before BindPipeline. renderManager->BindPipeline(pipeline->pipeline); if (pipeline != lastPipeline_) { - if (lastPipeline_ && !lastPipeline_->useBlendConstant && pipeline->useBlendConstant) { + if (lastPipeline_ && !(lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant())) { gstate_c.Dirty(DIRTY_BLEND_STATE); } lastPipeline_ = pipeline; } - ApplyDrawStateLate(renderManager, false, 0, pipeline->useBlendConstant); + ApplyDrawStateLate(renderManager, false, 0, pipeline->UsesBlendConstant()); gstate_c.Clean(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); lastPipeline_ = pipeline; + + // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. + if (fboTexBound_) + gstate_c.Dirty(DIRTY_BLEND_STATE); } lastPrim_ = prim; dirtyUniforms_ |= shaderManager_->UpdateUniforms(); UpdateUBOs(frame); - VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess); + VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, tess); { PROFILE_THIS_SCOPE("renderman_q"); - const uint32_t dynamicUBOOffsets[3] = { - baseUBOOffset, lightUBOOffset, boneUBOOffset, + const uint32_t dynamicUBOOffsets[2] = { + baseUBOOffset, lightUBOOffset, }; int stride = dec_->GetDecVtxFmt().stride; @@ -867,9 +813,9 @@ void DrawEngineVulkan::DoFlush() { if (!ibuf) ibOffset = (uint32_t)frame->pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf); int numInstances = tess ? numPatches : 1; - renderManager->DrawIndexed(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, numInstances, VK_INDEX_TYPE_UINT16); + renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, numInstances, VK_INDEX_TYPE_UINT16); } else { - renderManager->Draw(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, vertexCount); + renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount); } } } else { @@ -932,21 +878,25 @@ void DrawEngineVulkan::DoFlush() { Draw::NativeObject object = g_Config.iRenderingMode != 0 ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; VkRenderPass renderPass = (VkRenderPass)draw_->GetNativeObject(object); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, renderPass, pipelineKey_, &dec_->decFmt, vshader, fshader, false); - if (!pipeline) { + if (!pipeline || !pipeline->pipeline) { // Already logged, let's bail out. return; } BindShaderBlendTex(); // This might cause copies so super important to do before BindPipeline. renderManager->BindPipeline(pipeline->pipeline); if (pipeline != lastPipeline_) { - if (lastPipeline_ && !lastPipeline_->useBlendConstant && pipeline->useBlendConstant) { + if (lastPipeline_ && !lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant()) { gstate_c.Dirty(DIRTY_BLEND_STATE); } lastPipeline_ = pipeline; } - ApplyDrawStateLate(renderManager, result.setStencil, result.stencilValue, pipeline->useBlendConstant); + ApplyDrawStateLate(renderManager, result.setStencil, result.stencilValue, pipeline->UsesBlendConstant()); gstate_c.Clean(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); lastPipeline_ = pipeline; + + // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. + if (fboTexBound_) + gstate_c.Dirty(DIRTY_BLEND_STATE); } lastPrim_ = prim; @@ -955,9 +905,9 @@ void DrawEngineVulkan::DoFlush() { // Even if the first draw is through-mode, make sure we at least have one copy of these uniforms buffered UpdateUBOs(frame); - VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess); - const uint32_t dynamicUBOOffsets[3] = { - baseUBOOffset, lightUBOOffset, boneUBOOffset, + VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, tess); + const uint32_t dynamicUBOOffsets[2] = { + baseUBOOffset, lightUBOOffset, }; PROFILE_THIS_SCOPE("renderman_q"); @@ -967,12 +917,12 @@ void DrawEngineVulkan::DoFlush() { vbOffset = (uint32_t)frame->pushVertex->Push(drawBuffer, maxIndex * sizeof(TransformedVertex), &vbuf); ibOffset = (uint32_t)frame->pushIndex->Push(inds, sizeof(short) * numTrans, &ibuf); VkDeviceSize offsets[1] = { vbOffset }; - renderManager->DrawIndexed(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, numTrans, 1, VK_INDEX_TYPE_UINT16); + renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, numTrans, 1, VK_INDEX_TYPE_UINT16); } else { VkBuffer vbuf; vbOffset = (uint32_t)frame->pushVertex->Push(drawBuffer, numTrans * sizeof(TransformedVertex), &vbuf); VkDeviceSize offsets[1] = { vbOffset }; - renderManager->Draw(pipelineLayout_, ds, 3, dynamicUBOOffsets, vbuf, vbOffset, numTrans); + renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, numTrans); } } else if (result.action == SW_CLEAR) { // Note: we won't get here if the clear is alpha but not color, or color but not alpha. @@ -1024,10 +974,6 @@ void DrawEngineVulkan::UpdateUBOs(FrameData *frame) { lightUBOOffset = shaderManager_->PushLightBuffer(frame->pushUBO, &lightBuf); dirtyUniforms_ &= ~DIRTY_LIGHT_UNIFORMS; } - if ((dirtyUniforms_ & DIRTY_BONE_UNIFORMS) || boneBuf == VK_NULL_HANDLE) { - boneUBOOffset = shaderManager_->PushBoneBuffer(frame->pushUBO, &boneBuf); - dirtyUniforms_ &= ~DIRTY_BONE_UNIFORMS; - } } DrawEngineVulkan::TessellationDataTransferVulkan::TessellationDataTransferVulkan(VulkanContext *vulkan, Draw::DrawContext *draw) diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index c121bf297a..8b58dbb868 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -23,7 +23,7 @@ // * binding 1: Secondary texture sampler for shader blending or depal palettes // * binding 2: Base Uniform Buffer (includes fragment state) // * binding 3: Light uniform buffer -// * binding 4: Bone uniform buffer +// * binding 4: Shader buffer storage for tesselation // // All shaders conform to this layout, so they are all compatible with the same descriptor set. // The format of the various uniform buffers may vary though - vertex shaders that don't skin @@ -122,8 +122,6 @@ public: DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *draw); virtual ~DrawEngineVulkan(); - void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead); - void SetShaderManager(ShaderManagerVulkan *shaderManager) { shaderManager_ = shaderManager; } @@ -157,9 +155,6 @@ public: } void DispatchFlush() override { Flush(); } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override { - SubmitPrim(verts, inds, prim, vertexCount, vertType, bytesRead); - } VkPipelineLayout GetPipelineLayout() const { return pipelineLayout_; @@ -195,11 +190,12 @@ private: void DestroyDeviceObjects(); void DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf); + VkResult RecreateDescriptorPool(FrameData &frame, int newSize); void DoFlush(); void UpdateUBOs(FrameData *frame); - VkDescriptorSet GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess); + VkDescriptorSet GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, bool tess); VulkanContext *vulkan_; Draw::DrawContext *draw_; @@ -223,18 +219,21 @@ private: VkImageView imageView_; VkImageView secondaryImageView_; VkSampler sampler_; - VkBuffer base_, light_, bone_; // All three UBO slots will be set to this. This will usually be identical + VkBuffer base_, light_; // All three UBO slots will be set to this. This will usually be identical // for all draws in a frame, except when the buffer has to grow. }; // We alternate between these. struct FrameData { - FrameData() : descSets(1024) {} + FrameData() : descSets(512) {} - VkDescriptorPool descPool; - VulkanPushBuffer *pushUBO; - VulkanPushBuffer *pushVertex; - VulkanPushBuffer *pushIndex; + VkDescriptorPool descPool = VK_NULL_HANDLE; + int descCount = 0; + int descPoolSize = 256; // We double this before we allocate so we initialize this to half the size we want. + + VulkanPushBuffer *pushUBO = nullptr; + VulkanPushBuffer *pushVertex = nullptr; + VulkanPushBuffer *pushIndex = nullptr; // We do rolling allocation and reset instead of caching across frames. That we might do later. DenseHashMap descSets; @@ -254,8 +253,7 @@ private: uint64_t dirtyUniforms_; uint32_t baseUBOOffset; uint32_t lightUBOOffset; - uint32_t boneUBOOffset; - VkBuffer baseBuf, lightBuf, boneBuf; + VkBuffer baseBuf, lightBuf; VkImageView imageView = VK_NULL_HANDLE; VkSampler sampler = VK_NULL_HANDLE; diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 65b8c4bf71..d55e2de602 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -269,12 +269,13 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer) { if (enableColorTest) { if (colorTestAgainstZero) { // When testing against 0 (common), we can avoid some math. + // Have my doubts that this special case is actually worth it, but whatever. // 0.002 is approximately half of 1.0 / 255.0. if (colorTestFunc == GE_COMP_NOTEQUAL) { - WRITE(p, " if (v.r < 0.002 && v.g < 0.002 && v.b < 0.002) discard;\n"); + WRITE(p, " if (v.r + v.g + v.b < 0.002) discard;\n"); } else if (colorTestFunc != GE_COMP_NEVER) { // Anything else is a test for == 0. - WRITE(p, " if (v.r > 0.002 || v.g > 0.002 || v.b > 0.002) discard;\n"); + WRITE(p, " if (v.r + v.g + v.b > 0.002) discard;\n"); } else { // NEVER has been logged as used by games, although it makes little sense - statically failing. // Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here. diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 10d739642c..197802e4bc 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -89,7 +89,6 @@ protected: void Bind2DShader() override; void BindPostShader(const PostShaderUniforms &uniforms) override; void SetViewport2D(int x, int y, int w, int h) override; - void DisableState() override {} // Used by ReadFramebufferToMemory and later framebuffer block copies void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 5bdd2fc086..30598c92e9 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -16,6 +16,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "base/logging.h" #include "profiler/profiler.h" @@ -29,6 +30,7 @@ #include "Core/Config.h" #include "Core/Reporting.h" #include "Core/System.h" +#include "Core/ELF/ParamSFO.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" @@ -46,31 +48,6 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" -struct VulkanCommandTableEntry { - uint8_t cmd; - uint8_t flags; - uint64_t dirty; - GPU_Vulkan::CmdFunc func; -}; - -GPU_Vulkan::CommandInfo GPU_Vulkan::cmdInfo_[256]; - -// This table gets crunched into a faster form by init. -static const VulkanCommandTableEntry commandTable[] = { - // Changes that dirty the current texture. - { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPUCommon::Execute_TexSize0 }, - - // Changing the vertex type requires us to flush. - { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_VertexType }, - - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Prim }, - { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Bezier }, - { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPUCommon::Execute_Spline }, - - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_LoadClut }, -}; - GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw), vulkan_((VulkanContext *)gfxCtx->GetAPIContext()), @@ -111,46 +88,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - memset(cmdInfo_, 0, sizeof(cmdInfo_)); - - // Import both the global and local command tables, and check for dupes - std::set dupeCheck; - for (size_t i = 0; i < commonCommandTableSize; i++) { - const u8 cmd = commonCommandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); - cmdInfo_[cmd].func = commonCommandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - - for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { - const u8 cmd = commandTable[i].cmd; - if (dupeCheck.find(cmd) != dupeCheck.end()) { - ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); - } else { - dupeCheck.insert(cmd); - } - cmdInfo_[cmd].flags |= (uint64_t)commandTable[i].flags | (commandTable[i].dirty << 8); - cmdInfo_[cmd].func = commandTable[i].func; - if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { - Crash(); - } - } - // Find commands missing from the table. - for (int i = 0; i < 0xEF; i++) { - if (dupeCheck.find((u8)i) == dupeCheck.end()) { - ERROR_LOG(G3D, "Command missing from table: %02x (%i)", i, i); - } - } - - UpdateCmdInfo(); - BuildReportingInfo(); // Update again after init to be sure of any silly driver problems. UpdateVsyncInterval(true); @@ -159,9 +96,66 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) if (vulkan_->GetFeaturesEnabled().wideLines) { drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } + + // Load shader cache. + std::string discID = g_paramSFO.GetDiscID(); + if (discID.size()) { + File::CreateFullPath(GetSysDirectory(DIRECTORY_APP_CACHE)); + shaderCachePath_ = GetSysDirectory(DIRECTORY_APP_CACHE) + "/" + discID + ".vkshadercache"; + shaderCacheLoaded_ = false; + + std::thread th([&] { + LoadCache(shaderCachePath_); + shaderCacheLoaded_ = true; + }); + th.detach(); + } +} + +bool GPU_Vulkan::IsReady() { + return shaderCacheLoaded_; +} + +void GPU_Vulkan::LoadCache(std::string filename) { + PSP_SetLoading("Loading shader cache..."); + // Actually precompiled by IsReady() since we're single-threaded. + FILE *f = File::OpenCFile(filename, "rb"); + if (!f) + return; + + // First compile shaders to SPIR-V, then load the pipeline cache and recreate the pipelines. + // It's when recreating the pipelines that the pipeline cache is useful - in the ideal case, + // it can just memcpy the finished shader binaries out of the pipeline cache file. + bool result = shaderManagerVulkan_->LoadCache(f); + if (result) { + VkRenderPass renderPass = g_Config.iRenderingMode == FB_BUFFERED_MODE ? + (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::FRAMEBUFFER_RENDERPASS) : + (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::BACKBUFFER_RENDERPASS); + result = pipelineManager_->LoadCache(f, false, shaderManagerVulkan_, &drawEngine_, drawEngine_.GetPipelineLayout(), renderPass); + } + fclose(f); + if (!result) { + WARN_LOG(G3D, "Bad Vulkan pipeline cache"); + // Bad cache file for this GPU/Driver/etc. Delete it. + File::Delete(filename); + } else { + INFO_LOG(G3D, "Loaded Vulkan pipeline cache."); + } +} + +void GPU_Vulkan::SaveCache(std::string filename) { + FILE *f = File::OpenCFile(filename, "wb"); + if (!f) + return; + shaderManagerVulkan_->SaveCache(f); + pipelineManager_->SaveCache(f, false, shaderManagerVulkan_); + INFO_LOG(G3D, "Saved Vulkan pipeline cache"); + fclose(f); } GPU_Vulkan::~GPU_Vulkan() { + SaveCache(shaderCachePath_); + // Note: We save the cache in DeviceLost DestroyDeviceObjects(); framebufferManagerVulkan_->DestroyAllFBOs(); vulkan2D_.Shutdown(); @@ -255,7 +249,6 @@ void GPU_Vulkan::CheckGPUFeatures() { void GPU_Vulkan::BeginHostFrame() { drawEngine_.BeginFrame(); - UpdateCmdInfo(); if (resized_) { CheckGPUFeatures(); @@ -405,41 +398,11 @@ void GPU_Vulkan::UpdateVsyncInterval(bool force) { // TODO } -void GPU_Vulkan::UpdateCmdInfo() { - if (g_Config.bSoftwareSkinning) { - cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; - } else { - cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexType; - } -} - void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) { host->GPUNotifyDisplay(framebuf, stride, format); framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format); } -bool GPU_Vulkan::FramebufferDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->dirtyAfterDisplay; - vfb->dirtyAfterDisplay = false; - return dirty; - } - return true; -} - -bool GPU_Vulkan::FramebufferReallyDirty() { - VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB(); - if (vfb) { - bool dirty = vfb->reallyDirtyAfterDisplay; - vfb->reallyDirtyAfterDisplay = false; - return dirty; - } - return true; -} - void GPU_Vulkan::CopyDisplayToOutput() { // Flush anything left over. drawEngine_.Flush(); @@ -451,44 +414,6 @@ void GPU_Vulkan::CopyDisplayToOutput() { gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } -// Maybe should write this in ASM... -void GPU_Vulkan::FastRunLoop(DisplayList &list) { - PROFILE_THIS_SCOPE("gpuloop"); - const CommandInfo *cmdInfo = cmdInfo_; - int dc = downcount; - for (; dc > 0; --dc) { - // We know that display list PCs have the upper nibble == 0 - no need to mask the pointer - const u32 op = *(const u32 *)(Memory::base + list.pc); - const u32 cmd = op >> 24; - const CommandInfo &info = cmdInfo[cmd]; - const u32 diff = op ^ gstate.cmdmem[cmd]; - if (diff == 0) { - if (info.flags & FLAG_EXECUTE) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } - } else { - uint64_t flags = info.flags; - if (flags & FLAG_FLUSHBEFOREONCHANGE) { - drawEngine_.Flush(); - } - gstate.cmdmem[cmd] = op; - if (flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) { - downcount = dc; - (this->*info.func)(op, diff); - dc = downcount; - } else { - uint64_t dirty = flags >> 8; - if (dirty) - gstate_c.Dirty(dirty); - } - } - list.pc += 4; - } - downcount = 0; -} - void GPU_Vulkan::FinishDeferred() { drawEngine_.FinishDeferred(); } @@ -520,85 +445,6 @@ void GPU_Vulkan::ExecuteOp(u32 op, u32 diff) { } } -void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) { - // This drives all drawing. All other state we just buffer up, then we apply it only - // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. - - PROFILE_THIS_SCOPE("execprim"); - - u32 data = op & 0xFFFFFF; - u32 count = data & 0xFFFF; - if (count == 0) - return; - - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - SetDrawType(DRAW_PRIM, prim); - - // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. - if (gstate.isAntiAliasEnabled()) { - // Discard AA lines in DOA - if (prim == GE_PRIM_LINE_STRIP) - return; - // Discard AA lines in Summon Night 5 - if ((prim == GE_PRIM_LINES) && gstate.isSkinningEnabled()) - return; - } - - // This also makes skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); - - if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { - drawEngine_.SetupVertexDecoder(gstate.vertType); // Do we still need to do this? - // Rough estimate, not sure what's correct. - cyclesExecuted += EstimatePerVertexCost() * count; - return; - } - - if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); - return; - } - - void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *inds = 0; - u32 vertexType = gstate.vertType; - if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { - u32 indexAddr = gstate_c.indexAddr; - if (!Memory::IsValidAddress(indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", indexAddr); - return; - } - inds = Memory::GetPointerUnchecked(indexAddr); - } - -#ifndef MOBILE_DEVICE - if (prim > GE_PRIM_RECTANGLES) { - ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); - } -#endif - - if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { - vertexCost_ = EstimatePerVertexCost(); - } - gpuStats.vertexGPUCycles += vertexCost_ * count; - cyclesExecuted += vertexCost_* count; - - int bytesRead = 0; - UpdateUVScaleOffset(); - drawEngine_.SubmitPrim(verts, inds, prim, count, vertexType, &bytesRead); - - // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). - // Some games rely on this, they don't bother reloading VADDR and IADDR. - // The VADDR/IADDR registers are NOT updated. - AdvanceVerts(vertexType, count, bytesRead); -} - -void GPU_Vulkan::Execute_LoadClut(u32 op, u32 diff) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - textureCacheVulkan_->LoadClut(gstate.getClutAddress(), gstate.getClutLoadBytes()); -} - void GPU_Vulkan::InitDeviceObjects() { ILOG("GPU_Vulkan::InitDeviceObjects"); // Initialize framedata @@ -620,6 +466,9 @@ void GPU_Vulkan::DestroyDeviceObjects() { } void GPU_Vulkan::DeviceLost() { + if (!shaderCachePath_.empty()) { + SaveCache(shaderCachePath_); + } DestroyDeviceObjects(); framebufferManagerVulkan_->DeviceLost(); vulkan2D_.DeviceLost(); @@ -637,7 +486,6 @@ void GPU_Vulkan::DeviceRestore() { CheckGPUFeatures(); BuildReportingInfo(); - UpdateCmdInfo(); framebufferManagerVulkan_->DeviceRestore(vulkan_, draw_); vulkan2D_.DeviceRestore(vulkan_); diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index fcbbf4145d..d4ce2151a2 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -36,7 +36,9 @@ public: ~GPU_Vulkan(); // This gets called on startup and when we get back from settings. - void CheckGPUFeatures(); + void CheckGPUFeatures() override; + + bool IsReady() override; // These are where we can reset command buffers etc. void BeginHostFrame() override; @@ -54,25 +56,6 @@ public: void DoState(PointerWrap &p) override; void ClearShaderCache() override; - bool DecodeTexture(u8 *dest, const GPUgstate &state) override { - return false; - } - bool FramebufferDirty() override; - bool FramebufferReallyDirty() override; - - void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) override { - primaryInfo = reportingPrimaryInfo_; - fullInfo = reportingFullInfo_; - } - - typedef void (GPU_Vulkan::*CmdFunc)(u32 op, u32 diff); - struct CommandInfo { - uint64_t flags; - GPU_Vulkan::CmdFunc func; - }; - - void Execute_Prim(u32 op, u32 diff); - void Execute_LoadClut(u32 op, u32 diff); // Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend. std::vector DebugGetShaderIDs(DebugShaderType shader) override; @@ -83,7 +66,6 @@ public: } protected: - void FastRunLoop(DisplayList &list) override; void FinishDeferred() override; private: @@ -96,12 +78,12 @@ private: void CopyDisplayToOutput() override; void Reinitialize() override; inline void UpdateVsyncInterval(bool force); - void UpdateCmdInfo(); void InitDeviceObjects(); void DestroyDeviceObjects(); - static CommandInfo cmdInfo_[256]; + void LoadCache(std::string filename); + void SaveCache(std::string filename); VulkanContext *vulkan_; FramebufferManagerVulkan *framebufferManagerVulkan_; @@ -115,11 +97,6 @@ private: // Manages state and pipeline objects PipelineManagerVulkan *pipelineManager_; - int vertexCost_ = 0; - - std::string reportingPrimaryInfo_; - std::string reportingFullInfo_; - // Simple 2D drawing engine. Vulkan2D vulkan2D_; @@ -128,4 +105,7 @@ private: }; FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]{}; + + std::string shaderCachePath_; + bool shaderCacheLoaded_ = false; }; diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 4dcd4b6235..b28f36d8c5 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "profiler/profiler.h" @@ -8,9 +10,10 @@ #include "GPU/Vulkan/VulkanUtil.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" +#include "GPU/Common/DrawEngineCommon.h" PipelineManagerVulkan::PipelineManagerVulkan(VulkanContext *vulkan) : vulkan_(vulkan), pipelines_(256) { - pipelineCache_ = vulkan->CreatePipelineCache(); + // The pipeline cache is created on demand (or explicitly through Load). } PipelineManagerVulkan::~PipelineManagerVulkan() { @@ -25,7 +28,8 @@ void PipelineManagerVulkan::Clear() { // store the keys. pipelines_.Iterate([&](const VulkanPipelineKey &key, VulkanPipeline *value) { - vulkan_->Delete().QueueDeletePipeline(value->pipeline); + if (value->pipeline) + vulkan_->Delete().QueueDeletePipeline(value->pipeline); delete value; }); @@ -40,7 +44,7 @@ void PipelineManagerVulkan::DeviceLost() { void PipelineManagerVulkan::DeviceRestore(VulkanContext *vulkan) { vulkan_ = vulkan; - pipelineCache_ = vulkan->CreatePipelineCache(); + // The pipeline cache is created on demand. } struct DeclTypeInfo { @@ -80,12 +84,6 @@ static void VertexAttribSetup(VkVertexInputAttributeDescription *attr, int fmt, // as we will only call this code when we need to create a new VkPipeline. static int SetupVertexAttribs(VkVertexInputAttributeDescription attrs[], const DecVtxFormat &decFmt) { int count = 0; - if (decFmt.w0fmt != 0) { - VertexAttribSetup(&attrs[count++], decFmt.w0fmt, decFmt.w0off, PspAttributeLocation::W1); - } - if (decFmt.w1fmt != 0) { - VertexAttribSetup(&attrs[count++], decFmt.w1fmt, decFmt.w1off, PspAttributeLocation::W2); - } if (decFmt.uvfmt != 0) { VertexAttribSetup(&attrs[count++], decFmt.uvfmt, decFmt.uvoff, PspAttributeLocation::TEXCOORD); } @@ -103,7 +101,7 @@ static int SetupVertexAttribs(VkVertexInputAttributeDescription attrs[], const D return count; } -static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[], const DecVtxFormat &decFmt) { +static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[]) { int count = 0; VertexAttribSetup(&attrs[count++], DEC_FLOAT_4, 0, PspAttributeLocation::POSITION); VertexAttribSetup(&attrs[count++], DEC_FLOAT_3, 16, PspAttributeLocation::TEXCOORD); @@ -119,6 +117,7 @@ static bool UsesBlendConstant(int factor) { static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pipelineCache, VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &key, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform, float lineWidth) { + PROFILE_THIS_SCOPE("pipelinebuild"); bool useBlendConstant = false; VkPipelineColorBlendAttachmentState blend0 = {}; @@ -133,7 +132,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip } blend0.colorWriteMask = key.colorWriteMask; - VkPipelineColorBlendStateCreateInfo cbs = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + VkPipelineColorBlendStateCreateInfo cbs{ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbs.flags = 0; cbs.pAttachments = &blend0; cbs.attachmentCount = 1; @@ -143,7 +142,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip else cbs.logicOp = VK_LOGIC_OP_COPY; - VkPipelineDepthStencilStateCreateInfo dss = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + VkPipelineDepthStencilStateCreateInfo dss{ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dss.depthBoundsTestEnable = false; dss.stencilTestEnable = key.stencilTestEnable; if (key.stencilTestEnable) { @@ -175,12 +174,12 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip dynamicStates[numDyn++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; } - VkPipelineDynamicStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + VkPipelineDynamicStateCreateInfo ds{ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; ds.flags = 0; ds.pDynamicStates = dynamicStates; ds.dynamicStateCount = numDyn; - VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rs.flags = 0; rs.depthBiasEnable = false; rs.cullMode = key.cullMode; @@ -190,7 +189,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip rs.polygonMode = VK_POLYGON_MODE_FILL; rs.depthClampEnable = key.depthClampEnable; - VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + VkPipelineMultisampleStateCreateInfo ms{ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; ms.pSampleMask = nullptr; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; @@ -212,10 +211,14 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip if (!ss[0].module || !ss[1].module) { ERROR_LOG(G3D, "Failed creating graphics pipeline - bad shaders"); - return nullptr; + // Create a placeholder to avoid creating over and over if shader compiler broken. + VulkanPipeline *nullPipeline = new VulkanPipeline(); + nullPipeline->pipeline = VK_NULL_HANDLE; + nullPipeline->flags = 0; + return nullPipeline; } - VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + VkPipelineInputAssemblyStateCreateInfo inputAssembly{ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; inputAssembly.flags = 0; inputAssembly.topology = (VkPrimitiveTopology)key.topology; inputAssembly.primitiveRestartEnable = false; @@ -229,7 +232,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip attributeCount = SetupVertexAttribs(attrs, *decFmt); vertexStride = decFmt->stride; } else { - attributeCount = SetupVertexAttribsPretransformed(attrs, *decFmt); + attributeCount = SetupVertexAttribsPretransformed(attrs); vertexStride = 36; } @@ -238,21 +241,21 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip ibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; ibd.stride = vertexStride; - VkPipelineVertexInputStateCreateInfo vis = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + VkPipelineVertexInputStateCreateInfo vis{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; vis.flags = 0; vis.vertexBindingDescriptionCount = 1; vis.pVertexBindingDescriptions = &ibd; vis.vertexAttributeDescriptionCount = attributeCount; vis.pVertexAttributeDescriptions = attrs; - VkPipelineViewportStateCreateInfo views = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + VkPipelineViewportStateCreateInfo views{ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; views.flags = 0; views.viewportCount = 1; views.scissorCount = 1; views.pViewports = nullptr; // dynamic views.pScissors = nullptr; // dynamic - VkGraphicsPipelineCreateInfo pipe = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; + VkGraphicsPipelineCreateInfo pipe{ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipe.flags = 0; pipe.stageCount = 2; pipe.pStages = ss; @@ -280,26 +283,30 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip if (result != VK_SUCCESS) { _assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); - return nullptr; + // Create a placeholder to avoid creating over and over if something is broken. + VulkanPipeline *nullPipeline = new VulkanPipeline(); + nullPipeline->pipeline = VK_NULL_HANDLE; + nullPipeline->flags = 0; + return nullPipeline; } VulkanPipeline *vulkanPipeline = new VulkanPipeline(); vulkanPipeline->pipeline = pipeline; - vulkanPipeline->uniformBlocks = UB_VS_FS_BASE; - vulkanPipeline->useBlendConstant = useBlendConstant; - vulkanPipeline->usesLines = key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; - if (useHwTransform) { - if (vs->HasLights()) { - vulkanPipeline->uniformBlocks |= UB_VS_LIGHTS; - } - if (vs->HasBones()) { - vulkanPipeline->uniformBlocks |= UB_VS_BONES; - } - } + vulkanPipeline->flags = 0; + if (useBlendConstant) + vulkanPipeline->flags |= PIPELINE_FLAG_USES_BLEND_CONSTANT; + if (key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || key.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) + vulkanPipeline->flags |= PIPELINE_FLAG_USES_LINES; return vulkanPipeline; } VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform) { + if (!pipelineCache_) { + VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); + assert(VK_SUCCESS == res); + } + VulkanPipelineKey key{}; _assert_msg_(G3D, renderPass, "Can't create a pipeline with a null renderpass"); @@ -308,20 +315,23 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layo key.useHWTransform = useHwTransform; key.vShader = vs->GetModule(); key.fShader = fs->GetModule(); - key.vtxDecId = useHwTransform ? decFmt->id : 0; + key.vtxFmtId = useHwTransform ? decFmt->id : 0; auto iter = pipelines_.Get(key); if (iter) return iter; - PROFILE_THIS_SCOPE("pipelinebuild"); - VulkanPipeline *pipeline = CreateVulkanPipeline( vulkan_->GetDevice(), pipelineCache_, layout, renderPass, rasterKey, decFmt, vs, fs, useHwTransform, lineWidth_); - // Even if the result is nullptr, insert it so we don't try to create it repeatedly. pipelines_.Insert(key, pipeline); - return pipeline; + + // Don't return placeholder null pipelines. + if (pipeline && pipeline->pipeline) { + return pipeline; + } else { + return nullptr; + } } std::vector PipelineManagerVulkan::DebugGetObjectIDs(DebugShaderType type) { @@ -370,6 +380,25 @@ static const char *const compareOps[8] = { "ALWAYS", }; +static const char *const logicOps[] = { + "CLEAR", + "AND", + "AND_REV", + "COPY", + "AND_INV", + "NOOP", + "XOR", + "OR", + "NOR", + "EQUIV", + "INVERT", + "OR_REV", + "COPY_INV", + "OR_INV", + "NAND", + "SET", +}; + static const char *const stencilOps[8] = { "KEEP", "ZERO", @@ -415,27 +444,31 @@ std::string PipelineManagerVulkan::DebugGetObjectString(std::string id, DebugSha return ""; } + std::string str = pipelineKey.GetDescription(stringType); + return StringFromFormat("%p: %s", iter, str.c_str()); +} + +std::string VulkanPipelineKey::GetDescription(DebugShaderStringType stringType) const { switch (stringType) { case SHADER_STRING_SHORT_DESC: { std::stringstream str; - str << topologies[pipelineKey.raster.topology] << " "; - if (pipelineKey.raster.blendEnable) { - str << "Blend("; - str << "C:" << blendOps[pipelineKey.raster.blendOpColor] << "/" - << blendFactors[pipelineKey.raster.srcColor] << ":" << blendFactors[pipelineKey.raster.destColor] << " "; - if (pipelineKey.raster.blendOpAlpha != VK_BLEND_OP_ADD || - pipelineKey.raster.srcAlpha != VK_BLEND_FACTOR_ONE || - pipelineKey.raster.destAlpha != VK_BLEND_FACTOR_ZERO) { - str << "A:" << blendOps[pipelineKey.raster.blendOpAlpha] << "/" - << blendFactors[pipelineKey.raster.srcColor] << ":" << blendFactors[pipelineKey.raster.destColor] << " "; + str << topologies[raster.topology] << " "; + if (raster.blendEnable) { + str << "Blend(C:" << blendOps[raster.blendOpColor] << "/" + << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; + if (raster.blendOpAlpha != VK_BLEND_OP_ADD || + raster.srcAlpha != VK_BLEND_FACTOR_ONE || + raster.destAlpha != VK_BLEND_FACTOR_ZERO) { + str << "A:" << blendOps[raster.blendOpAlpha] << "/" + << blendFactors[raster.srcColor] << ":" << blendFactors[raster.destColor] << " "; } str << ") "; } - if (pipelineKey.raster.colorWriteMask != 0xF) { + if (raster.colorWriteMask != 0xF) { str << "Mask("; for (int i = 0; i < 4; i++) { - if (pipelineKey.raster.colorWriteMask & (1 << i)) { + if (raster.colorWriteMask & (1 << i)) { str << "RGBA"[i]; } else { str << "_"; @@ -443,37 +476,34 @@ std::string PipelineManagerVulkan::DebugGetObjectString(std::string id, DebugSha } str << ") "; } - if (pipelineKey.raster.depthTestEnable) { + if (raster.depthTestEnable) { str << "Depth("; - if (pipelineKey.raster.depthWriteEnable) + if (raster.depthWriteEnable) str << "W, "; - if (pipelineKey.raster.depthCompareOp) - str << compareOps[pipelineKey.raster.depthCompareOp & 7]; + if (raster.depthCompareOp) + str << compareOps[raster.depthCompareOp & 7]; str << ") "; } - if (pipelineKey.raster.stencilTestEnable) { + if (raster.stencilTestEnable) { str << "Stencil("; - str << compareOps[pipelineKey.raster.stencilCompareOp & 7] << " "; - str << stencilOps[pipelineKey.raster.stencilPassOp & 7] << "/"; - str << stencilOps[pipelineKey.raster.stencilFailOp & 7] << "/"; - str << stencilOps[pipelineKey.raster.stencilDepthFailOp& 7]; + str << compareOps[raster.stencilCompareOp & 7] << " "; + str << stencilOps[raster.stencilPassOp & 7] << "/"; + str << stencilOps[raster.stencilFailOp & 7] << "/"; + str << stencilOps[raster.stencilDepthFailOp& 7]; str << ") "; } - if (pipelineKey.raster.logicOpEnable) { - str << "Logic("; - str << ") "; + if (raster.logicOpEnable) { + str << "Logic(" << logicOps[raster.logicOp & 15] << ") "; } - if (pipelineKey.useHWTransform) { + if (useHWTransform) { str << "HWX "; } - if (pipelineKey.vtxDecId) { - str << "V("; - str << StringFromFormat("%08x", pipelineKey.vtxDecId); // TODO: Format nicer. - str << ") "; + if (vtxFmtId) { + str << "V(" << StringFromFormat("%08x", vtxFmtId) << ") "; // TODO: Format nicer. } else { str << "SWX "; } - return StringFromFormat("%p: %s", iter, str.str().c_str()); + return str.str(); } case SHADER_STRING_SOURCE_CODE: @@ -492,10 +522,163 @@ void PipelineManagerVulkan::SetLineWidth(float lineWidth) { // Wipe all line-drawing pipelines. pipelines_.Iterate([&](const VulkanPipelineKey &key, VulkanPipeline *value) { - if (value->usesLines) { - vulkan_->Delete().QueueDeletePipeline(value->pipeline); + if (value->UsesLines()) { + if (value->pipeline) + vulkan_->Delete().QueueDeletePipeline(value->pipeline); delete value; pipelines_.Remove(key); } }); } + +// For some reason this struct is only defined in the spec, not in the headers. +struct VkPipelineCacheHeader { + uint32_t headerSize; + VkPipelineCacheHeaderVersion version; + uint32_t vendorId; + uint32_t deviceId; + uint8_t uuid[VK_UUID_SIZE]; +}; + +void PipelineManagerVulkan::SaveCache(FILE *file, bool saveRawPipelineCache, ShaderManagerVulkan *shaderManager) { + size_t dataSize = 0; + uint32_t size; + + if (saveRawPipelineCache) { + VkResult result = vkGetPipelineCacheData(vulkan_->GetDevice(), pipelineCache_, &dataSize, nullptr); + uint32_t size = (uint32_t)dataSize; + if (result != VK_SUCCESS) { + size = 0; + fwrite(&size, sizeof(size), 1, file); + return; + } + std::unique_ptr buffer(new uint8_t[dataSize]); + vkGetPipelineCacheData(vulkan_->GetDevice(), pipelineCache_, &dataSize, buffer.get()); + size = (uint32_t)dataSize; + fwrite(&size, sizeof(size), 1, file); + fwrite(buffer.get(), 1, size, file); + NOTICE_LOG(G3D, "Saved Vulkan pipeline cache (%d bytes).", (int)size); + } + + size_t seekPosOnFailure = ftell(file); + + bool failed = false; + int count = 0; + // Since we don't include the full pipeline key, there can be duplicates, + // caused by things like switching from buffered to non-buffered rendering. + // Make sure the set of pipelines we write is "unique". + std::set keys; + + pipelines_.Iterate([&](const VulkanPipelineKey &pkey, VulkanPipeline *value) { + if (failed) + return; + VulkanVertexShader *vshader = shaderManager->GetVertexShaderFromModule(pkey.vShader); + VulkanFragmentShader *fshader = shaderManager->GetFragmentShaderFromModule(pkey.fShader); + if (!vshader || !fshader) { + failed = true; + return; + } + StoredVulkanPipelineKey key{}; + key.raster = pkey.raster; + key.useHWTransform = pkey.useHWTransform; + key.fShaderID = fshader->GetID(); + key.vShaderID = vshader->GetID(); + if (key.useHWTransform) { + // NOTE: This is not a vtype, but a decoded vertex format. + key.vtxFmtId = pkey.vtxFmtId; + } + keys.insert(key); + }); + + // Write the number of pipelines. + size = (uint32_t)keys.size(); + fwrite(&size, sizeof(size), 1, file); + + // Write the pipelines. + for (auto &key : keys) { + fwrite(&key, sizeof(key), 1, file); + } + + if (failed) { + ERROR_LOG(G3D, "Failed to write pipeline cache, some shader was missing"); + // Write a zero in the right place so it doesn't try to load the pipelines next time. + size = 0; + fseek(file, (long)seekPosOnFailure, SEEK_SET); + fwrite(&size, sizeof(size), 1, file); + return; + } + NOTICE_LOG(G3D, "Saved Vulkan pipeline ID cache (%d unique pipelines/%d).", (int)keys.size(), (int)pipelines_.size()); +} + +bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, DrawEngineCommon *drawEngine, VkPipelineLayout layout, VkRenderPass renderPass) { + uint32_t size = 0; + if (loadRawPipelineCache) { + fread(&size, sizeof(size), 1, file); + if (!size) { + WARN_LOG(G3D, "Zero-sized Vulkan pipeline cache."); + return true; + } + std::unique_ptr buffer(new uint8_t[size]); + fread(buffer.get(), 1, size, file); + // Verify header. + VkPipelineCacheHeader *header = (VkPipelineCacheHeader *)buffer.get(); + if (header->version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) { + // Bad header, don't do anything. + WARN_LOG(G3D, "Bad Vulkan pipeline cache header - ignoring"); + return false; + } + if (0 != memcmp(header->uuid, vulkan_->GetPhysicalDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE)) { + // Wrong hardware/driver/etc. + WARN_LOG(G3D, "Bad Vulkan pipeline cache UUID - ignoring"); + return false; + } + + VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + pc.pInitialData = buffer.get(); + pc.initialDataSize = size; + pc.flags = 0; + VkPipelineCache cache; + VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &cache); + if (res != VK_SUCCESS) { + return false; + } + if (!pipelineCache_) { + pipelineCache_ = cache; + } else { + vkMergePipelineCaches(vulkan_->GetDevice(), pipelineCache_, 1, &cache); + } + NOTICE_LOG(G3D, "Loaded Vulkan pipeline cache (%d bytes).", (int)size); + } else { + if (!pipelineCache_) { + VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); + } + } + + // Read the number of pipelines. + fread(&size, sizeof(size), 1, file); + + NOTICE_LOG(G3D, "Creating %d pipelines...", size); + bool failed = false; + for (uint32_t i = 0; i < size; i++) { + if (failed) { + continue; + } + StoredVulkanPipelineKey key; + fread(&key, sizeof(key), 1, file); + VulkanVertexShader *vs = shaderManager->GetVertexShaderFromID(key.vShaderID); + VulkanFragmentShader *fs = shaderManager->GetFragmentShaderFromID(key.fShaderID); + if (!vs || !fs) { + failed = true; + ERROR_LOG(G3D, "Failed to find vs or fs in of pipeline %d in cache", (int)i); + continue; + } + DecVtxFormat fmt; + fmt.InitializeFromID(key.vtxFmtId); + GetOrCreatePipeline(layout, renderPass, key.raster, + key.useHWTransform ? &fmt : 0, + vs, fs, key.useHWTransform); + } + NOTICE_LOG(G3D, "Recreated Vulkan pipeline cache (%d pipelines).", (int)size); + return true; +} diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index 8463033784..1ef673b9b7 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -17,6 +17,7 @@ #pragma once +#include #include "Common/Hashmaps.h" #include "GPU/Common/VertexDecoderCommon.h" @@ -42,7 +43,7 @@ struct VulkanPipelineKey { VkRenderPass renderPass; VkShaderModule vShader; VkShaderModule fShader; - uint32_t vtxDecId; + uint32_t vtxFmtId; bool useHWTransform; void ToString(std::string *str) const { @@ -52,25 +53,42 @@ struct VulkanPipelineKey { void FromString(const std::string &str) { memcpy(this, &str[0], sizeof(*this)); } + std::string GetDescription(DebugShaderStringType stringType) const; }; -enum { - UB_VS_FS_BASE = (1 << 0), - UB_VS_BONES = (1 << 1), - UB_VS_LIGHTS = (1 << 2), +struct StoredVulkanPipelineKey { + VulkanPipelineRasterStateKey raster; + VShaderID vShaderID; + FShaderID fShaderID; + uint32_t vtxFmtId; + bool useHWTransform; + + // For std::set. Better zero-initialize the struct properly for this to work. + bool operator < (const StoredVulkanPipelineKey &other) const { + return memcmp(this, &other, sizeof(*this)) < 0; + } +}; + +enum PipelineFlags { + PIPELINE_FLAG_USES_LINES = (1 << 2), + PIPELINE_FLAG_USES_BLEND_CONSTANT = (1 << 3), }; // Simply wraps a Vulkan pipeline, providing some metadata. struct VulkanPipeline { VkPipeline pipeline; - int uniformBlocks; // UB_ enum above. - bool useBlendConstant; - bool usesLines; + int flags; // PipelineFlags enum above. + + // Convenience. + bool UsesBlendConstant() const { return (flags & PIPELINE_FLAG_USES_BLEND_CONSTANT) != 0; } + bool UsesLines() const { return (flags & PIPELINE_FLAG_USES_LINES) != 0; } }; class VulkanContext; class VulkanVertexShader; class VulkanFragmentShader; +class ShaderManagerVulkan; +class DrawEngineCommon; class PipelineManagerVulkan { public: @@ -90,9 +108,13 @@ public: std::string DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType); std::vector DebugGetObjectIDs(DebugShaderType type); + // Saves data for faster creation next time. + void SaveCache(FILE *file, bool saveRawPipelineCache, ShaderManagerVulkan *shaderManager); + bool LoadCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, DrawEngineCommon *drawEngine, VkPipelineLayout layout, VkRenderPass renderPass); + private: DenseHashMap pipelines_; - VkPipelineCache pipelineCache_; + VkPipelineCache pipelineCache_ = VK_NULL_HANDLE; VulkanContext *vulkan_; float lineWidth_ = 1.0f; }; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index d830b1acb1..8066e96076 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -41,8 +41,8 @@ #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" #include "GPU/Vulkan/VertexShaderGeneratorVulkan.h" -VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, const char *code, bool useHWTransform) - : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(0) { +VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, const char *code) + : vulkan_(vulkan), id_(id), failed_(false), module_(0) { PROFILE_THIS_SCOPE("shadercomp"); source_ = code; @@ -99,8 +99,8 @@ std::string VulkanFragmentShader::GetShaderString(DebugShaderStringType type) co } } -VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting) - : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(VK_NULL_HANDLE), usesLighting_(usesLighting) { +VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, bool useHWTransform) + : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(VK_NULL_HANDLE) { PROFILE_THIS_SCOPE("shadercomp"); source_ = code; std::string errorMessage; @@ -159,11 +159,9 @@ ShaderManagerVulkan::ShaderManagerVulkan(VulkanContext *vulkan) uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment; memset(&ub_base, 0, sizeof(ub_base)); memset(&ub_lights, 0, sizeof(ub_lights)); - memset(&ub_bones, 0, sizeof(ub_bones)); ILOG("sizeof(ub_base): %d", (int)sizeof(ub_base)); ILOG("sizeof(ub_lights): %d", (int)sizeof(ub_lights)); - ILOG("sizeof(ub_bones): %d", (int)sizeof(ub_bones)); } ShaderManagerVulkan::~ShaderManagerVulkan() { @@ -216,8 +214,6 @@ uint64_t ShaderManagerVulkan::UpdateUniforms() { BaseUpdateUniforms(&ub_base, dirty, false); if (dirty & DIRTY_LIGHT_UNIFORMS) LightUpdateUniforms(&ub_lights, dirty); - if (dirty & DIRTY_BONE_UNIFORMS) - BoneUpdateUniforms(&ub_bones, dirty); } gstate_c.CleanUniforms(); return dirty; @@ -257,9 +253,8 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader VulkanVertexShader *vs = vsCache_.Get(VSID); if (!vs) { // Vertex shader not in cache. Let's compile it. - bool usesLighting; - GenerateVulkanGLSLVertexShader(VSID, codeBuffer_, &usesLighting); - vs = new VulkanVertexShader(vulkan_, VSID, codeBuffer_, vertType, useHWTransform, usesLighting); + GenerateVulkanGLSLVertexShader(VSID, codeBuffer_); + vs = new VulkanVertexShader(vulkan_, VSID, codeBuffer_, useHWTransform); vsCache_.Insert(VSID, vs); } lastVSID_ = VSID; @@ -268,7 +263,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader if (!fs) { // Fragment shader not in cache. Let's compile it. GenerateVulkanGLSLFragmentShader(FSID, codeBuffer_); - fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_, useHWTransform); + fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_); fsCache_.Insert(FSID, fs); } @@ -328,3 +323,88 @@ std::string ShaderManagerVulkan::DebugGetShaderString(std::string id, DebugShade return "N/A"; } } + +VulkanVertexShader *ShaderManagerVulkan::GetVertexShaderFromModule(VkShaderModule module) { + VulkanVertexShader *vs = nullptr; + vsCache_.Iterate([&](const VShaderID &id, VulkanVertexShader *shader) { + if (shader->GetModule() == module) + vs = shader; + }); + return vs; +} + +VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderModule module) { + VulkanFragmentShader *fs = nullptr; + fsCache_.Iterate([&](const FShaderID &id, VulkanFragmentShader *shader) { + if (shader->GetModule() == module) + fs = shader; + }); + return fs; +} + +// Shader cache. +// +// We simply store the IDs of the shaders used during gameplay. On next startup of +// the same game, we simply compile all the shaders from the start, so we don't have to +// compile them on the fly later. We also store the Vulkan pipeline cache, so if it contains +// pipelines compiled from SPIR-V matching these shaders, pipeline creation will be practically +// instantaneous. + +#define CACHE_HEADER_MAGIC 0xff51f420 +#define CACHE_VERSION 6 +struct VulkanCacheHeader { + uint32_t magic; + uint32_t version; + uint32_t featureFlags; + uint32_t reserved; + int numVertexShaders; + int numFragmentShaders; +}; + +bool ShaderManagerVulkan::LoadCache(FILE *f) { + VulkanCacheHeader header{}; + fread(&header, sizeof(header), 1, f); + if (header.magic != CACHE_HEADER_MAGIC) + return false; + if (header.version != CACHE_VERSION) + return false; + if (header.featureFlags != gstate_c.featureFlags) + return false; + + for (int i = 0; i < header.numVertexShaders; i++) { + VShaderID id; + fread(&id, sizeof(id), 1, f); + bool useHWTransform = id.Bit(VS_BIT_USE_HW_TRANSFORM); + GenerateVulkanGLSLVertexShader(id, codeBuffer_); + VulkanVertexShader *vs = new VulkanVertexShader(vulkan_, id, codeBuffer_, useHWTransform); + vsCache_.Insert(id, vs); + } + for (int i = 0; i < header.numFragmentShaders; i++) { + FShaderID id; + fread(&id, sizeof(id), 1, f); + GenerateVulkanGLSLFragmentShader(id, codeBuffer_); + VulkanFragmentShader *fs = new VulkanFragmentShader(vulkan_, id, codeBuffer_); + fsCache_.Insert(id, fs); + } + + NOTICE_LOG(G3D, "Loaded %d vertex and %d fragment shaders", header.numVertexShaders, header.numFragmentShaders); + return true; +} + +void ShaderManagerVulkan::SaveCache(FILE *f) { + VulkanCacheHeader header{}; + header.magic = CACHE_HEADER_MAGIC; + header.version = CACHE_VERSION; + header.featureFlags = gstate_c.featureFlags; + header.reserved = 0; + header.numVertexShaders = (int)vsCache_.size(); + header.numFragmentShaders = (int)fsCache_.size(); + fwrite(&header, sizeof(header), 1, f); + vsCache_.Iterate([&](const VShaderID &id, VulkanVertexShader *vs) { + fwrite(&id, sizeof(id), 1, f); + }); + fsCache_.Iterate([&](const FShaderID &id, VulkanFragmentShader *fs) { + fwrite(&id, sizeof(id), 1, f); + }); + NOTICE_LOG(G3D, "Saved %d vertex and %d fragment shaders", header.numVertexShaders, header.numFragmentShaders); +} diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 0078b5cba5..281d4768e0 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -17,6 +17,8 @@ #pragma once +#include + #include "base/basictypes.h" #include "Common/Hashmaps.h" #include "Common/Vulkan/VulkanMemory.h" @@ -33,16 +35,16 @@ class VulkanPushBuffer; class VulkanFragmentShader { public: - VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, const char *code, bool useHWTransform); + VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, const char *code); ~VulkanFragmentShader(); const std::string &source() const { return source_; } bool Failed() const { return failed_; } - bool UseHWTransform() const { return useHWTransform_; } std::string GetShaderString(DebugShaderStringType type) const; VkShaderModule GetModule() const { return module_; } + const FShaderID &GetID() { return id_; } protected: VkShaderModule module_; @@ -50,28 +52,22 @@ protected: VulkanContext *vulkan_; std::string source_; bool failed_; - bool useHWTransform_; FShaderID id_; }; class VulkanVertexShader { public: - VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, int vertType, bool useHWTransform, bool usesLighting); + VulkanVertexShader(VulkanContext *vulkan, VShaderID id, const char *code, bool useHWTransform); ~VulkanVertexShader(); const std::string &source() const { return source_; } bool Failed() const { return failed_; } bool UseHWTransform() const { return useHWTransform_; } - bool HasBones() const { - return id_.Bit(VS_BIT_ENABLE_BONES); - } - bool HasLights() const { - return usesLighting_; - } std::string GetShaderString(DebugShaderStringType type) const; VkShaderModule GetModule() const { return module_; } + const VShaderID &GetID() { return id_; } protected: VkShaderModule module_; @@ -80,7 +76,6 @@ protected: std::string source_; bool failed_; bool useHWTransform_; - bool usesLighting_; VShaderID id_; }; @@ -101,6 +96,12 @@ public: int GetNumVertexShaders() const { return (int)vsCache_.size(); } int GetNumFragmentShaders() const { return (int)fsCache_.size(); } + // Used for saving/loading the cache. Don't need to be particularly fast. + VulkanVertexShader *GetVertexShaderFromID(VShaderID id) { return vsCache_.Get(id); } + VulkanFragmentShader *GetFragmentShaderFromID(FShaderID id) { return fsCache_.Get(id); } + VulkanVertexShader *GetVertexShaderFromModule(VkShaderModule module); + VulkanFragmentShader *GetFragmentShaderFromModule(VkShaderModule module); + std::vector DebugGetShaderIDs(DebugShaderType type); std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType); @@ -110,7 +111,6 @@ public: // Applies dirty changes and copies the buffer. bool IsBaseDirty() { return true; } bool IsLightDirty() { return true; } - bool IsBoneDirty() { return true; } uint32_t PushBaseBuffer(VulkanPushBuffer *dest, VkBuffer *buf) { return dest->PushAligned(&ub_base, sizeof(ub_base), uboAlignment_, buf); @@ -118,10 +118,9 @@ public: uint32_t PushLightBuffer(VulkanPushBuffer *dest, VkBuffer *buf) { return dest->PushAligned(&ub_lights, sizeof(ub_lights), uboAlignment_, buf); } - // TODO: Only push half the bone buffer if we only have four bones. - uint32_t PushBoneBuffer(VulkanPushBuffer *dest, VkBuffer *buf) { - return dest->PushAligned(&ub_bones, sizeof(ub_bones), uboAlignment_, buf); - } + + bool LoadCache(FILE *f); + void SaveCache(FILE *f); private: void Clear(); @@ -140,7 +139,6 @@ private: // Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time. UB_VS_FS_Base ub_base; UB_VS_Lights ub_lights; - UB_VS_Bones ub_bones; VulkanFragmentShader *lastFShader_; VulkanVertexShader *lastVShader_; diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 8ee4666583..febe32c61c 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -38,11 +38,15 @@ layout (location = 0) in vec2 v_texcoord0; layout (location = 0) out vec4 fragColor0; void main() { - vec4 index = texture(tex, v_texcoord0); - int indexBits = int(floor(index.a * 255.99)) & 0xFF; - if ((indexBits & u_stencilValue) == 0) - discard; - fragColor0 = index.aaaa; + if (u_stencilValue == 0) { + fragColor0 = vec4(0.0); + } else { + vec4 index = texture(tex, v_texcoord0); + int indexBits = int(floor(index.a * 255.99)) & 0xFF; + if ((indexBits & u_stencilValue) == 0) + discard; + fragColor0 = index.aaaa; + } } )"; @@ -116,18 +120,6 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - if (usedBits == 0) { - if (skipZero) { - // Common when creating buffers, it's already 0. We're done. - return false; - } - - // TODO: Find a nice way to clear alpha here too. - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); - return true; - } - shaderManagerVulkan_->DirtyLastShader(); textureCacheVulkan_->ForgetLastTexture(); @@ -150,26 +142,34 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip VkDescriptorSet descSet = vulkan2D_->GetDescriptorSet(overrideImageView_, nearestSampler_, VK_NULL_HANDLE, VK_NULL_HANDLE); + // Note: Even with skipZero, we don't necessarily start framebuffers at 0 in Vulkan. Clear anyway. + // Not an actual clear, because we need to draw to alpha only as well. + uint32_t value = 0; + renderManager->PushConstants(vulkan2D_->GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4, &value); + renderManager->SetStencilParams(0xFF, 0xFF, 0x00); + renderManager->Draw(vulkan2D_->GetPipelineLayout(), descSet, 0, nullptr, VK_NULL_HANDLE, 0, 3); // full screen triangle + for (int i = 1; i < values; i += i) { if (!(usedBits & i)) { // It's already zero, let's skip it. continue; } - // These feel a little backwards : Mask is the bits that are going to be written, while value - // is the "mask" that will be tested against. - uint8_t mask = 0; + + // These are the stencil bits that will be written. We discard when the bit doesn't match. + uint8_t writeMask = 0; + // This is the value to test the texture alpha against in the shader. uint32_t value = 0; if (dstBuffer->format == GE_FORMAT_4444) { - mask = i | (i << 4); + writeMask = i | (i << 4); value = i * 16; } else if (dstBuffer->format == GE_FORMAT_5551) { - mask = 0xFF; + writeMask = 0xFF; value = i * 128; } else { - mask = i; + writeMask = i; value = i; } - renderManager->SetStencilParams(mask, 0xFF, 0xFF); + renderManager->SetStencilParams(writeMask, 0xFF, 0xFF); // Need to specify both VERTEX and FRAGMENT bits here since that's what we set up in the pipeline layout, and we need // that for the post shaders. There's probably not really a cost to this. renderManager->PushConstants(vulkan2D_->GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4, &value); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index c3ccc94a1c..0af59d8956 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -789,16 +789,18 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt } bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { - ApplyTexture(); SetTexture(false); if (!nextTexture_) return false; + // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. + TexCacheEntry *entry = nextTexture_; + ApplyTexture(); + // TODO: Centralize? - if (nextTexture_->framebuffer) { - VirtualFramebuffer *vfb = nextTexture_->framebuffer; - bool flipY = GetGPUBackend() == GPUBackend::OPENGL && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, flipY); + if (entry->framebuffer) { + VirtualFramebuffer *vfb = entry->framebuffer; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. @@ -808,9 +810,9 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve return retval; } - if (!nextTexture_->vkTex || !nextTexture_->vkTex->texture_) + if (!entry->vkTex || !entry->vkTex->texture_) return false; - VulkanTexture *texture = nextTexture_->vkTex->texture_; + VulkanTexture *texture = entry->vkTex->texture_; VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); GPUDebugBufferFormat bufferFormat; diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index aa457ede94..ef3d8f3330 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -51,18 +51,6 @@ static const char *vulkan_glsl_preamble = #undef WRITE #define WRITE p+=sprintf -static const char * const boneWeightDecl[9] = { - "#ERROR#", - "layout(location = 3) in float w1;\n", - "layout(location = 3) in vec2 w1;\n", - "layout(location = 3) in vec3 w1;\n", - "layout(location = 3) in vec4 w1;\n", - "layout(location = 3) in vec4 w1;\nlayout(location = 4) in float w2;\n", - "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec2 w2;\n", - "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec3 w2;\n", - "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec4 w2;\n", -}; - enum DoLightComputation { LIGHT_OFF, LIGHT_SHADE, @@ -101,7 +89,7 @@ static void WriteGuardBand(char *&p) { // TODO: Skip all this if we can actually get a 16-bit depth buffer along with stencil, which // is a bit of a rare configuration, although quite common on mobile. -bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *usesLighting) { +bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { char *p = buffer; WRITE(p, "%s", vulkan_glsl_preamble); @@ -130,7 +118,6 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use bool flipNormal = id.Bit(VS_BIT_NORM_REVERSE); int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); - bool enableBones = id.Bit(VS_BIT_ENABLE_BONES); bool enableLighting = id.Bit(VS_BIT_LIGHTING_ENABLE); int matUpdate = id.Bits(VS_BIT_MATERIAL_UPDATE, 3); @@ -140,16 +127,10 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use bool hasTexcoordTess = id.Bit(VS_BIT_HAS_TEXCOORD_TESS); bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS); - // The uniforms are passed in as three "clumps" that may or may not be present. - // We will memcpy the parts into place in a big buffer so we can be quite dynamic about what parts - // are present and what parts aren't, but we will not be ultra detailed about it. - *usesLighting = enableLighting || doShadeMapping; WRITE(p, "\n"); WRITE(p, "layout (std140, set = 0, binding = 2) uniform baseVars {\n%s} base;\n", ub_baseStr); if (enableLighting || doShadeMapping) WRITE(p, "layout (std140, set = 0, binding = 3) uniform lightVars {\n%s} light;\n", ub_vs_lightsStr); - if (enableBones) - WRITE(p, "layout (std140, set = 0, binding = 4) uniform boneVars {\n%s} bone;\n", ub_vs_bonesStr); const char *shading = doFlatShading ? "flat " : ""; @@ -165,13 +146,6 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use } } - int numBoneWeights = 0; - int boneWeightScale = id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2); - if (enableBones) { - numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3); - WRITE(p, "%s", boneWeightDecl[numBoneWeights]); - } - if (useHWTransform) WRITE(p, "layout (location = %d) in vec3 position;\n", (int)PspAttributeLocation::POSITION); else @@ -229,7 +203,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use WRITE(p, " vec4 uv;\n"); WRITE(p, " vec4 color;\n"); WRITE(p, "};"); - WRITE(p, "layout (std430, set = 0, binding = 5) buffer s_tess_data {\n"); + WRITE(p, "layout (std430, set = 0, binding = 4) buffer s_tess_data {\n"); WRITE(p, " TessData data[];"); WRITE(p, "} tess_data;"); @@ -340,140 +314,109 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use WRITE(p, " gl_Position = outPos;\n"); } else { // Step 1: World Transform / Skinning - if (!enableBones) { - if (doBezier || doSpline) { - WRITE(p, " vec3 _pos[16];\n"); - WRITE(p, " vec2 _tex[16];\n"); - WRITE(p, " vec4 _col[16];\n"); - WRITE(p, " int num_patches_u = %s;\n", doBezier ? "(base.spline_count_u - 1) / 3" : "base.spline_count_u - 3"); - WRITE(p, " int u = int(mod(gl_InstanceIndex, num_patches_u));\n"); - WRITE(p, " int v = gl_InstanceIndex / num_patches_u;\n"); - WRITE(p, " ivec2 patch_pos = ivec2(u, v);\n"); - WRITE(p, " for (int i = 0; i < 4; i++) {\n"); - WRITE(p, " for (int j = 0; j < 4; j++) {\n"); - WRITE(p, " int idx = (i + v%s) * base.spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : ""); - WRITE(p, " _pos[i * 4 + j] = tess_data.data[idx].pos.xyz;\n"); - if (doTexture && hasTexcoord && hasTexcoordTess) - WRITE(p, " _tex[i * 4 + j] = tess_data.data[idx].uv.xy;\n"); - if (hasColor && hasColorTess) - WRITE(p, " _col[i * 4 + j] = tess_data.data[idx].color;\n"); - WRITE(p, " }\n"); - WRITE(p, " }\n"); - WRITE(p, " vec2 tess_pos = position.xy;\n"); - WRITE(p, " vec2 weights[4];\n"); - if (doBezier) { - // Bernstein 3D - WRITE(p, " weights[0] = (1 - tess_pos) * (1 - tess_pos) * (1 - tess_pos);\n"); - WRITE(p, " weights[1] = 3 * tess_pos * (1 - tess_pos) * (1 - tess_pos);\n"); - WRITE(p, " weights[2] = 3 * tess_pos * tess_pos * (1 - tess_pos);\n"); - WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); - } else { // Spline - WRITE(p, " ivec2 spline_num_patches = ivec2(base.spline_count_u - 3, base.spline_count_v - 3);\n"); - WRITE(p, " ivec2 spline_type = ivec2(base.spline_type_u, base.spline_type_v);\n"); - WRITE(p, " vec2 knots[6];\n"); - WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); - WRITE(p, " spline_weight(tess_pos + patch_pos, knots, weights);\n"); - } - WRITE(p, " vec3 pos = tess_sample(_pos, weights);\n"); - if (doTexture && hasTexcoord) { - if (hasTexcoordTess) - WRITE(p, " vec2 tex = tess_sample(_tex, weights);\n"); - else - WRITE(p, " vec2 tex = tess_pos + patch_pos;\n"); - } - if (hasColor) { - if (hasColorTess) - WRITE(p, " vec4 col = tess_sample(_col, weights);\n"); - else - WRITE(p, " vec4 col = tess_data.data[0].color;\n"); - } - if (hasNormal) { - // Curved surface is probably always need to compute normal(not sampling from control points) - if (doBezier) { - // Bernstein derivative - WRITE(p, " vec2 bernderiv[4];\n"); - WRITE(p, " bernderiv[0] = -3 * (tess_pos - 1) * (tess_pos - 1); \n"); - WRITE(p, " bernderiv[1] = 9 * tess_pos * tess_pos - 12 * tess_pos + 3; \n"); - WRITE(p, " bernderiv[2] = 3 * (2 - 3 * tess_pos) * tess_pos; \n"); - WRITE(p, " bernderiv[3] = 3 * tess_pos * tess_pos; \n"); - - WRITE(p, " vec2 bernderiv_u[4];\n"); - WRITE(p, " vec2 bernderiv_v[4];\n"); - WRITE(p, " for (int i = 0; i < 4; i++) {\n"); - WRITE(p, " bernderiv_u[i] = vec2(bernderiv[i].x, weights[i].y);\n"); - WRITE(p, " bernderiv_v[i] = vec2(weights[i].x, bernderiv[i].y);\n"); - WRITE(p, " }\n"); - - WRITE(p, " vec3 du = tess_sample(_pos, bernderiv_u);\n"); - WRITE(p, " vec3 dv = tess_sample(_pos, bernderiv_v);\n"); - } else { // Spline - WRITE(p, " vec2 tess_next_u = vec2(normal.x, 0);\n"); - WRITE(p, " vec2 tess_next_v = vec2(0, normal.y);\n"); - // Right - WRITE(p, " vec2 tess_pos_r = tess_pos + tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_r + patch_pos, knots, weights);\n"); - WRITE(p, " vec3 pos_r = tess_sample(_pos, weights);\n"); - // Left - WRITE(p, " vec2 tess_pos_l = tess_pos - tess_next_u;\n"); - WRITE(p, " spline_weight(tess_pos_l + patch_pos, knots, weights);\n"); - WRITE(p, " vec3 pos_l = tess_sample(_pos, weights);\n"); - // Down - WRITE(p, " vec2 tess_pos_d = tess_pos + tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_d + patch_pos, knots, weights);\n"); - WRITE(p, " vec3 pos_d = tess_sample(_pos, weights);\n"); - // Up - WRITE(p, " vec2 tess_pos_u = tess_pos - tess_next_v;\n"); - WRITE(p, " spline_weight(tess_pos_u + patch_pos, knots, weights);\n"); - WRITE(p, " vec3 pos_u = tess_sample(_pos, weights);\n"); - - WRITE(p, " vec3 du = pos_r - pos_l;\n"); - WRITE(p, " vec3 dv = pos_d - pos_u;\n"); - } - WRITE(p, " vec3 nrm = cross(du, dv);\n"); - WRITE(p, " nrm = normalize(nrm);\n"); - } - WRITE(p, " vec3 worldpos = vec4(pos.xyz, 1.0) * base.world_mtx;\n"); - if (hasNormal) { - WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snrm, 0.0) * base.world_mtx);\n", flipNormalTess ? "-" : ""); - } else { - WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); - } - } else { - // No skinning, just standard T&L. - WRITE(p, " vec3 worldpos = vec4(position.xyz, 1.0) * base.world_mtx;\n"); - if (hasNormal) - WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snormal, 0.0) * base.world_mtx);\n", flipNormal ? "-" : ""); + if (doBezier || doSpline) { + WRITE(p, " vec3 _pos[16];\n"); + WRITE(p, " vec2 _tex[16];\n"); + WRITE(p, " vec4 _col[16];\n"); + WRITE(p, " int num_patches_u = %s;\n", doBezier ? "(base.spline_count_u - 1) / 3" : "base.spline_count_u - 3"); + WRITE(p, " int u = int(mod(gl_InstanceIndex, num_patches_u));\n"); + WRITE(p, " int v = gl_InstanceIndex / num_patches_u;\n"); + WRITE(p, " ivec2 patch_pos = ivec2(u, v);\n"); + WRITE(p, " for (int i = 0; i < 4; i++) {\n"); + WRITE(p, " for (int j = 0; j < 4; j++) {\n"); + WRITE(p, " int idx = (i + v%s) * base.spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : ""); + WRITE(p, " _pos[i * 4 + j] = tess_data.data[idx].pos.xyz;\n"); + if (doTexture && hasTexcoord && hasTexcoordTess) + WRITE(p, " _tex[i * 4 + j] = tess_data.data[idx].uv.xy;\n"); + if (hasColor && hasColorTess) + WRITE(p, " _col[i * 4 + j] = tess_data.data[idx].color;\n"); + WRITE(p, " }\n"); + WRITE(p, " }\n"); + WRITE(p, " vec2 tess_pos = position.xy;\n"); + WRITE(p, " vec2 weights[4];\n"); + if (doBezier) { + // Bernstein 3D + WRITE(p, " weights[0] = (1 - tess_pos) * (1 - tess_pos) * (1 - tess_pos);\n"); + WRITE(p, " weights[1] = 3 * tess_pos * (1 - tess_pos) * (1 - tess_pos);\n"); + WRITE(p, " weights[2] = 3 * tess_pos * tess_pos * (1 - tess_pos);\n"); + WRITE(p, " weights[3] = tess_pos * tess_pos * tess_pos;\n"); + } else { // Spline + WRITE(p, " ivec2 spline_num_patches = ivec2(base.spline_count_u - 3, base.spline_count_v - 3);\n"); + WRITE(p, " ivec2 spline_type = ivec2(base.spline_type_u, base.spline_type_v);\n"); + WRITE(p, " vec2 knots[6];\n"); + WRITE(p, " spline_knot(spline_num_patches, spline_type, knots, patch_pos);\n"); + WRITE(p, " spline_weight(tess_pos + patch_pos, knots, weights);\n"); + } + WRITE(p, " vec3 pos = tess_sample(_pos, weights);\n"); + if (doTexture && hasTexcoord) { + if (hasTexcoordTess) + WRITE(p, " vec2 tex = tess_sample(_tex, weights);\n"); else - WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); + WRITE(p, " vec2 tex = tess_pos + patch_pos;\n"); + } + if (hasColor) { + if (hasColorTess) + WRITE(p, " vec4 col = tess_sample(_col, weights);\n"); + else + WRITE(p, " vec4 col = tess_data.data[0].color;\n"); + } + if (hasNormal) { + // Curved surface is probably always need to compute normal(not sampling from control points) + if (doBezier) { + // Bernstein derivative + WRITE(p, " vec2 bernderiv[4];\n"); + WRITE(p, " bernderiv[0] = -3 * (tess_pos - 1) * (tess_pos - 1); \n"); + WRITE(p, " bernderiv[1] = 9 * tess_pos * tess_pos - 12 * tess_pos + 3; \n"); + WRITE(p, " bernderiv[2] = 3 * (2 - 3 * tess_pos) * tess_pos; \n"); + WRITE(p, " bernderiv[3] = 3 * tess_pos * tess_pos; \n"); + + WRITE(p, " vec2 bernderiv_u[4];\n"); + WRITE(p, " vec2 bernderiv_v[4];\n"); + WRITE(p, " for (int i = 0; i < 4; i++) {\n"); + WRITE(p, " bernderiv_u[i] = vec2(bernderiv[i].x, weights[i].y);\n"); + WRITE(p, " bernderiv_v[i] = vec2(weights[i].x, bernderiv[i].y);\n"); + WRITE(p, " }\n"); + + WRITE(p, " vec3 du = tess_sample(_pos, bernderiv_u);\n"); + WRITE(p, " vec3 dv = tess_sample(_pos, bernderiv_v);\n"); + } else { // Spline + WRITE(p, " vec2 tess_next_u = vec2(normal.x, 0);\n"); + WRITE(p, " vec2 tess_next_v = vec2(0, normal.y);\n"); + // Right + WRITE(p, " vec2 tess_pos_r = tess_pos + tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_r + patch_pos, knots, weights);\n"); + WRITE(p, " vec3 pos_r = tess_sample(_pos, weights);\n"); + // Left + WRITE(p, " vec2 tess_pos_l = tess_pos - tess_next_u;\n"); + WRITE(p, " spline_weight(tess_pos_l + patch_pos, knots, weights);\n"); + WRITE(p, " vec3 pos_l = tess_sample(_pos, weights);\n"); + // Down + WRITE(p, " vec2 tess_pos_d = tess_pos + tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_d + patch_pos, knots, weights);\n"); + WRITE(p, " vec3 pos_d = tess_sample(_pos, weights);\n"); + // Up + WRITE(p, " vec2 tess_pos_u = tess_pos - tess_next_v;\n"); + WRITE(p, " spline_weight(tess_pos_u + patch_pos, knots, weights);\n"); + WRITE(p, " vec3 pos_u = tess_sample(_pos, weights);\n"); + + WRITE(p, " vec3 du = pos_r - pos_l;\n"); + WRITE(p, " vec3 dv = pos_d - pos_u;\n"); + } + WRITE(p, " vec3 nrm = cross(du, dv);\n"); + WRITE(p, " nrm = normalize(nrm);\n"); + } + WRITE(p, " vec3 worldpos = vec4(pos.xyz, 1.0) * base.world_mtx;\n"); + if (hasNormal) { + WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snrm, 0.0) * base.world_mtx);\n", flipNormalTess ? "-" : ""); + } else { + WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } } else { - static const char *rescale[4] = { "", " * 1.9921875", " * 1.999969482421875", "" }; // 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f}; - const char *factor = rescale[boneWeightScale]; - - static const char * const boneWeightAttr[8] = { - "w1.x", "w1.y", "w1.z", "w1.w", - "w2.x", "w2.y", "w2.z", "w2.w", - }; - - WRITE(p, " mat3x4 skinMatrix = w1.x * bone.m[0];\n"); - if (numBoneWeights > 1) { - for (int i = 1; i < numBoneWeights; i++) { - WRITE(p, " skinMatrix += %s * bone.m[%i];\n", boneWeightAttr[i], i); - } - } - - WRITE(p, ";\n"); - - // Trying to simplify this results in bugs in LBP... - WRITE(p, " vec3 skinnedpos = (vec4(position, 1.0) * skinMatrix) %s;\n", factor); - WRITE(p, " vec3 worldpos = vec4(skinnedpos, 1.0) * base.world_mtx;\n"); - - if (hasNormal) { - WRITE(p, " mediump vec3 skinnednormal = vec4(%snormal, 0.0) * skinMatrix %s;\n", flipNormal ? "-" : "", factor); - } else { - WRITE(p, " mediump vec3 skinnednormal = vec4(0.0, 0.0, %s1.0, 0.0) * skinMatrix %s;\n", flipNormal ? "-" : "", factor); - } - WRITE(p, " mediump vec3 worldnormal = normalize(vec4(skinnednormal, 0.0) * base.world_mtx);\n"); + WRITE(p, " vec3 worldpos = vec4(position.xyz, 1.0) * base.world_mtx;\n"); + if (hasNormal) + WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snormal, 0.0) * base.world_mtx);\n", flipNormal ? "-" : ""); + else + WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } WRITE(p, " vec4 viewPos = vec4(vec4(worldpos, 1.0) * base.view_mtx, 1.0);\n"); @@ -576,8 +519,8 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: WRITE(p, " float angle%i = dot(normalize(light.dir[%i]), toLight);\n", i, i); - WRITE(p, " if (angle%i >= light.angle[%i]) {\n", i, i); - WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, light.spotCoef[%i]);\n", i, i, i); + WRITE(p, " if (angle%i >= light.angle_spotCoef[%i].x) {\n", i, i); + WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, light.angle_spotCoef[%i].y);\n", i, i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.h b/GPU/Vulkan/VertexShaderGeneratorVulkan.h index e1c75a7a46..1501c1cdae 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.h +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.h @@ -2,4 +2,4 @@ #include "GPU/Common/ShaderId.h" -bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *usesLighting); +bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer); diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index fa41eb4bfc..d7d6223fc8 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -62,7 +62,10 @@ void Vulkan2D::DestroyDeviceObjects() { } void Vulkan2D::InitDeviceObjects() { - pipelineCache_ = vulkan_->CreatePipelineCache(); + VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); + assert(VK_SUCCESS == res); + VkDescriptorSetLayoutBinding bindings[2] = {}; // Texture. bindings[0].descriptorCount = 1; @@ -80,7 +83,7 @@ void Vulkan2D::InitDeviceObjects() { VkDescriptorSetLayoutCreateInfo dsl = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsl.bindingCount = 2; dsl.pBindings = bindings; - VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); + res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); assert(VK_SUCCESS == res); VkDescriptorPoolSize dpTypes[1]; @@ -164,8 +167,11 @@ VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, VkDescriptorImageInfo image1 = {}; VkDescriptorImageInfo image2 = {}; if (tex1) { - // TODO: Also support LAYOUT_GENERAL to be able to texture from framebuffers without transitioning them? +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + image1.imageLayout = VK_IMAGE_LAYOUT_GENERAL; +#else image1.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +#endif image1.imageView = tex1; image1.sampler = sampler1; writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -178,7 +184,11 @@ VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, } if (tex2) { // TODO: Also support LAYOUT_GENERAL to be able to texture from framebuffers without transitioning them? +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + image2.imageLayout = VK_IMAGE_LAYOUT_GENERAL; +#else image2.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +#endif image2.imageView = tex2; image2.sampler = sampler2; writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; diff --git a/Qt/Debugger/debugger_displaylist.cpp b/Qt/Debugger/debugger_displaylist.cpp index 349dbfea80..6089c64003 100644 --- a/Qt/Debugger/debugger_displaylist.cpp +++ b/Qt/Debugger/debugger_displaylist.cpp @@ -10,8 +10,9 @@ #include "Core/Host.h" #include "base/display.h" #include "mainwindow.h" -#include "UI/HostTypes.h" -//commented out until someone bothers to maintain it +#include "Qt/QtHost.h" + +//commented out until someone bothers to maintain it (see below) //#include "GPU/GLES/VertexDecoder.h" Debugger_DisplayList::Debugger_DisplayList(DebugInterface *_cpu, Draw::DrawContext *draw, MainWindow* mainWindow_, QWidget *parent) : diff --git a/Qt/Debugger/debugger_memorytex.cpp b/Qt/Debugger/debugger_memorytex.cpp index 51af9915c5..238c1371af 100644 --- a/Qt/Debugger/debugger_memorytex.cpp +++ b/Qt/Debugger/debugger_memorytex.cpp @@ -1,5 +1,4 @@ #include "debugger_memorytex.h" -#include "gfx/GLStateCache.h" #include "gfx/gl_common.h" #include "ui_debugger_memorytex.h" #include "Core/MemMap.h" @@ -55,17 +54,7 @@ void Debugger_MemoryTex::on_readBtn_clicked() w = std::max(bufW,w); uchar* newData = new uchar[w*h*4]; - if(gpu->DecodeTexture(newData, state)) - { - QImage img = QImage(newData, w, h, w*4, QImage::Format_ARGB32); // EmuThread_GrabBackBuffer(); - - QPixmap pixmap = QPixmap::fromImage(img); - ui->textureImg->setPixmap(pixmap); - ui->textureImg->setMinimumWidth(pixmap.width()); - ui->textureImg->setMinimumHeight(pixmap.height()); - ui->textureImg->setMaximumWidth(pixmap.width()); - ui->textureImg->setMaximumHeight(pixmap.height()); - } + // TODO: Use GPU_GetCurrentTexture(). Warning: blocks. delete[] newData; } diff --git a/Qt/QtHost.cpp b/Qt/QtHost.cpp new file mode 100644 index 0000000000..c2ef7d2eac --- /dev/null +++ b/Qt/QtHost.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include "Qt/QtHost.h" + +const char* QtHost::SymbolMapFilename(std::string currentFilename) { + std::string result = currentFilename; + size_t dot = result.rfind('.'); + if (dot == result.npos) + return (result + ".map").c_str(); + + result.replace(dot, result.npos, ".map"); + return result.c_str(); +} diff --git a/Qt/QtHost.h b/Qt/QtHost.h new file mode 100644 index 0000000000..2df6155bb0 --- /dev/null +++ b/Qt/QtHost.h @@ -0,0 +1,123 @@ +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "Core/Host.h" +#include "UI/OnScreenDisplay.h" + +#include "Core/Debugger/SymbolMap.h" +#include "Qt/mainwindow.h" + +class QtHost : public Host { +public: + QtHost(MainWindow *mainWindow_) + { + mainWindow = mainWindow_; + m_GPUStep = false; + m_GPUFlag = 0; + } + + virtual void UpdateUI() override { + mainWindow->updateMenus(); + } + + virtual void UpdateMemView() override { + if(mainWindow->GetDialogMemory()) + mainWindow->GetDialogMemory()->Update(); + } + virtual void UpdateDisassembly() override { + if(mainWindow->GetDialogDisasm()) + mainWindow->GetDialogDisasm()->Update(); + if(mainWindow->GetDialogDisplaylist()) + mainWindow->GetDialogDisplaylist()->Update(); + } + + virtual void SetDebugMode(bool mode) override { + if(mainWindow->GetDialogDisasm()) + mainWindow->GetDialogDisasm()->SetDebugMode(mode); + } + + virtual bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; } + virtual void ShutdownGraphics() override {} + + virtual void InitSound() override; + virtual void UpdateSound() override {} + virtual void ShutdownSound() override; + + // this is sent from EMU thread! Make sure that Host handles it properly! + virtual void BootDone() override { + g_symbolMap->SortSymbols(); + mainWindow->Notify(MainWindowMsg::BOOT_DONE); + } + + virtual bool IsDebuggingEnabled() override { +#ifdef _DEBUG + return true; +#else + return false; +#endif + } + virtual bool AttemptLoadSymbolMap() override { + return false; + // TODO: Make this work with Qt and threaded GL... not sure what's so broken. + // auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); + // return g_symbolMap->LoadSymbolMap(fn); + } + void PrepareShutdown() { + g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart)); + } + void SetWindowTitle(const char *message) override { + std::string title = std::string("PPSSPP ") + PPSSPP_GIT_VERSION; + if (message) + title += std::string(" - ") + message; +#ifdef _DEBUG + title += " (debug)"; +#endif + mainWindow->SetWindowTitleAsync(title); + } + + void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override { + osm.Show(message, duration, color, -1, true, id); + } + + void SendUIMessage(const std::string &message, const std::string &value) override { + NativeMessageReceived(message.c_str(), value.c_str()); + } + + bool GPUDebuggingActive() override { + auto dialogDisplayList = mainWindow->GetDialogDisplaylist(); + if (dialogDisplayList && dialogDisplayList->isVisible()) { + if (m_GPUStep && m_GPUFlag == -1) + m_GPUFlag = 0; + + return true; + } + return false; + } + void SetGPUStep(bool value, int flag = 0, u32 data = 0) { + m_GPUStep = value; + m_GPUFlag = flag; + m_GPUData = data; + } +private: + const char* SymbolMapFilename(std::string currentFilename); + MainWindow* mainWindow; + bool m_GPUStep; + int m_GPUFlag; + u32 m_GPUData; +}; diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 3030f64354..5112c20435 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -29,6 +29,7 @@ #include "QtMain.h" #include "gfx_es2/gpu_features.h" #include "math/math_util.h" +#include "thread/threadutil.h" #include @@ -139,8 +140,7 @@ float CalculateDPIScale() #endif } -static int mainInternal(QApplication &a) -{ +static int mainInternal(QApplication &a) { #ifdef MOBILE_DEVICE emugl = new MainUI(); emugl->resize(pixel_xres, pixel_yres); @@ -185,34 +185,78 @@ static int mainInternal(QApplication &a) QScopedPointer audio(new MainAudio()); audio->run(); #endif - return a.exec(); + int retval = a.exec(); + delete emugl; + return retval; +} + +void MainUI::EmuThreadFunc() { + setCurrentThreadName("Emu"); + + // There's no real requirement that NativeInit happen on this thread, though it can't hurt... + // We just call the update/render loop here. NativeInitGraphics should be here though. + NativeInitGraphics(graphicsContext); + + emuThreadState = (int)EmuThreadState::RUNNING; + while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { + updateAccelerometer(); + UpdateRunLoop(); + } + emuThreadState = (int)EmuThreadState::STOPPED; + + NativeShutdownGraphics(); + graphicsContext->StopThread(); +} + +void MainUI::EmuThreadStart() { + emuThreadState = (int)EmuThreadState::START_REQUESTED; + emuThread = std::thread([&]() { this->EmuThreadFunc(); } ); +} + +void MainUI::EmuThreadStop() { + emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; +} + +void MainUI::EmuThreadJoin() { + emuThread.join(); + emuThread = std::thread(); } MainUI::MainUI(QWidget *parent): - QGLWidget(parent) + QGLWidget(parent) { - setAttribute(Qt::WA_AcceptTouchEvents); + emuThreadState = (int)EmuThreadState::DISABLED; + setAttribute(Qt::WA_AcceptTouchEvents); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - setAttribute(Qt::WA_LockLandscapeOrientation); + setAttribute(Qt::WA_LockLandscapeOrientation); #endif #if defined(MOBILE_DEVICE) - acc = new QAccelerometer(this); - acc->start(); + acc = new QAccelerometer(this); + acc->start(); #endif - setFocus(); - setFocusPolicy(Qt::StrongFocus); - startTimer(16); + setFocus(); + setFocusPolicy(Qt::StrongFocus); + startTimer(16); } MainUI::~MainUI() { + ILOG("MainUI::Destructor"); + if (emuThreadState != (int)EmuThreadState::DISABLED) { + ILOG("EmuThreadStop"); + EmuThreadStop(); + while (graphicsContext->ThreadFrame()) { + // Need to keep eating frames to allow the EmuThread to exit correctly. + continue; + } + EmuThreadJoin(); + } #if defined(MOBILE_DEVICE) - delete acc; + delete acc; #endif - NativeShutdownGraphics(); - graphicsContext->Shutdown(); - delete graphicsContext; - graphicsContext = nullptr; + graphicsContext->Shutdown(); + delete graphicsContext; + graphicsContext = nullptr; } QString MainUI::InputBoxGetQString(QString title, QString defaultValue) @@ -318,30 +362,47 @@ bool MainUI::event(QEvent *e) return true; } -void MainUI::initializeGL() -{ +void MainUI::initializeGL() { + if (g_Config.iGPUBackend != (int)GPUBackend::OPENGL) { + ILOG("Only GL supported under Qt - switching."); + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + } + #ifndef USING_GLES2 // Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc. // glewExperimental allows us to force GLEW to search for the pointers anyway. - if (gl_extensions.IsCoreContext) + if (gl_extensions.IsCoreContext) { glewExperimental = true; + } glewInit(); // Unfortunately, glew will generate an invalid enum error, ignore. - if (gl_extensions.IsCoreContext) + if (gl_extensions.IsCoreContext) { glGetError(); + } #endif - graphicsContext = new QtDummyGraphicsContext(); - NativeInitGraphics(graphicsContext); + if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) { + // OpenGL uses a background thread to do the main processing and only renders on the gl thread. + ILOG("Initializing GL graphics context"); + graphicsContext = new QtGLGraphicsContext(); + ILOG("Using thread, starting emu thread"); + EmuThreadStart(); + } else { + ILOG("Not using thread, backend=%d", (int)g_Config.iGPUBackend); + } + graphicsContext->ThreadStart(); } -void MainUI::paintGL() -{ -#ifdef SDL - SDL_PumpEvents(); -#endif - updateAccelerometer(); - time_update(); - UpdateRunLoop(); +void MainUI::paintGL() { + #ifdef SDL + SDL_PumpEvents(); + #endif + updateAccelerometer(); + if (emuThreadState == (int)EmuThreadState::DISABLED) { + UpdateRunLoop(); + } else { + graphicsContext->ThreadFrame(); + // Do the rest in EmuThreadFunc + } } void MainUI::updateAccelerometer() @@ -454,17 +515,20 @@ int main(int argc, char *argv[]) #endif savegame_dir += "/"; external_dir += "/"; - + bool fullscreenCLI=false; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i],"--fullscreen")) fullscreenCLI=true; } NativeInit(argc, (const char **)argv, savegame_dir.c_str(), external_dir.c_str(), nullptr, fullscreenCLI); - - int ret = mainInternal(a); - NativeShutdownGraphics(); + // TODO: Support other backends than GL, like Vulkan, in the Qt backend. + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + + int ret = mainInternal(a); + ILOG("Left mainInternal here."); + #ifdef SDL SDL_PauseAudio(1); SDL_CloseAudio(); diff --git a/Qt/QtMain.h b/Qt/QtMain.h index f4f1b3c5c2..7f67794487 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -19,6 +19,8 @@ QTM_USE_NAMESPACE #endif #include +#include +#include #include "base/display.h" #include "base/logging.h" @@ -37,31 +39,70 @@ QTM_USE_NAMESPACE #include "Core/Core.h" #include "Core/Config.h" #include "Core/System.h" +#include "thin3d/thin3d_create.h" +#include "thin3d/GLRenderManager.h" // Input void SimulateGamepad(); -class QtDummyGraphicsContext : public DummyGraphicsContext { +class QtGLGraphicsContext : public GraphicsContext { public: - QtDummyGraphicsContext() { + QtGLGraphicsContext() { CheckGLExtensions(); draw_ = Draw::T3DCreateGLContext(); SetGPUBackend(GPUBackend::OPENGL); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); bool success = draw_->CreatePresets(); assert(success); } - ~QtDummyGraphicsContext() { + + ~QtGLGraphicsContext() { delete draw_; + draw_ = nullptr; + renderManager_ = nullptr; } + void Shutdown() override {} + void SwapInterval(int interval) override {} + void SwapBuffers() override {} + void Resize() override {} + Draw::DrawContext *GetDrawContext() override { return draw_; } + + void ThreadStart() override { + renderManager_->ThreadStart(); + } + + bool ThreadFrame() override { + return renderManager_->ThreadFrame(); + } + + void ThreadEnd() override { + renderManager_->ThreadEnd(); + } + + void StopThread() override { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); + } + private: - Draw::DrawContext *draw_; + Draw::DrawContext *draw_ = nullptr; + GLRenderManager *renderManager_ = nullptr; }; -//GUI +enum class EmuThreadState { + DISABLED, + START_REQUESTED, + RUNNING, + QUIT_REQUESTED, + STOPPED, +}; + + +// GUI, thread manager class MainUI : public QGLWidget { Q_OBJECT @@ -87,13 +128,21 @@ protected: void updateAccelerometer(); + void EmuThreadFunc(); + void EmuThreadStart(); + void EmuThreadStop(); + void EmuThreadJoin(); + private: - QtDummyGraphicsContext *graphicsContext; + QtGLGraphicsContext *graphicsContext; float xscale, yscale; #if defined(MOBILE_DEVICE) QAccelerometer* acc; #endif + + std::thread emuThread; + std::atomic emuThreadState; }; extern MainUI* emugl; @@ -101,8 +150,7 @@ extern MainUI* emugl; #ifndef SDL // Audio -class MainAudio: public QObject -{ +class MainAudio : public QObject { Q_OBJECT public: MainAudio() {} diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 7e0b481f9b..116b7f084a 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -72,6 +72,21 @@ void MainWindow::newFrame() updateMenus(); } + + std::unique_lock lock(msgMutex_); + while (!msgQueue_.empty()) { + MainWindowMsg msg = msgQueue_.front(); + msgQueue_.pop(); + switch (msg) { + case MainWindowMsg::BOOT_DONE: + bootDone(); + break; + case MainWindowMsg::WINDOW_TITLE_CHANGED: + std::unique_lock lock(titleMutex_); + setWindowTitle(QString::fromUtf8(newWindowTitle_.c_str())); + break; + } + } } void MainWindow::updateMenus() @@ -128,8 +143,7 @@ void MainWindow::updateMenus() emit updateMenu(); } -/* SLOTS */ -void MainWindow::Boot() +void MainWindow::bootDone() { dialogDisasm = new Debugger_Disasm(currentDebugMIPS, this, this); if(g_Config.bShowDebuggerOnLoad) @@ -149,6 +163,7 @@ void MainWindow::Boot() updateMenus(); } +/* SIGNALS */ void MainWindow::openAct() { QString filename = QFileDialog::getOpenFileName(NULL, "Load File", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.prx)"); diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index c52120820e..ba2d3ff7dc 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -1,5 +1,7 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#pragma once + +#include +#include #include #include @@ -21,6 +23,12 @@ extern bool g_TakeScreenshot; class MenuAction; class MenuTree; +// hacky, should probably use qt signals or something, but whatever.. +enum class MainWindowMsg { + BOOT_DONE, + WINDOW_TITLE_CHANGED, +}; + class MainWindow : public QMainWindow { Q_OBJECT @@ -38,6 +46,17 @@ public: void ShowMemory(u32 addr); void updateMenus(); + void Notify(MainWindowMsg msg) { + std::unique_lock lock(msgMutex_); + msgQueue_.push(msg); + } + + void SetWindowTitleAsync(std::string title) { + std::unique_lock lock(titleMutex_); + newWindowTitle_ = title; + Notify(MainWindowMsg::WINDOW_TITLE_CHANGED); + } + protected: void changeEvent(QEvent *e) { @@ -54,7 +73,6 @@ signals: void updateMenu(); public slots: - void Boot(); void newFrame(); private slots: @@ -136,6 +154,7 @@ private slots: void langChanged(QAction *action) { loadLanguage(action->data().toString(), true); } private: + void bootDone(); void SetWindowScale(int zoom); void SetGameTitle(QString text); void loadLanguage(const QString &language, bool retranslate); @@ -155,6 +174,12 @@ private: QActionGroup *anisotropicGroup, *screenGroup, *displayLayoutGroup, *defaultLogGroup, *g3dLogGroup, *hleLogGroup; + + std::queue msgQueue_; + std::mutex msgMutex_; + + std::string newWindowTitle_; + std::mutex titleMutex_; }; class MenuAction : public QAction @@ -275,5 +300,3 @@ public slots: private: const char *_text; }; - -#endif // MAINWINDOW_H diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp new file mode 100644 index 0000000000..3693c77c5a --- /dev/null +++ b/SDL/SDLGLGraphicsContext.cpp @@ -0,0 +1,143 @@ +#include "SDLGLGraphicsContext.h" +#include "Core/Config.h" +#include "Core/System.h" +#include "base/NativeApp.h" +#include "base/display.h" +#include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d_create.h" + +class GLRenderManager; + +// Returns 0 on success. +int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { + struct GLVersionPair { + int major; + int minor; + }; + GLVersionPair attemptVersions[] = { +#ifdef USING_GLES2 + {3, 2}, {3, 1}, {3, 0}, {2, 0}, +#else + {4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, + {3, 3}, {3, 2}, {3, 1}, {3, 0}, +#endif + }; + +#ifdef USING_GLES2 + mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN; +#else + mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; +#endif + SDL_GLContext glContext = nullptr; + for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) { + const auto &ver = attemptVersions[i]; + // Make sure to request a somewhat modern GL context at least - the + // latest supported by MacOS X (really, really sad...) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor); +#ifdef USING_GLES2 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SetGLCoreContext(false); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SetGLCoreContext(true); +#endif + + window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); + if (!window) { + NativeShutdown(); + fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); + continue; + } + + glContext = SDL_GL_CreateContext(window); + if (glContext != nullptr) { + // Victory, got one. + break; + } + + // Let's keep trying. To be safe, destroy the window - docs say needed to change profile. + // in practice, it doesn't seem to matter, but maybe it differs by platform. + SDL_DestroyWindow(window); + } + + if (glContext == nullptr) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SetGLCoreContext(false); + + window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); + if (window == nullptr) { + NativeShutdown(); + fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + + glContext = SDL_GL_CreateContext(window); + if (glContext == nullptr) { + NativeShutdown(); + fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + } + +#ifdef USING_EGL + EGL_Init(); +#endif + +#ifndef USING_GLES2 + // Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc. + // glewExperimental allows us to force GLEW to search for the pointers anyway. + if (gl_extensions.IsCoreContext) { + glewExperimental = true; + } + if (GLEW_OK != glewInit()) { + printf("Failed to initialize glew!\n"); + return 1; + } + // Unfortunately, glew will generate an invalid enum error, ignore. + if (gl_extensions.IsCoreContext) + glGetError(); + + if (GLEW_VERSION_2_0) { + printf("OpenGL 2.0 or higher.\n"); + } else { + printf("Sorry, this program requires OpenGL 2.0.\n"); + return 1; + } +#endif + + // Finally we can do the regular initialization. + CheckGLExtensions(); + draw_ = Draw::T3DCreateGLContext(); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + SetGPUBackend(GPUBackend::OPENGL); + bool success = draw_->CreatePresets(); + assert(success); + renderManager_->SetSwapFunction([&]() { +#ifdef USING_EGL + eglSwapBuffers(g_eglDisplay, g_eglSurface); +#else + SDL_GL_SwapWindow(window_); +#endif + }); + window_ = window; + return 0; +} + +void SDLGLGraphicsContext::Shutdown() { +} + +void SDLGLGraphicsContext::ShutdownFromRenderThread() { + delete draw_; + draw_ = nullptr; + +#ifdef USING_EGL + EGL_Close(); +#else + SDL_GL_DeleteContext(glContext); +#endif +} diff --git a/SDL/SDLGLGraphicsContext.h b/SDL/SDLGLGraphicsContext.h new file mode 100644 index 0000000000..2695ebf64d --- /dev/null +++ b/SDL/SDLGLGraphicsContext.h @@ -0,0 +1,53 @@ +#if !defined(__APPLE__) +#include "SDL_syswm.h" +#endif +#include "SDL.h" + +#include "thin3d/GLRenderManager.h" +#include "gfx/gl_common.h" +#include "Common/GraphicsContext.h" + +class SDLGLGraphicsContext : public DummyGraphicsContext { +public: + SDLGLGraphicsContext() { + } + + // Returns 0 on success. + int Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message); + + void Shutdown() override; + void ShutdownFromRenderThread() override; + + void SwapBuffers() override { + // Do nothing, the render thread takes care of this. + } + + Draw::DrawContext *GetDrawContext() override { + return draw_; + } + + void ThreadStart() override { + renderManager_->ThreadStart(); + } + + bool ThreadFrame() override { + return renderManager_->ThreadFrame(); + } + + void ThreadEnd() override { + renderManager_->ThreadEnd(); + } + + void StopThread() override { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); + } + +private: + Draw::DrawContext *draw_ = nullptr; + SDL_Window *window_; + SDL_GLContext glContext = nullptr; + GLRenderManager *renderManager_ = nullptr; +}; + + diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index acc5cc0e10..9cd5af04a9 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -14,26 +14,25 @@ SDLJoystick *joystick = NULL; #include #endif +#include #include #include #include +#include #include "base/display.h" #include "base/logging.h" #include "base/timeutil.h" #include "ext/glslang/glslang/Public/ShaderLang.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" #include "input/input_state.h" #include "input/keycodes.h" #include "net/resolve.h" #include "base/NKCodeFromSDL.h" #include "util/const_map.h" #include "util/text/utf8.h" -#include "util/text/parsers.h" #include "math/math_util.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "thin3d/GLRenderManager.h" +#include "thread/threadutil.h" #include "math.h" #if !defined(__APPLE__) @@ -57,6 +56,9 @@ SDLJoystick *joystick = NULL; #include "Core/Core.h" #include "Core/Config.h" #include "Common/GraphicsContext.h" +#include "SDLGLGraphicsContext.h" +#include "SDLVulkanGraphicsContext.h" + GlobalUIState lastUIState = UISTATE_MENU; GlobalUIState GetUIState(); @@ -68,8 +70,6 @@ static int g_QuitRequested = 0; static int g_DesktopWidth = 0; static int g_DesktopHeight = 0; -static VulkanLogOptions g_LogOptions; - #if defined(USING_EGL) static EGLDisplay g_eglDisplay = NULL; @@ -198,299 +198,6 @@ void EGL_Close() { } #endif -class SDLGLGraphicsContext : public DummyGraphicsContext { -public: - SDLGLGraphicsContext() { - } - ~SDLGLGraphicsContext() { - delete draw_; - } - - // Returns 0 on success. - int Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message); - - void Shutdown() override { -#ifdef USING_EGL - EGL_Close(); -#else - SDL_GL_DeleteContext(glContext); -#endif - } - - void SwapBuffers() override { -#ifdef USING_EGL - eglSwapBuffers(g_eglDisplay, g_eglSurface); -#else - SDL_GL_SwapWindow(window_); -#endif - } - - Draw::DrawContext *GetDrawContext() override { - return draw_; - } - -private: - Draw::DrawContext *draw_ = nullptr; - SDL_Window *window_; - SDL_GLContext glContext = nullptr; -}; - -// Returns 0 on success. -int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { - struct GLVersionPair { - int major; - int minor; - }; - GLVersionPair attemptVersions[] = { -#ifdef USING_GLES2 - {3, 2}, {3, 1}, {3, 0}, {2, 0}, -#else - {4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, - {3, 3}, {3, 2}, {3, 1}, {3, 0}, -#endif - }; - -#ifdef USING_GLES2 - mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN; -#else - mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; -#endif - SDL_GLContext glContext = nullptr; - for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) { - const auto &ver = attemptVersions[i]; - // Make sure to request a somewhat modern GL context at least - the - // latest supported by MacOS X (really, really sad...) - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor); -#ifdef USING_GLES2 - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - SetGLCoreContext(false); -#else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SetGLCoreContext(true); -#endif - - window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); - if (!window) { - NativeShutdown(); - fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); - continue; - } - - glContext = SDL_GL_CreateContext(window); - if (glContext != nullptr) { - // Victory, got one. - break; - } - - // Let's keep trying. To be safe, destroy the window - docs say needed to change profile. - // in practice, it doesn't seem to matter, but maybe it differs by platform. - SDL_DestroyWindow(window); - } - - if (glContext == nullptr) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SetGLCoreContext(false); - - window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); - if (window == nullptr) { - NativeShutdown(); - fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); - SDL_Quit(); - return 2; - } - - glContext = SDL_GL_CreateContext(window); - if (glContext == nullptr) { - NativeShutdown(); - fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); - SDL_Quit(); - return 2; - } - } - -#ifdef USING_EGL - EGL_Init(); -#endif - -#ifndef USING_GLES2 - // Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc. - // glewExperimental allows us to force GLEW to search for the pointers anyway. - if (gl_extensions.IsCoreContext) { - glewExperimental = true; - } - if (GLEW_OK != glewInit()) { - printf("Failed to initialize glew!\n"); - return 1; - } - // Unfortunately, glew will generate an invalid enum error, ignore. - if (gl_extensions.IsCoreContext) - glGetError(); - - if (GLEW_VERSION_2_0) { - printf("OpenGL 2.0 or higher.\n"); - } else { - printf("Sorry, this program requires OpenGL 2.0.\n"); - return 1; - } -#endif - - // Finally we can do the regular initialization. - CheckGLExtensions(); - draw_ = Draw::T3DCreateGLContext(); - SetGPUBackend(GPUBackend::OPENGL); - bool success = draw_->CreatePresets(); - assert(success); - window_ = window; - return 0; -} - -class SDLVulkanGraphicsContext : public GraphicsContext { -public: - SDLVulkanGraphicsContext() {} - ~SDLVulkanGraphicsContext() { - delete draw_; - } - - bool Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message); - - void Shutdown() override; - - void SwapBuffers() override { - // We don't do it this way. - } - - void Resize() override { - /* - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - vulkan_->DestroyObjects(); - // TODO: Take from real window dimensions - int width = 1024; - int height = 768; - vulkan_->ReinitSurface(width, height); - vulkan_->InitObjects(); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - */ - } - - void SwapInterval(int interval) override { - } - void *GetAPIContext() override { - return vulkan_; - } - - Draw::DrawContext *GetDrawContext() override { - return draw_; - } -private: - Draw::DrawContext *draw_ = nullptr; - VulkanContext *vulkan_ = nullptr; -}; - -bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { - window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode); - if (!window) { - fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError()); - exit(1); - } - - init_glslang(); - - g_LogOptions.breakOnError = true; - g_LogOptions.breakOnWarning = true; - g_LogOptions.msgBoxOnError = false; - - Version gitVer(PPSSPP_GIT_VERSION); - - vulkan_ = new VulkanContext(); - if (vulkan_->InitError().size()) { - *error_message = vulkan_->InitError(); - delete vulkan_; - vulkan_ = nullptr; - return false; - } - - int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX; - // vulkanFlags |= VULKAN_FLAG_VALIDATE; - VulkanContext::CreateInfo info{}; - info.app_name = "PPSSPP"; - info.app_ver = gitVer.ToInteger(); - info.flags = vulkanFlags; - if (VK_SUCCESS != vulkan_->CreateInstance(info)) { - *error_message = vulkan_->InitError(); - delete vulkan_; - vulkan_ = nullptr; - return false; - } - vulkan_->ChooseDevice(vulkan_->GetBestPhysicalDevice()); - if (vulkan_->CreateDevice() != VK_SUCCESS) { - *error_message = vulkan_->InitError(); - delete vulkan_; - vulkan_ = nullptr; - return false; - } - -#if !defined(__APPLE__) - SDL_SysWMinfo sys_info{}; - SDL_VERSION(&sys_info.version); //Set SDL version - if (!SDL_GetWindowWMInfo(window, &sys_info)) { - fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError()); - exit(1); - } - switch (sys_info.subsystem) { - case SDL_SYSWM_X11: -#if defined(VK_USE_PLATFORM_XLIB_KHR) - vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display, - (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); -#elif defined(VK_USE_PLATFORM_XCB_KHR) - vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display), - (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); -#endif - break; -#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - case SDL_SYSWM_WAYLAND: - vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, - (void *)sys_info.info.wl.surface, pixel_xres, pixel_yres); - break; -#endif - default: - fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem); - exit(1); - break; - } -#endif - - if (!vulkan_->InitObjects()) { - *error_message = vulkan_->InitError(); - Shutdown(); - return false; - } - - draw_ = Draw::T3DCreateVulkanContext(vulkan_, false); - SetGPUBackend(GPUBackend::VULKAN); - bool success = draw_->CreatePresets(); - assert(success); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - - return true; -} - -void SDLVulkanGraphicsContext::Shutdown() { - if (draw_) - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - delete draw_; - draw_ = nullptr; - vulkan_->WaitUntilQueueIdle(); - vulkan_->DestroyObjects(); - vulkan_->DestroyDevice(); - vulkan_->DestroyDebugMsgCallback(); - vulkan_->DestroyInstance(); - delete vulkan_; - vulkan_ = nullptr; - finalize_glslang(); -} int getDisplayNumber(void) { int displayNumber = 0; @@ -499,8 +206,7 @@ int getDisplayNumber(void) { //get environment displayNumberStr=getenv("SDL_VIDEO_FULLSCREEN_HEAD"); - if (displayNumberStr) - { + if (displayNumberStr) { displayNumber = atoi(displayNumberStr); } @@ -691,6 +397,49 @@ void ToggleFullScreenIfFlagSet(SDL_Window *window) { } } +enum class EmuThreadState { + DISABLED, + START_REQUESTED, + RUNNING, + QUIT_REQUESTED, + STOPPED, +}; + +static std::thread emuThread; +static std::atomic emuThreadState((int)EmuThreadState::DISABLED); + +static void EmuThreadFunc(GraphicsContext *graphicsContext) { + setCurrentThreadName("Emu"); + + // There's no real requirement that NativeInit happen on this thread. + // We just call the update/render loop here. + emuThreadState = (int)EmuThreadState::RUNNING; + + NativeInitGraphics(graphicsContext); + + while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { + UpdateRunLoop(); + } + emuThreadState = (int)EmuThreadState::STOPPED; + + NativeShutdownGraphics(); + graphicsContext->StopThread(); +} + +static void EmuThreadStart(GraphicsContext *context) { + emuThreadState = (int)EmuThreadState::START_REQUESTED; + emuThread = std::thread(&EmuThreadFunc, context); +} + +static void EmuThreadStop() { + emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; +} + +static void EmuThreadJoin() { + emuThread.join(); + emuThread = std::thread(); +} + #ifdef _WIN32 #undef main #endif @@ -866,6 +615,7 @@ int main(int argc, char *argv[]) { GraphicsContext *graphicsContext = nullptr; SDL_Window *window = nullptr; + std::string error_message; if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) { SDLGLGraphicsContext *ctx = new SDLGLGraphicsContext(); @@ -888,15 +638,23 @@ int main(int argc, char *argv[]) { } } + bool useEmuThread = g_Config.iGPUBackend == (int)GPUBackend::OPENGL; + SDL_SetWindowTitle(window, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str()); + // Since we render from the main thread, there's nothing done here, but we call it to avoid confusion. + if (!graphicsContext->InitFromRenderThread(&error_message)) { + printf("Init from thread error: '%s'\n", error_message.c_str()); + } + #ifdef MOBILE_DEVICE SDL_ShowCursor(SDL_DISABLE); #endif - NativeInitGraphics(graphicsContext); - - NativeResized(); + if (!useEmuThread) { + NativeInitGraphics(graphicsContext); + NativeResized(); + } SDL_AudioSpec fmt, ret_fmt; memset(&fmt, 0, sizeof(fmt)); @@ -934,6 +692,11 @@ int main(int argc, char *argv[]) { int framecount = 0; bool mouseDown = false; + if (useEmuThread) { + EmuThreadStart(graphicsContext); + } + graphicsContext->ThreadStart(); + while (true) { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -1101,7 +864,9 @@ int main(int argc, char *argv[]) { if (g_QuitRequested) break; const uint8_t *keys = SDL_GetKeyboardState(NULL); - UpdateRunLoop(); + if (emuThreadState == (int)EmuThreadState::DISABLED) { + UpdateRunLoop(); + } if (g_QuitRequested) break; #if !defined(MOBILE_DEVICE) @@ -1118,15 +883,35 @@ int main(int argc, char *argv[]) { // glsl_refresh(); // auto-reloads modified GLSL shaders once per second. } + if (emuThreadState != (int)EmuThreadState::DISABLED) { + if (!graphicsContext->ThreadFrame()) + break; + } graphicsContext->SwapBuffers(); ToggleFullScreenIfFlagSet(window); time_update(); framecount++; } + + if (useEmuThread) { + EmuThreadStop(); + while (graphicsContext->ThreadFrame()) { + // Need to keep eating frames to allow the EmuThread to exit correctly. + continue; + } + EmuThreadJoin(); + } + delete joystick; - NativeShutdownGraphics(); + + if (!useEmuThread) { + NativeShutdownGraphics(); + } graphicsContext->Shutdown(); + graphicsContext->ThreadEnd(); + graphicsContext->ShutdownFromRenderThread(); + NativeShutdown(); delete graphicsContext; @@ -1138,5 +923,6 @@ int main(int argc, char *argv[]) { #endif glslang::FinalizeProcess(); + ILOG("Leaving main"); return 0; } diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp new file mode 100644 index 0000000000..898d2c3a2a --- /dev/null +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -0,0 +1,112 @@ +#include "Core/Config.h" +#include "base/NativeApp.h" +#include "base/display.h" +#include "thin3d/thin3d.h" +#include "thin3d/thin3d_create.h" +#include "util/text/parsers.h" + +#include "Core/System.h" +#include "SDLVulkanGraphicsContext.h" + +bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { + window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode); + if (!window) { + fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError()); + exit(1); + } + + init_glslang(); + + g_LogOptions.breakOnError = true; + g_LogOptions.breakOnWarning = true; + g_LogOptions.msgBoxOnError = false; + + Version gitVer(PPSSPP_GIT_VERSION); + + vulkan_ = new VulkanContext(); + if (vulkan_->InitError().size()) { + *error_message = vulkan_->InitError(); + delete vulkan_; + vulkan_ = nullptr; + return false; + } + + int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX; + // vulkanFlags |= VULKAN_FLAG_VALIDATE; + VulkanContext::CreateInfo info{}; + info.app_name = "PPSSPP"; + info.app_ver = gitVer.ToInteger(); + info.flags = vulkanFlags; + if (VK_SUCCESS != vulkan_->CreateInstance(info)) { + *error_message = vulkan_->InitError(); + delete vulkan_; + vulkan_ = nullptr; + return false; + } + vulkan_->ChooseDevice(vulkan_->GetBestPhysicalDevice()); + if (vulkan_->CreateDevice() != VK_SUCCESS) { + *error_message = vulkan_->InitError(); + delete vulkan_; + vulkan_ = nullptr; + return false; + } + +#if !defined(__APPLE__) + SDL_SysWMinfo sys_info{}; + SDL_VERSION(&sys_info.version); //Set SDL version + if (!SDL_GetWindowWMInfo(window, &sys_info)) { + fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError()); + exit(1); + } + switch (sys_info.subsystem) { + case SDL_SYSWM_X11: +#if defined(VK_USE_PLATFORM_XLIB_KHR) + vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display, + (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); +#elif defined(VK_USE_PLATFORM_XCB_KHR) + vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display), + (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); +#endif + break; +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + case SDL_SYSWM_WAYLAND: + vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, + (void *)sys_info.info.wl.surface, pixel_xres, pixel_yres); + break; +#endif + default: + fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem); + exit(1); + break; + } +#endif + + if (!vulkan_->InitObjects()) { + *error_message = vulkan_->InitError(); + Shutdown(); + return false; + } + + draw_ = Draw::T3DCreateVulkanContext(vulkan_, false); + SetGPUBackend(GPUBackend::VULKAN); + bool success = draw_->CreatePresets(); + assert(success); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + + return true; +} + +void SDLVulkanGraphicsContext::Shutdown() { + if (draw_) + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + delete draw_; + draw_ = nullptr; + vulkan_->WaitUntilQueueIdle(); + vulkan_->DestroyObjects(); + vulkan_->DestroyDevice(); + vulkan_->DestroyDebugMsgCallback(); + vulkan_->DestroyInstance(); + delete vulkan_; + vulkan_ = nullptr; + finalize_glslang(); +} diff --git a/SDL/SDLVulkanGraphicsContext.h b/SDL/SDLVulkanGraphicsContext.h new file mode 100644 index 0000000000..42883b6700 --- /dev/null +++ b/SDL/SDLVulkanGraphicsContext.h @@ -0,0 +1,53 @@ +#include "SDL.h" +#if !defined(__APPLE__) +#include "SDL_syswm.h" +#endif + +#include "Common/GraphicsContext.h" +#include "Common/Vulkan/VulkanContext.h" +#include "Common/Vulkan/VulkanDebug.h" + +#include "thin3d/thin3d.h" + +class SDLVulkanGraphicsContext : public GraphicsContext { +public: + SDLVulkanGraphicsContext() {} + ~SDLVulkanGraphicsContext() { + delete draw_; + } + + bool Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message); + + void Shutdown() override; + + void SwapBuffers() override { + // We don't do it this way. + } + + void Resize() override { + /* + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + vulkan_->DestroyObjects(); + // TODO: Take from real window dimensions + int width = 1024; + int height = 768; + vulkan_->ReinitSurface(width, height); + vulkan_->InitObjects(); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + */ + } + + void SwapInterval(int interval) override { + } + void *GetAPIContext() override { + return vulkan_; + } + + Draw::DrawContext *GetDrawContext() override { + return draw_; + } +private: + Draw::DrawContext *draw_ = nullptr; + VulkanContext *vulkan_ = nullptr; + VulkanLogOptions g_LogOptions; +}; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index a01f730b77..27e7a4f4d2 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -42,6 +42,7 @@ #include "UI/GameSettingsScreen.h" #ifdef _WIN32 +#include "Common/CommonWindows.h" // Want to avoid including the full header here as it includes d3dx.h int GetD3DXVersion(); #endif @@ -119,7 +120,8 @@ UI::EventReturn DevMenu::OnJitCompare(UI::EventParams &e) { UI::EventReturn DevMenu::OnShaderView(UI::EventParams &e) { UpdateUIState(UISTATE_PAUSEMENU); - screenManager()->push(new ShaderListScreen()); + if (gpu) // Avoid crashing if chosen while the game is being loaded. + screenManager()->push(new ShaderListScreen()); return UI::EVENT_DONE; } @@ -471,6 +473,9 @@ void SystemInfoScreen::CreateViews() { #else buildConfig->Add(new InfoItem("NDEBUG", "")); #endif +#ifdef USE_ADDRESS_SANITIZER + buildConfig->Add(new InfoItem("USE_ADDRESS_SANITIZER", "")); +#endif #ifdef USING_GLES2 buildConfig->Add(new InfoItem("USING_GLES2", "")); #endif diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 7b9dfc2f7c..4e719533ed 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -28,7 +28,7 @@ #include "Core/Config.h" #include "Core/System.h" #include "DisplayLayoutEditor.h" -#include "GPU/GLES/FramebufferManagerGLES.h" +#include "GPU/Common/FramebufferCommon.h" static const int leftColumnWidth = 200; static const float orgRatio = 1.764706f; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 4c6cfd6633..bbee8c3b28 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -49,8 +49,10 @@ #include "Core/System.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" -#include "GPU/GLES/FramebufferManagerGLES.h" +#include "GPU/Common/FramebufferCommon.h" +#if !PPSSPP_PLATFORM(UWP) #include "GPU/Vulkan/DebugVisVulkan.h" +#endif #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceSas.h" @@ -78,9 +80,6 @@ #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) #include "Windows/MainWindow.h" #endif -#if !PPSSPP_PLATFORM(UWP) -#include "gfx/gl_common.h" -#endif #ifndef MOBILE_DEVICE static AVIDump avi; @@ -255,7 +254,7 @@ void EmuScreen::bootComplete() { #if !PPSSPP_PLATFORM(UWP) if (GetGPUBackend() == GPUBackend::OPENGL) { - const char *renderer = (const char*)glGetString(GL_RENDERER); + const char *renderer = gl_extensions.model; if (strstr(renderer, "Chainfire3D") != 0) { osm.Show(sc->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true); } else if (strstr(renderer, "GLTools") != 0) { @@ -894,14 +893,23 @@ void EmuScreen::CreateViews() { root_->Add(new OnScreenMessagesView(new AnchorLayoutParams((Size)bounds.w, (Size)bounds.h))); GameInfoBGView *loadingBG = root_->Add(new GameInfoBGView(gamePath_, new AnchorLayoutParams(FILL_PARENT, FILL_PARENT))); - TextView *loadingTextView = root_->Add(new TextView(sc->T("Loading game..."), new AnchorLayoutParams(bounds.centerX(), bounds.centerY(), NONE, NONE, true))); + TextView *loadingTextView = root_->Add(new TextView(sc->T(PSP_GetLoading()), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 40, true))); + static const int symbols[4] = { + I_CROSS, + I_CIRCLE, + I_SQUARE, + I_TRIANGLE + }; + Spinner *loadingSpinner = root_->Add(new Spinner(symbols, ARRAY_SIZE(symbols), new AnchorLayoutParams(NONE, NONE, 45, 45, true))); + loadingSpinner_ = loadingSpinner; loadingTextView->SetShadow(true); - loadingView_ = loadingTextView; + loadingTextView_ = loadingTextView; loadingViewColor_ = loadingTextView->AddTween(new CallbackColorTween(0x00FFFFFF, 0x00FFFFFF, 0.2f, &bezierEaseInOut)); - loadingViewColor_->SetCallback([loadingBG, loadingTextView](View *v, uint32_t c) { + loadingViewColor_->SetCallback([loadingBG, loadingTextView, loadingSpinner](View *v, uint32_t c) { loadingBG->SetColor(c & 0xFFC0C0C0); loadingTextView->SetTextColor(c); + loadingSpinner->SetColor(alphaMul(c, 0.7f)); }); loadingViewColor_->Persist(); @@ -1133,6 +1141,10 @@ void EmuScreen::render() { DrawContext *thin3d = screenManager()->getDrawContext(); if (invalid_) { + // Loading, or after shutdown? + if (loadingTextView_->GetVisibility() == UI::V_VISIBLE) + loadingTextView_->SetText(PSP_GetLoading()); + // It's possible this might be set outside PSP_RunLoopFor(). // In this case, we need to double check it here. checkPowerDown(); @@ -1184,7 +1196,7 @@ void EmuScreen::render() { if (invalid_) return; - const bool hasVisibleUI = !osm.IsEmpty() || saveStatePreview_->GetVisibility() != UI::V_GONE || g_Config.bShowTouchControls || loadingView_->GetVisibility() == UI::V_VISIBLE; + const bool hasVisibleUI = !osm.IsEmpty() || saveStatePreview_->GetVisibility() != UI::V_GONE || g_Config.bShowTouchControls || loadingTextView_->GetVisibility() == UI::V_VISIBLE; const bool showDebugUI = g_Config.bShowDebugStats || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || g_Config.bShowFrameProfiler || g_Config.bSimpleFrameStats; if (hasVisibleUI || showDebugUI || g_Config.iShowFPSCounter != 0) { renderUI(); @@ -1213,7 +1225,7 @@ void EmuScreen::renderUI() { DrawContext *thin3d = screenManager()->getDrawContext(); UIContext *ctx = screenManager()->getUIContext(); - + ctx->BeginFrame(); // This sets up some important states but not the viewport. ctx->Begin(); @@ -1244,9 +1256,11 @@ void EmuScreen::renderUI() { DrawFPS(draw2d, ctx->GetBounds()); } +#if !PPSSPP_PLATFORM(UWP) if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN && g_Config.bShowAllocatorDebug) { DrawAllocatorVis(ctx, gpu); } +#endif if ((g_Config.bShowFrameProfiler || g_Config.bSimpleFrameStats) && !invalid_) { DrawProfile(*ctx); diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 1745e8728c..c5f95d515b 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -98,7 +98,8 @@ private: AsyncImageFileView *saveStatePreview_; int saveStateSlot_; - UI::View *loadingView_ = nullptr; UI::CallbackColorTween *loadingViewColor_ = nullptr; UI::VisibilityTween *loadingViewVisible_ = nullptr; + UI::Spinner *loadingSpinner_ = nullptr; + UI::TextView *loadingTextView_ = nullptr; }; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 83b97f2b72..63e9c6efb9 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -460,13 +460,13 @@ handleELF: std::string screenshot_jpg = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.jpg"; std::string screenshot_png = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.png"; // Try using png/jpg screenshots first - if (File::Exists(screenshot_png)) + if (File::Exists(screenshot_png)) { readFileToString(false, screenshot_png.c_str(), info_->icon.data); - else if (File::Exists(screenshot_jpg)) + } else if (File::Exists(screenshot_jpg)) { readFileToString(false, screenshot_jpg.c_str(), info_->icon.data); - else { + } else { // Read standard icon - DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF"); + VERBOSE_LOG(LOADER, "Loading unknown.png because there was an ELF"); ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); } info_->icon.dataLoaded = true; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4ed3a5437d..1b2479c4a5 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -54,7 +54,7 @@ #include "Core/Reporting.h" #include "android/jni/TestRunner.h" #include "GPU/GPUInterface.h" -#include "GPU/GLES/FramebufferManagerGLES.h" +#include "GPU/Common/FramebufferCommon.h" #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) #pragma warning(disable:4091) // workaround bug in VS2015 headers @@ -63,10 +63,6 @@ #include "Windows/W32Util/ShellUtil.h" #endif -#if !PPSSPP_PLATFORM(UWP) -#include "gfx/gl_common.h" -#endif - extern bool VulkanMayBeAvailable(); GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore) @@ -85,8 +81,7 @@ bool CheckSupportInstancedTessellationGLES() { return true; #else // TODO: Make work with non-GL backends - int maxVertexTextureImageUnits; - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); + int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; bool vertexTexture = maxVertexTextureImageUnits >= 3; // At least 3 for hardware tessellation bool canUseInstanceID = gl_extensions.EXT_draw_instanced || gl_extensions.ARB_draw_instanced; @@ -100,7 +95,7 @@ bool CheckSupportInstancedTessellationGLES() { #endif } -bool IsBackendSupportHWTess() { +bool DoesBackendSupportHWTess() { switch (GetGPUBackend()) { case GPUBackend::OPENGL: return CheckSupportInstancedTessellationGLES(); @@ -310,13 +305,6 @@ void GameSettingsScreen::CreateViews() { hwTransform->OnClick.Handle(this, &GameSettingsScreen::OnHardwareTransform); hwTransform->SetDisabledPtr(&g_Config.bSoftwareRendering); - CheckBox *swSkin = graphicsSettings->Add(new CheckBox(&g_Config.bSoftwareSkinning, gr->T("Software Skinning"))); - swSkin->OnClick.Add([=](EventParams &e) { - settingInfo_->Show(gr->T("SoftwareSkinning Tip", "Combine skinned model draws on the CPU, faster in most games"), e.v); - return UI::EVENT_CONTINUE; - }); - swSkin->SetDisabledPtr(&g_Config.bSoftwareRendering); - CheckBox *vtxCache = graphicsSettings->Add(new CheckBox(&g_Config.bVertexCache, gr->T("Vertex Cache"))); vtxCache->OnClick.Add([=](EventParams &e) { settingInfo_->Show(gr->T("VertexCache Tip", "Faster, but may cause temporary flicker"), e.v); @@ -360,7 +348,7 @@ void GameSettingsScreen::CreateViews() { settingInfo_->Show(gr->T("HardwareTessellation Tip", "Uses hardware to make curves, always uses a fixed quality"), e.v); return UI::EVENT_CONTINUE; }); - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; tessellationHW->SetEnabledPtr(&tessHWEnable_); } @@ -689,8 +677,8 @@ void GameSettingsScreen::CreateViews() { #if PPSSPP_PLATFORM(ANDROID) if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_MOBILE) { - static const char *screenRotation[] = {"Landscape", "Portrait", "Landscape Reversed", "Portrait Reversed"}; - PopupMultiChoice *rot = systemSettings->Add(new PopupMultiChoice(&g_Config.iScreenRotation, co->T("Screen Rotation"), screenRotation, 1, ARRAY_SIZE(screenRotation), co->GetName(), screenManager())); + static const char *screenRotation[] = {"Auto", "Landscape", "Portrait", "Landscape Reversed", "Portrait Reversed", "Landscape Auto"}; + PopupMultiChoice *rot = systemSettings->Add(new PopupMultiChoice(&g_Config.iScreenRotation, co->T("Screen Rotation"), screenRotation, 0, ARRAY_SIZE(screenRotation), co->GetName(), screenManager())); rot->OnChoice.Handle(this, &GameSettingsScreen::OnScreenRotation); if (System_GetPropertyBool(SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE)) { @@ -832,13 +820,13 @@ UI::EventReturn GameSettingsScreen::OnSoftwareRendering(UI::EventParams &e) { postProcEnable_ = !g_Config.bSoftwareRendering && (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); resolutionEnable_ = !g_Config.bSoftwareRendering && (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); bloomHackEnable_ = !g_Config.bSoftwareRendering && (g_Config.iInternalResolution != 1); - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; return UI::EVENT_DONE; } UI::EventReturn GameSettingsScreen::OnHardwareTransform(UI::EventParams &e) { vtxCacheEnable_ = !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; return UI::EVENT_DONE; } diff --git a/UI/HostTypes.h b/UI/HostTypes.h index 102d583ce7..e489aa668d 100644 --- a/UI/HostTypes.h +++ b/UI/HostTypes.h @@ -20,11 +20,6 @@ #include "Core/Host.h" #include "UI/OnScreenDisplay.h" -#if !defined(MOBILE_DEVICE) && defined(USING_QT_UI) -#include "Core/Debugger/SymbolMap.h" -#include "Qt/mainwindow.h" -#endif - class NativeHost : public Host { public: NativeHost() {} @@ -58,112 +53,3 @@ public: NativeMessageReceived(message.c_str(), value.c_str()); } }; - -#if !defined(MOBILE_DEVICE) && defined(USING_QT_UI) -static const char* SymbolMapFilename(std::string currentFilename) -{ - std::string result = currentFilename; - size_t dot = result.rfind('.'); - if (dot == result.npos) - return (result + ".map").c_str(); - - result.replace(dot, result.npos, ".map"); - return result.c_str(); -} - -class QtHost : public Host { -public: - QtHost(MainWindow *mainWindow_) - { - mainWindow = mainWindow_; - m_GPUStep = false; - m_GPUFlag = 0; - } - - virtual void UpdateUI() override { - mainWindow->updateMenus(); - } - - virtual void UpdateMemView() override { - if(mainWindow->GetDialogMemory()) - mainWindow->GetDialogMemory()->Update(); - } - virtual void UpdateDisassembly() override { - if(mainWindow->GetDialogDisasm()) - mainWindow->GetDialogDisasm()->Update(); - if(mainWindow->GetDialogDisplaylist()) - mainWindow->GetDialogDisplaylist()->Update(); - } - - virtual void SetDebugMode(bool mode) override { - if(mainWindow->GetDialogDisasm()) - mainWindow->GetDialogDisasm()->SetDebugMode(mode); - } - - virtual bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; } - virtual void ShutdownGraphics() override {} - - virtual void InitSound() override; - virtual void UpdateSound() override {} - virtual void ShutdownSound(); - - // this is sent from EMU thread! Make sure that Host handles it properly! - virtual void BootDone() { - g_symbolMap->SortSymbols(); - mainWindow->Boot(); - } - - virtual bool IsDebuggingEnabled() { -#ifdef _DEBUG - return true; -#else - return false; -#endif - } - virtual bool AttemptLoadSymbolMap() { - return g_symbolMap->LoadSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart)); - } - virtual void PrepareShutdown() { - g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart)); - } - virtual void ResetSymbolMap() {} - virtual void AddSymbol(std::string name, u32 addr, u32 size, int type=0) {} - virtual void SetWindowTitle(const char *message) { - QString title = "PPSSPP " + QString(PPSSPP_GIT_VERSION) + " - " + QString::fromUtf8(message); - - mainWindow->setWindowTitle(title); - } - - void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override { - osm.Show(message, duration, color, -1, true, id); - } - - void SendUIMessage(const std::string &message, const std::string &value) override { - NativeMessageReceived(message.c_str(), value.c_str()); - } - - bool GPUDebuggingActive() - { - auto dialogDisplayList = mainWindow->GetDialogDisplaylist(); - if (dialogDisplayList && dialogDisplayList->isVisible()) - { - if (m_GPUStep && m_GPUFlag == -1) - m_GPUFlag = 0; - - return true; - } - return false; - } - void SetGPUStep(bool value, int flag = 0, u32 data = 0) - { - m_GPUStep = value; - m_GPUFlag = flag; - m_GPUData = data; - } -private: - MainWindow* mainWindow; - bool m_GPUStep; - int m_GPUFlag; - u32 m_GPUData; -}; -#endif diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 9671289f63..7dad059b0b 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -71,6 +71,8 @@ static const uint32_t colors[4] = { static std::unique_ptr bgTexture; +static bool backgroundInited; + void UIBackgroundInit(UIContext &dc) { const std::string bgPng = GetSysDirectory(DIRECTORY_SYSTEM) + "background.png"; const std::string bgJpg = GetSysDirectory(DIRECTORY_SYSTEM) + "background.jpg"; @@ -82,9 +84,15 @@ void UIBackgroundInit(UIContext &dc) { void UIBackgroundShutdown() { bgTexture.reset(nullptr); + backgroundInited = false; } void DrawBackground(UIContext &dc, float alpha) { + if (!backgroundInited) { + UIBackgroundInit(dc); + backgroundInited = true; + } + static float xbase[100] = {0}; static float ybase[100] = {0}; float xres = dc.GetBounds().w; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index e961e2ba1e..17a64dc2a9 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -101,6 +101,10 @@ #include "Common/KeyMap.h" #endif +#if !defined(MOBILE_DEVICE) && defined(USING_QT_UI) +#include "Qt/QtHost.h" +#endif + // The new UI framework, for initialization static UI::Theme ui_theme; @@ -123,8 +127,6 @@ static UI::Theme ui_theme; #include "android/android-ndk-profiler/prof.h" #endif -std::unique_ptr uiTexture; - ScreenManager *screenManager; std::string config_filename; @@ -622,16 +624,6 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { UIThemeInit(); - uiTexture = CreateTextureFromFile(g_draw, "ui_atlas.zim", ImageFileType::ZIM); - if (!uiTexture) { - PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); - ELOG("Failed to load ui_atlas.zim"); -#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) - UINT ExitCode = 0; - ExitProcess(ExitCode); -#endif - } - uiContext = new UIContext(); uiContext->theme = &ui_theme; @@ -676,8 +668,6 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { screenManager->setDrawContext(g_draw); screenManager->setPostRenderCallback(&RenderOverlays, nullptr); - UIBackgroundInit(*uiContext); - #ifdef _WIN32 winAudioBackend = CreateAudioBackend((AudioBackendType)g_Config.iAudioBackend); #if PPSSPP_PLATFORM(UWP) @@ -714,8 +704,6 @@ void NativeShutdownGraphics() { UIBackgroundShutdown(); - uiTexture.reset(nullptr); - delete uiContext; uiContext = nullptr; @@ -804,10 +792,6 @@ void RenderOverlays(UIContext *dc, void *userdata) { void NativeRender(GraphicsContext *graphicsContext) { g_GameManager.Update(); - // If uitexture gets reloaded, make sure we use the latest one. - // Not sure this happens anymore now that we tear down all graphics on app switches... - uiContext->FrameSetup(uiTexture->GetTexture()); - float xres = dp_xres; float yres = dp_yres; @@ -1125,7 +1109,7 @@ void NativeShutdown() { #endif g_Config.Save(); - // Avoid shutting this down when restaring core. + // Avoid shutting this down when restarting core. if (!restarting) LogManager::Shutdown(); diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index ed22b92b60..345e26cf89 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -80,7 +80,7 @@ void AsyncImageFileView::SetFilename(std::string filename) { void AsyncImageFileView::Draw(UIContext &dc) { using namespace Draw; if (!texture_ && !textureFailed_ && !filename_.empty()) { - texture_ = std::move(CreateTextureFromFile(dc.GetDrawContext(), filename_.c_str(), DETECT, true)); + texture_ = CreateTextureFromFile(dc.GetDrawContext(), filename_.c_str(), DETECT, true); if (!texture_.get()) textureFailed_ = true; } diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 6ee742751b..d934f956cf 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -131,8 +131,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag if (image[i]) free(image[i]); } - - return true; + return texture_ != nullptr; } bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType type, bool generateMips) { @@ -162,7 +161,7 @@ std::unique_ptr CreateTextureFromFile(Draw::DrawContext *draw, c delete mtex; return std::unique_ptr(); } - return std::move(std::unique_ptr(mtex)); + return std::unique_ptr(mtex); } // TODO: Remove the code duplication between this and LoadFromFileData @@ -171,5 +170,5 @@ std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *dra return std::unique_ptr(); ManagedTexture *mtex = new ManagedTexture(draw); mtex->LoadFromFileData(data, size, type, generateMips); - return std::move(std::unique_ptr(mtex)); -} \ No newline at end of file + return std::unique_ptr(mtex); +} diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 28a28b69d3..c71b1e39ba 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -3,7 +3,6 @@ #include #include "thin3d/thin3d.h" -#include "Core/Config.h" enum ImageFileType { PNG, diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 828b6b150d..ac94b54c2e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index b4e4bb6ea9..2211777fa4 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index b7d1f40921..0d1bc445ea 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 @@ -313,6 +313,7 @@ + @@ -365,6 +366,7 @@ + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index fbb4d4939b..641d4feef0 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -160,6 +160,9 @@ Debugger + + Common + @@ -295,5 +298,8 @@ Debugger + + Common + \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 9db58ee9a8..e6e8d6a89f 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 @@ -338,7 +338,6 @@ - @@ -1170,7 +1169,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index d0abe95c90..6b58b4d5c1 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -451,9 +451,6 @@ data - - gfx - base @@ -725,8 +722,5 @@ data - - gfx - \ No newline at end of file diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 96d346b819..994871cff1 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -1,4 +1,4 @@ -#include "pch.h" +#include "pch.h" #include "PPSSPP_UWPMain.h" #include @@ -20,6 +20,7 @@ #include "net/resolve.h" #include "base/display.h" #include "thread/threadutil.h" +#include "thin3d/thin3d_create.h" #include "util/text/utf8.h" #include "Common/DirectXHelper.h" #include "NKCodeFromWindowsSystem.h" @@ -108,8 +109,7 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrSetAllLogLevels(LogTypes::LDEBUG); diff --git a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj index d36a6fec45..8e4ac9dfc2 100644 --- a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj +++ b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index 377dff98d5..7fda5b55f9 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 16f370ea04..4f6ef42475 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -46,10 +46,10 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 PPSSPP_UWP - 10.0.15063.0 + 10.0.16299.0 @@ -117,39 +117,39 @@ - + - + - + - + - + - + - + - + - + @@ -490,7 +490,7 @@ copy AssetsGold\*.* Assets /Y - + diff --git a/UWP/glslang_UWP/glslang_UWP.vcxproj b/UWP/glslang_UWP/glslang_UWP.vcxproj index a4b35f9bcd..841a94fd24 100644 --- a/UWP/glslang_UWP/glslang_UWP.vcxproj +++ b/UWP/glslang_UWP/glslang_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 @@ -302,6 +302,7 @@ + @@ -347,6 +348,7 @@ + @@ -403,4 +405,4 @@ - + \ No newline at end of file diff --git a/UWP/glslang_UWP/glslang_UWP.vcxproj.filters b/UWP/glslang_UWP/glslang_UWP.vcxproj.filters index 443bf3bd7d..9d3fc6da3c 100644 --- a/UWP/glslang_UWP/glslang_UWP.vcxproj.filters +++ b/UWP/glslang_UWP/glslang_UWP.vcxproj.filters @@ -160,6 +160,9 @@ OGLCompilersDLL + + glslang\MachineIndependent + @@ -317,5 +320,8 @@ OGLCompilersDLL + + glslang\MachineIndependent + - + \ No newline at end of file diff --git a/UWP/libkirk_UWP/libkirk_UWP.vcxproj b/UWP/libkirk_UWP/libkirk_UWP.vcxproj index 49ecaec065..d993e1145e 100644 --- a/UWP/libkirk_UWP/libkirk_UWP.vcxproj +++ b/UWP/libkirk_UWP/libkirk_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/UWP/zlib_UWP/zlib_UWP.vcxproj b/UWP/zlib_UWP/zlib_UWP.vcxproj index ce7b30285c..347bd1ea74 100644 --- a/UWP/zlib_UWP/zlib_UWP.vcxproj +++ b/UWP/zlib_UWP/zlib_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.10240.0 + 10.0.14393.0 10.0 - 10.0.15063.0 + 10.0.16299.0 diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 87ae5f1d17..03a8124725 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -10,6 +10,7 @@ #include "Common/Log.h" #include "Common/StringUtils.h" +#include "Common/GraphicsContext.h" #include "Windows/EmuThread.h" #include "Windows/W32Util/Misc.h" #include "Windows/MainWindow.h" @@ -23,52 +24,98 @@ #include "Core/Config.h" #include "thread/threadutil.h" -static std::mutex emuThreadLock; +enum class EmuThreadState { + DISABLED, + START_REQUESTED, + RUNNING, + QUIT_REQUESTED, + STOPPED, +}; + static std::thread emuThread; -static std::atomic emuThreadState; +static std::atomic emuThreadState((int)EmuThreadState::DISABLED); + +static std::thread mainThread; +static bool useEmuThread; +static std::string g_error_message; +static bool g_inLoop; extern std::vector GetWideCmdLine(); -enum EmuThreadStatus : int { - THREAD_NONE = 0, - THREAD_INIT, - THREAD_CORE_LOOP, - THREAD_SHUTDOWN, - THREAD_END, -}; +class GraphicsContext; +static GraphicsContext *g_graphicsContext; -void EmuThreadFunc(); +void EmuThreadFunc(GraphicsContext *graphicsContext); +void MainThreadFunc(); -void EmuThread_Start() { - std::lock_guard guard(emuThreadLock); - emuThread = std::thread(&EmuThreadFunc); +// On most other platforms, we let the "main" thread become the render thread and +// start a separate emu thread from that, if needed. Should probably switch to that +// to make it the same on all platforms. +void MainThread_Start(bool separateEmuThread) { + useEmuThread = separateEmuThread; + mainThread = std::thread(&MainThreadFunc); } -void EmuThread_Stop() { +void MainThread_Stop() { // Already stopped? - { - std::lock_guard guard(emuThreadLock); - if (emuThreadState == THREAD_END) - return; - } - UpdateUIState(UISTATE_EXIT); Core_Stop(); - Core_WaitInactive(800); - emuThread.join(); - - PostMessage(MainWindow::GetHWND(), MainWindow::WM_USER_UPDATE_UI, 0, 0); + mainThread.join(); } -bool EmuThread_Ready() { - return emuThreadState == THREAD_CORE_LOOP; +bool MainThread_Ready() { + return g_inLoop; } -void EmuThreadFunc() { - emuThreadState = THREAD_INIT; - +static void EmuThreadFunc(GraphicsContext *graphicsContext) { setCurrentThreadName("Emu"); + // There's no real requirement that NativeInit happen on this thread. + // We just call the update/render loop here. + emuThreadState = (int)EmuThreadState::RUNNING; + + NativeInitGraphics(graphicsContext); + + while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { + // We're here again, so the game quit. Restart Core_Run() which controls the UI. + // This way they can load a new game. + if (!Core_IsActive()) + UpdateUIState(UISTATE_MENU); + Core_Run(g_graphicsContext); + } + + emuThreadState = (int)EmuThreadState::STOPPED; + + NativeShutdownGraphics(); + + // Ask the main thread to stop. This prevents a hang on a race condition. + graphicsContext->StopThread(); +} + +static void EmuThreadStart(GraphicsContext *graphicsContext) { + emuThreadState = (int)EmuThreadState::START_REQUESTED; + emuThread = std::thread(&EmuThreadFunc, graphicsContext); +} + +static void EmuThreadStop() { + emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; +} + +static void EmuThreadJoin() { + emuThread.join(); + emuThread = std::thread(); + ILOG("EmuThreadJoin - joined"); +} + +void MainThreadFunc() { + if (useEmuThread) { + // We'll start up a separate thread we'll call Emu + setCurrentThreadName("Render"); + } else { + // This is both Emu and Render. + setCurrentThreadName("Emu"); + } + host = new WindowsHost(MainWindow::GetHInstance(), MainWindow::GetHWND(), MainWindow::GetDisplayHWND()); host->SetWindowTitle(nullptr); @@ -87,10 +134,15 @@ void EmuThreadFunc() { host->UpdateUI(); - GraphicsContext *graphicsContext = nullptr; - std::string error_string; - if (!host->InitGraphics(&error_string, &graphicsContext)) { + bool success = host->InitGraphics(&error_string, &g_graphicsContext); + + if (success) { + // Main thread is the render thread. + success = g_graphicsContext->InitFromRenderThread(&error_string); + } + + if (!success) { // Before anything: are we restarting right now? if (performingRestart) { // Okay, switching graphics didn't work out. Probably a driver bug - fallback to restart. @@ -139,8 +191,12 @@ void EmuThreadFunc() { exit(1); } - NativeInitGraphics(graphicsContext); - NativeResized(); + GraphicsContext *graphicsContext = g_graphicsContext; + + if (!useEmuThread) { + NativeInitGraphics(graphicsContext); + NativeResized(); + } INFO_LOG(BOOT, "Done."); _dbg_update_(); @@ -150,29 +206,63 @@ void EmuThreadFunc() { goto shutdown; } - emuThreadState = THREAD_CORE_LOOP; + g_inLoop = true; + + if (useEmuThread) { + EmuThreadStart(graphicsContext); + } + graphicsContext->ThreadStart(); if (g_Config.bBrowse) PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); - Core_EnableStepping(FALSE); + Core_EnableStepping(false); - while (GetUIState() != UISTATE_EXIT) { - // We're here again, so the game quit. Restart Core_Run() which controls the UI. - // This way they can load a new game. - if (!Core_IsActive()) - UpdateUIState(UISTATE_MENU); - Core_Run(graphicsContext); + if (useEmuThread) { + while (emuThreadState != (int)EmuThreadState::DISABLED) { + graphicsContext->ThreadFrame(); + if (GetUIState() == UISTATE_EXIT) { + break; + } + } + } else { + while (GetUIState() != UISTATE_EXIT) { + // We're here again, so the game quit. Restart Core_Run() which controls the UI. + // This way they can load a new game. + if (!Core_IsActive()) + UpdateUIState(UISTATE_MENU); + Core_Run(g_graphicsContext); + } + } + Core_Stop(); + if (!useEmuThread) { + // Process the shutdown. Without this, non-GL delays 800ms on shutdown. + Core_Run(g_graphicsContext); + } + Core_WaitInactive(800); + + g_inLoop = false; + + if (useEmuThread) { + EmuThreadStop(); + while (graphicsContext->ThreadFrame()) { + // Need to keep eating frames to allow the EmuThread to exit correctly. + continue; + } + EmuThreadJoin(); } shutdown: - emuThreadState = THREAD_SHUTDOWN; - NativeShutdownGraphics(); + if (!useEmuThread) { + NativeShutdownGraphics(); + } + + g_graphicsContext->ThreadEnd(); + g_graphicsContext->ShutdownFromRenderThread(); // NativeShutdown deletes the graphics context through host->ShutdownGraphics(). NativeShutdown(); - emuThreadState = THREAD_END; + + PostMessage(MainWindow::GetHWND(), MainWindow::WM_USER_UPDATE_UI, 0, 0); } - - diff --git a/Windows/EmuThread.h b/Windows/EmuThread.h index ed1a9df08d..bc04bc3f06 100644 --- a/Windows/EmuThread.h +++ b/Windows/EmuThread.h @@ -17,6 +17,6 @@ #pragma once -void EmuThread_Start(); -void EmuThread_Stop(); -bool EmuThread_Ready(); +void MainThread_Start(bool separateRenderThread); +void MainThread_Stop(); +bool MainThread_Ready(); diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index b8ec01bd4b..e42ddd2eed 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -14,6 +14,7 @@ #include "Windows/GPU/D3D11Context.h" #include "Windows/W32Util/Misc.h" #include "thin3d/thin3d.h" +#include "thin3d/thin3d_create.h" #include "thin3d/d3d11_loader.h" #if PPSSPP_PLATFORM(UWP) diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index 19f772fb91..ad71c0a48d 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -14,6 +14,7 @@ #include "Windows/GPU/D3D9Context.h" #include "Windows/W32Util/Misc.h" #include "thin3d/thin3d.h" +#include "thin3d/thin3d_create.h" #include "thin3d/d3dx9_loader.h" void D3D9Context::SwapBuffers() { diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 3b9707ca4c..8feae44307 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -21,6 +21,8 @@ #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d_create.h" +#include "thin3d/GLRenderManager.h" #include "GL/gl.h" #include "GL/wglew.h" #include "Core/Config.h" @@ -34,7 +36,8 @@ #include "Windows/GPU/WindowsGLContext.h" void WindowsGLContext::SwapBuffers() { - ::SwapBuffers(hDC); + // We no longer call RenderManager::Swap here, it's handled by the render thread, which + // we're not on here. // Used during fullscreen switching to prevent rendering. if (pauseRequested) { @@ -46,10 +49,6 @@ void WindowsGLContext::SwapBuffers() { } pauseRequested = false; } - - // According to some sources, doing this *after* swapbuffers can reduce frame latency - // at a large performance cost. So let's not. - // glFinish(); } void WindowsGLContext::Pause() { @@ -96,7 +95,7 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu case GL_DEBUG_SOURCE_APPLICATION_ARB: sourceFmt = "APPLICATION"; break; case GL_DEBUG_SOURCE_OTHER_ARB: sourceFmt = "OTHER"; break; } - _snprintf(sourceStr, 32, sourceFmt, source); + snprintf(sourceStr, sizeof(sourceStr), sourceFmt, source); char typeStr[32]; const char *typeFmt = "UNDEFINED(0x%04X)"; @@ -108,30 +107,34 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu case GL_DEBUG_TYPE_PERFORMANCE_ARB: typeFmt = "PERFORMANCE"; break; case GL_DEBUG_TYPE_OTHER_ARB: typeFmt = "OTHER"; break; } - _snprintf(typeStr, 32, typeFmt, type); + snprintf(typeStr, sizeof(typeStr), typeFmt, type); char severityStr[32]; const char *severityFmt = "UNDEFINED"; - switch(severity) - { - case GL_DEBUG_SEVERITY_HIGH_ARB: severityFmt = "HIGH"; break; + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH_ARB: severityFmt = "HIGH"; break; case GL_DEBUG_SEVERITY_MEDIUM_ARB: severityFmt = "MEDIUM"; break; case GL_DEBUG_SEVERITY_LOW_ARB: severityFmt = "LOW"; break; } - _snprintf(severityStr, 32, severityFmt, severity); - - _snprintf(outStr, outStrSize, "OpenGL: %s [source=%s type=%s severity=%s id=%d]", msg, sourceStr, typeStr, severityStr, id); + snprintf(severityStr, sizeof(severityStr), severityFmt, severity); + snprintf(outStr, outStrSize, "OpenGL: %s [source=%s type=%s severity=%s id=%d]\n", msg, sourceStr, typeStr, severityStr, id); } void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) { (void)length; - FILE *outFile = (FILE*)userParam; - char finalMessage[256]; - FormatDebugOutputARB(finalMessage, 256, source, type, id, severity, message); + FILE *outFile = (FILE *)userParam; + char finalMessage[1024]; + FormatDebugOutputARB(finalMessage, sizeof(finalMessage), source, type, id, severity, message); OutputDebugStringA(finalMessage); + // Truncate the \n before passing to our log functions. + size_t len = strlen(finalMessage); + if (len) { + finalMessage[len - 1] = '\0'; + } + switch (type) { case GL_DEBUG_TYPE_ERROR_ARB: case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: @@ -153,8 +156,15 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_message) { glslang::InitializeProcess(); + + hInst_ = hInst; + hWnd_ = window; + *error_message = "ok"; + return true; +} + +bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { *error_message = "ok"; - hWnd = window; GLuint PixelFormat; // TODO: Change to use WGL_ARB_pixel_format instead @@ -179,14 +189,14 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes 0, 0, 0 // Layer Masks Ignored }; - hDC = GetDC(hWnd); + hDC = GetDC(hWnd_); if (!hDC) { *error_message = "Failed to get a device context."; return false; // Return FALSE } - if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { + if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { *error_message = "Can't find a suitable PixelFormat."; return false; } @@ -196,7 +206,7 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes return false; } - if (!(hRC = wglCreateContext(hDC))) { + if (!(hRC = wglCreateContext(hDC))) { *error_message = "Can't create a GL rendering context."; return false; } @@ -225,7 +235,7 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes HDC dc = GetDC(NULL); u32 colour_depth = GetDeviceCaps(dc, BITSPIXEL); ReleaseDC(NULL, dc); - if (colour_depth != 32){ + if (colour_depth != 32) { MessageBox(0, L"Please switch your display to 32-bit colour mode", L"OpenGL Error", MB_OK); ExitProcess(1); } @@ -239,7 +249,7 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes std::wstring title = ConvertUTF8ToWString(err->T("OpenGLDriverError", "OpenGL driver error")); std::wstring combined = versionDetected + error; - bool yes = IDYES == MessageBox(hWnd, combined.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); + bool yes = IDYES == MessageBox(hWnd_, combined.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { // Change the config to D3D and restart. @@ -322,8 +332,6 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes hRC = m_hrc; - SwapInterval(0); - if (g_Config.bGfxDebugOutput) { if (wglewIsSupported("GL_KHR_debug") == 1) { glGetError(); @@ -362,20 +370,31 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes CheckGLExtensions(); draw_ = Draw::T3DCreateGLContext(); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these. assert(success); + renderManager_->SetSwapFunction([&]() {::SwapBuffers(hDC); }); + if (wglSwapIntervalEXT) { + // glew loads wglSwapIntervalEXT if available + renderManager_->SetSwapIntervalFunction([&](int interval) { + wglSwapIntervalEXT(interval); + }); + } CHECK_GL_ERROR_IF_DEBUG(); return true; // Success } void WindowsGLContext::SwapInterval(int interval) { - // glew loads wglSwapIntervalEXT if available - if (wglSwapIntervalEXT) - wglSwapIntervalEXT(interval); + // Delegate to the render manager to make sure it's done on the right thread. + renderManager_->SwapInterval(interval); } void WindowsGLContext::Shutdown() { + glslang::FinalizeProcess(); +} + +void WindowsGLContext::ShutdownFromRenderThread() { delete draw_; draw_ = nullptr; CloseHandle(pauseEvent); @@ -383,26 +402,42 @@ void WindowsGLContext::Shutdown() { if (hRC) { // Are we able to release the DC and RC contexts? if (!wglMakeCurrent(NULL,NULL)) { - MessageBox(NULL,L"Release of DC and RC failed.", L"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, L"Release of DC and RC failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } // Are we able to delete the RC? if (!wglDeleteContext(hRC)) { - MessageBox(NULL,L"Release rendering context failed.", L"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, L"Release rendering context failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } hRC = NULL; } - if (hDC && !ReleaseDC(hWnd,hDC)) { + if (hDC && !ReleaseDC(hWnd_, hDC)) { DWORD err = GetLastError(); if (err != ERROR_DC_NOT_FOUND) { - MessageBox(NULL,L"Release device context failed.", L"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, L"Release device context failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } hDC = NULL; } - hWnd = NULL; - glslang::FinalizeProcess(); + hWnd_ = NULL; } void WindowsGLContext::Resize() { } + +void WindowsGLContext::ThreadStart() { + renderManager_->ThreadStart(); +} + +bool WindowsGLContext::ThreadFrame() { + return renderManager_->ThreadFrame(); +} + +void WindowsGLContext::ThreadEnd() { + renderManager_->ThreadEnd(); +} + +void WindowsGLContext::StopThread() { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); +} diff --git a/Windows/GPU/WindowsGLContext.h b/Windows/GPU/WindowsGLContext.h index 3fe2f9f4a8..1303aece79 100644 --- a/Windows/GPU/WindowsGLContext.h +++ b/Windows/GPU/WindowsGLContext.h @@ -7,9 +7,15 @@ namespace Draw { class DrawContext; } +class GLRenderManager; + class WindowsGLContext : public WindowsGraphicsContext { public: bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override; + + bool InitFromRenderThread(std::string *errorMessage) override; + void ShutdownFromRenderThread() override; + void Shutdown() override; void SwapInterval(int interval) override; void SwapBuffers() override; @@ -18,16 +24,23 @@ public: // not the rendering thread or CPU thread. void Pause() override; void Resume() override; - void Resize() override; + void ThreadStart() override; + void ThreadEnd() override; + bool ThreadFrame() override; + void StopThread() override; + Draw::DrawContext *GetDrawContext() override { return draw_; } private: + bool renderThread_; Draw::DrawContext *draw_; + GLRenderManager *renderManager_; + HINSTANCE hInst_; HDC hDC; // Private GDI Device Context HGLRC hRC; // Permanent Rendering Context - HWND hWnd; // Holds Our Window Handle + HWND hWnd_; // Holds Our Window Handle volatile bool pauseRequested; volatile bool resumeRequested; HANDLE pauseEvent; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 67e6f51954..0e71ace543 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -58,6 +58,7 @@ #include "base/stringutil.h" #include "thin3d/thin3d.h" +#include "thin3d/thin3d_create.h" #include "thin3d/VulkanRenderManager.h" #include "util/text/parsers.h" #include "Windows/GPU/WindowsVulkanContext.h" diff --git a/Windows/MainThread.h b/Windows/MainThread.h new file mode 100644 index 0000000000..6f70f09bee --- /dev/null +++ b/Windows/MainThread.h @@ -0,0 +1 @@ +#pragma once diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index f56ade7bce..f15bcfe3a5 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -263,8 +263,6 @@ namespace MainWindow // Moves the internal display window to match the inner size of the main window. MoveWindow(hwndDisplay, 0, 0, width, height, TRUE); - INFO_LOG(SYSTEM, "New width/height: %dx%d", width, height); - // Setting pixelWidth to be too small could have odd consequences. if (width >= 4 && height >= 4) { // The framebuffer manager reads these once per frame, hopefully safe enough.. should really use a mutex or some @@ -273,7 +271,7 @@ namespace MainWindow PSP_CoreParameter().pixelHeight = height; } - INFO_LOG(SYSTEM, "Pixel width/height: %dx%d", PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DEBUG_LOG(SYSTEM, "Pixel width/height: %dx%d", PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); if (UpdateScreenScale(width, height)) { NativeMessageReceived("gpu_resized", ""); @@ -795,7 +793,7 @@ namespace MainWindow case WM_COMMAND: { - if (!EmuThread_Ready()) + if (!MainThread_Ready()) return DefWindowProc(hWnd, message, wParam, lParam); MainWindowMenu_Process(hWnd, wParam); @@ -844,7 +842,7 @@ namespace MainWindow case WM_DROPFILES: { - if (!EmuThread_Ready()) + if (!MainThread_Ready()) return DefWindowProc(hWnd, message, wParam, lParam); HDROP hdrop = (HDROP)wParam; @@ -866,9 +864,7 @@ namespace MainWindow case WM_CLOSE: InputDevice::StopPolling(); - EmuThread_Stop(); WindowsRawInput::Shutdown(); - return DefWindowProc(hWnd,message,wParam,lParam); case WM_DESTROY: @@ -914,10 +910,10 @@ namespace MainWindow case WM_USER_RESTART_EMUTHREAD: NativeSetRestarting(); InputDevice::StopPolling(); - EmuThread_Stop(); + MainThread_Stop(); coreState = CORE_POWERUP; ResetUIState(); - EmuThread_Start(); + MainThread_Start(g_Config.iGPUBackend == (int)GPUBackend::OPENGL); InputDevice::BeginPolling(); break; diff --git a/Windows/main.cpp b/Windows/main.cpp index 4d6a28c849..0e9259b93d 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -529,8 +529,10 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin MainWindow::Minimize(); } - // Emu thread is always running! - EmuThread_Start(); + // Emu thread (and render thread, if any) is always running! + // Only OpenGL uses an externally managed render thread (due to GL's single-threaded context design). Vulkan + // manages its own render thread. + MainThread_Start(g_Config.iGPUBackend == (int)GPUBackend::OPENGL); InputDevice::BeginPolling(); HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS); @@ -569,10 +571,8 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin break; } - if (!TranslateAccelerator(wnd, accel, &msg)) - { - if (!DialogManager::IsDialogMessage(&msg)) - { + if (!TranslateAccelerator(wnd, accel, &msg)) { + if (!DialogManager::IsDialogMessage(&msg)) { //and finally translate and dispatch TranslateMessage(&msg); DispatchMessage(&msg); @@ -580,13 +580,12 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin } } + MainThread_Stop(); + VFSShutdown(); InputDevice::StopPolling(); - // The emuthread calls NativeShutdown when shutting down. - EmuThread_Stop(); - MainWindow::DestroyDebugWindows(); DialogManager::DestroyAll(); timeEndPeriod(1); diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 8742085535..1a40994cf7 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -1,18 +1,23 @@ +#include #include "base/logging.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d_create.h" #include "AndroidEGLContext.h" #include "GL/GLInterface/EGLAndroid.h" #include "Core/System.h" -bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, int backbufferHeight, int backbufferFormat, int androidVersion) { +bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { + ILOG("AndroidEGLGraphicsContext::Init()"); wnd_ = wnd; gl = HostGL_CreateGLInterface(); if (!gl) { ELOG("ERROR: Failed to create GL interface"); return false; } + int backbufferWidth = desiredBackbufferSizeX; + int backbufferHeight = desiredBackbufferSizeY; ILOG("EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight); // Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect... diff --git a/android/jni/AndroidEGLContext.h b/android/jni/AndroidEGLContext.h index efeafecf80..2bc9d5341c 100644 --- a/android/jni/AndroidEGLContext.h +++ b/android/jni/AndroidEGLContext.h @@ -6,7 +6,7 @@ class AndroidEGLGraphicsContext : public AndroidGraphicsContext { public: AndroidEGLGraphicsContext() : draw_(nullptr), wnd_(nullptr), gl(nullptr) {} - bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + bool InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; void Shutdown() override; void SwapBuffers() override; void SwapInterval(int interval) override {} @@ -14,6 +14,9 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } + bool Initialized() override { + return draw_ != nullptr; + } private: Draw::DrawContext *draw_; diff --git a/android/jni/AndroidGraphicsContext.h b/android/jni/AndroidGraphicsContext.h index 027be92505..50a213e68b 100644 --- a/android/jni/AndroidGraphicsContext.h +++ b/android/jni/AndroidGraphicsContext.h @@ -19,5 +19,8 @@ enum { class AndroidGraphicsContext : public GraphicsContext { public: - virtual bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) = 0; + // This is different than the base class function since on + // Android (EGL, Vulkan) we do have all this info on the render thread. + virtual bool InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) = 0; + virtual bool Initialized() = 0; }; diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index 8a97a62187..0f0937db08 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -1,19 +1,30 @@ +#include + #include "AndroidJavaGLContext.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "Core/System.h" AndroidJavaEGLGraphicsContext::AndroidJavaEGLGraphicsContext() { + SetGPUBackend(GPUBackend::OPENGL); +} + +bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { + ILOG("AndroidJavaEGLGraphicsContext::InitFromRenderThread"); CheckGLExtensions(); draw_ = Draw::T3DCreateGLContext(); - SetGPUBackend(GPUBackend::OPENGL); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); bool success = draw_->CreatePresets(); - assert(success); + return success; +} + +void AndroidJavaEGLGraphicsContext::ShutdownFromRenderThread() { + ILOG("AndroidJavaEGLGraphicsContext::Shutdown"); + renderManager_->WaitUntilQueueIdle(); + renderManager_ = nullptr; // owned by draw_. + delete draw_; + draw_ = nullptr; } void AndroidJavaEGLGraphicsContext::Shutdown() { - ILOG("AndroidJavaEGLGraphicsContext::Shutdown"); - delete draw_; - draw_ = nullptr; - NativeShutdownGraphics(); } diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h index 36e443e51d..7b47f58f3c 100644 --- a/android/jni/AndroidJavaGLContext.h +++ b/android/jni/AndroidJavaGLContext.h @@ -1,14 +1,30 @@ #pragma once +#include +#include +#include + #include "AndroidGraphicsContext.h" +#include "thin3d/GLRenderManager.h" +#include "thin3d/thin3d_create.h" // Doesn't do much. Just to fit in. -class AndroidJavaEGLGraphicsContext : public GraphicsContext { +class AndroidJavaEGLGraphicsContext : public AndroidGraphicsContext { public: AndroidJavaEGLGraphicsContext(); ~AndroidJavaEGLGraphicsContext() { delete draw_; } + + bool Initialized() override { + return draw_ != nullptr; + } + + // This performs the actual initialization, + bool InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + + void ShutdownFromRenderThread() override; + void Shutdown() override; void SwapBuffers() override {} void SwapInterval(int interval) override {} @@ -16,7 +32,26 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } + + void ThreadStart() override { + renderManager_->ThreadStart(); + } + + bool ThreadFrame() override { + return renderManager_->ThreadFrame(); + } + + void ThreadEnd() override { + renderManager_->ThreadEnd(); + } + + void StopThread() override { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); + } + private: - Draw::DrawContext *draw_; + Draw::DrawContext *draw_ = nullptr; + GLRenderManager *renderManager_ = nullptr; }; diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 99b21469be..4240bde18c 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -1,9 +1,12 @@ +#include + #include "AndroidVulkanContext.h" #include "base/NativeApp.h" #include "base/display.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" #include "thin3d/VulkanRenderManager.h" +#include "thin3d/thin3d_create.h" #include "util/text/parsers.h" #include "Core/Config.h" #include "Core/System.h" @@ -58,7 +61,8 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, loglevel = ANDROID_LOG_WARN; } - __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", pLayerPrefix, ObjTypeToString(objType), msgCode, pMsg); + __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", + pLayerPrefix, ObjTypeToString(objType), msgCode, pMsg); // false indicates that layer should not bail-out of an // API call that had validation failures. This may mean that the @@ -68,12 +72,15 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, return false; } +AndroidVulkanContext::AndroidVulkanContext() { +} + AndroidVulkanContext::~AndroidVulkanContext() { delete g_Vulkan; g_Vulkan = nullptr; } -bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { +bool AndroidVulkanContext::InitAPI() { ILOG("AndroidVulkanContext::Init"); init_glslang(); @@ -91,9 +98,11 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, info.app_name = "PPSSPP"; info.app_ver = gitVer.ToInteger(); info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED; - if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) { + VkResult res = g_Vulkan->CreateInstance(info); + if (res != VK_SUCCESS) { ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); System_SendMessage("toast", "No Vulkan compatible device found. Using OpenGL instead."); + VulkanSetAvailable(false); delete g_Vulkan; g_Vulkan = nullptr; return false; @@ -120,6 +129,10 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, g_Vulkan = nullptr; return false; } + return true; +} + +bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { int width = desiredBackbufferSizeX; int height = desiredBackbufferSizeY; if (!width || !height) { @@ -158,22 +171,24 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, return success; } -void AndroidVulkanContext::Shutdown() { +void AndroidVulkanContext::ShutdownFromRenderThread() { ILOG("AndroidVulkanContext::Shutdown"); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - ILOG("Calling NativeShutdownGraphics"); - NativeShutdownGraphics(); delete draw_; draw_ = nullptr; g_Vulkan->WaitUntilQueueIdle(); - g_Vulkan->DestroyObjects(); + g_Vulkan->PerformPendingDeletes(); + g_Vulkan->DestroyObjects(); // Also destroys the surface, a bit asymmetric + ILOG("Done with ShutdownFromRenderThread"); +} + +void AndroidVulkanContext::Shutdown() { + ILOG("Calling NativeShutdownGraphics"); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); - // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. - finalize_glslang(); ILOG("AndroidVulkanContext::Shutdown completed"); } diff --git a/android/jni/AndroidVulkanContext.h b/android/jni/AndroidVulkanContext.h index 8c48e09c92..adb47e2806 100644 --- a/android/jni/AndroidVulkanContext.h +++ b/android/jni/AndroidVulkanContext.h @@ -8,10 +8,14 @@ class VulkanContext; class AndroidVulkanContext : public AndroidGraphicsContext { public: - AndroidVulkanContext() : draw_(nullptr) {} + AndroidVulkanContext(); ~AndroidVulkanContext(); - bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + bool InitAPI(); + + bool InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + void ShutdownFromRenderThread() override; // Inverses InitFromRenderThread. + void Shutdown() override; void SwapInterval(int interval) override; void SwapBuffers() override; @@ -22,6 +26,10 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } + bool Initialized() override { + return draw_ != nullptr; + } + private: VulkanContext *g_Vulkan = nullptr; Draw::DrawContext *draw_ = nullptr; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 05306c22be..335230f3ef 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -50,9 +51,20 @@ #include "app-android.h" -JNIEnv *jniEnvMain; -JNIEnv *jniEnvGraphics; -JavaVM *javaVM; +bool useCPUThread = true; + +enum class EmuThreadState { + DISABLED, + START_REQUESTED, + RUNNING, + QUIT_REQUESTED, + STOPPED, +}; + +static std::thread emuThread; +static std::atomic emuThreadState((int)EmuThreadState::DISABLED); + +void UpdateRunLoopAndroid(JNIEnv *env); static AndroidAudioState *g_audioState; @@ -97,6 +109,12 @@ static int backbuffer_format; // Android PixelFormat enum static int desiredBackbufferSizeX; static int desiredBackbufferSizeY; +// Cache the class loader so we can use it from native threads. Required for TextAndroid. +JavaVM* gJvm = nullptr; +static jobject gClassLoader; +static jmethodID gFindClassMethod; + + static jmethodID postCommand; static jobject nativeActivity; static volatile bool exitRenderLoop; @@ -114,7 +132,96 @@ static bool javaGL = true; static std::string library_path; static std::map permissions; -GraphicsContext *graphicsContext; +AndroidGraphicsContext *graphicsContext; + +JNIEnv* getEnv() { + JNIEnv *env; + int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6); + if(status < 0) { + status = gJvm->AttachCurrentThread(&env, NULL); + if(status < 0) { + return nullptr; + } + } + return env; +} + +jclass findClass(const char* name) { + return static_cast(getEnv()->CallObjectMethod(gClassLoader, gFindClassMethod, getEnv()->NewStringUTF(name))); +} + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *pjvm, void *reserved) { + ILOG("JNI_OnLoad"); + gJvm = pjvm; // cache the JavaVM pointer + auto env = getEnv(); + //replace with one of your classes in the line below + auto randomClass = env->FindClass("org/ppsspp/ppsspp/NativeActivity"); + jclass classClass = env->GetObjectClass(randomClass); + auto classLoaderClass = env->FindClass("java/lang/ClassLoader"); + auto getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader", + "()Ljava/lang/ClassLoader;"); + gClassLoader = env->NewGlobalRef(env->CallObjectMethod(randomClass, getClassLoaderMethod)); + gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;"); + return JNI_VERSION_1_6; +} + +static void EmuThreadFunc() { + JNIEnv *env; + gJvm->AttachCurrentThread(&env, nullptr); + + setCurrentThreadName("Emu"); + ILOG("Entering emu thread"); + + // Wait for render loop to get started. + if (!graphicsContext || !graphicsContext->Initialized()) { + ILOG("Runloop: Waiting for displayInit..."); + while (!graphicsContext || !graphicsContext->Initialized()) { + sleep_ms(20); + } + } else { + ILOG("Runloop: Graphics context available! %p", graphicsContext); + } + NativeInitGraphics(graphicsContext); + + ILOG("Graphics initialized. Entering loop."); + + // There's no real requirement that NativeInit happen on this thread. + // We just call the update/render loop here. + emuThreadState = (int)EmuThreadState::RUNNING; + while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { + UpdateRunLoopAndroid(env); + } + emuThreadState = (int)EmuThreadState::STOPPED; + + NativeShutdownGraphics(); + + // Also ask the main thread to stop, so it doesn't hang waiting for a new frame. + graphicsContext->StopThread(); + + gJvm->DetachCurrentThread(); + ILOG("Leaving emu thread"); +} + +static void EmuThreadStart() { + ILOG("EmuThreadStart"); + emuThreadState = (int)EmuThreadState::START_REQUESTED; + emuThread = std::thread(&EmuThreadFunc); +} + +// Call EmuThreadStop first, then keep running the GPU (or eat commands) +// as long as emuThreadState isn't STOPPED and/or there are still things queued up. +// Only after that, call EmuThreadJoin. +static void EmuThreadStop() { + ILOG("EmuThreadStop - stopping..."); + emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; +} + +static void EmuThreadJoin() { + emuThread.join(); + emuThread = std::thread(); + ILOG("EmuThreadJoin - joined"); +} static void ProcessFrameCommands(JNIEnv *env); @@ -225,7 +332,6 @@ std::string GetJavaString(JNIEnv *env, jstring jstr) { extern "C" void Java_org_ppsspp_ppsspp_NativeActivity_registerCallbacks(JNIEnv *env, jobject obj) { nativeActivity = env->NewGlobalRef(obj); postCommand = env->GetMethodID(env->GetObjectClass(obj), "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V"); - ILOG("Got method ID to postCommand: %p", postCommand); } extern "C" void Java_org_ppsspp_ppsspp_NativeActivity_unregisterCallbacks(JNIEnv *env, jobject obj) { @@ -265,9 +371,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init (JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath, jstring jdataDir, jstring jexternalDir, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam, jint jAndroidVersion, jstring jboard) { - jniEnvMain = env; - env->GetJavaVM(&javaVM); - setCurrentThreadName("androidInit"); // Makes sure we get early permission grants. @@ -323,16 +426,49 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init if (shortcut_param.empty()) { const char *argv[2] = {app_name.c_str(), 0}; NativeInit(1, argv, user_data_path.c_str(), externalDir.c_str(), cacheDir.c_str()); - } - else { + } else { const char *argv[3] = {app_name.c_str(), shortcut_param.c_str(), 0}; NativeInit(2, argv, user_data_path.c_str(), externalDir.c_str(), cacheDir.c_str()); } +retry: // Now that we've loaded config, set javaGL. javaGL = NativeQueryConfig("androidJavaGL") == "true"; - ILOG("NativeApp.init() -- end"); + switch (g_Config.iGPUBackend) { + case (int)GPUBackend::OPENGL: + useCPUThread = true; + _assert_(javaGL); + ILOG("NativeApp.init() -- creating OpenGL context (JavaGL)"); + graphicsContext = new AndroidJavaEGLGraphicsContext(); + break; + case (int)GPUBackend::VULKAN: + { + ILOG("NativeApp.init() -- creating Vulkan context"); + useCPUThread = false; // The Vulkan render manager manages its own thread. + // We create and destroy the Vulkan graphics context in the "EGL" thread. + AndroidVulkanContext *ctx = new AndroidVulkanContext(); + if (!ctx->InitAPI()) { + ILOG("Failed to initialize Vulkan, switching to OpenGL"); + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + SetGPUBackend(GPUBackend::OPENGL); + goto retry; + } else { + graphicsContext = ctx; + } + break; + } + default: + ELOG("NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend); + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + goto retry; + // Crash(); + } + + if (useCPUThread) { + ILOG("NativeApp.init() - launching emu thread"); + EmuThreadStart(); + } } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) { @@ -381,9 +517,18 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_pause(JNIEnv *, jclass) { } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { + if (useCPUThread && graphicsContext) { + EmuThreadStop(); + while (graphicsContext->ThreadFrame()) { + continue; + } + EmuThreadJoin(); + } + ILOG("NativeApp.shutdown() -- begin"); if (renderer_inited) { ILOG("Shutting down renderer"); + // This will be from the wrong thread? :/ graphicsContext->Shutdown(); delete graphicsContext; graphicsContext = nullptr; @@ -401,32 +546,39 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { // JavaEGL extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { - // Need to get the local JNI env for the graphics thread. Used later in draw_text_android. - int res = javaVM->GetEnv((void **)&jniEnvGraphics, JNI_VERSION_1_6); - if (res != JNI_OK) { - ELOG("GetEnv failed: %d", res); - } - - if (javaGL && !graphicsContext) { - graphicsContext = new AndroidJavaEGLGraphicsContext(); - } else if (!graphicsContext) { - _assert_msg_(G3D, false, "No graphics context in displayInit?"); - } - + // We should be running on the render thread here. + std::string errorMessage; if (renderer_inited) { + // Would be really nice if we could get something on the GL thread immediately when shutting down... ILOG("NativeApp.displayInit() restoring"); - NativeShutdownGraphics(); - delete graphicsContext; + graphicsContext->ThreadEnd(); + if (useCPUThread) { + EmuThreadStop(); + while (graphicsContext->ThreadFrame()) { + continue; + } + EmuThreadJoin(); + } else { + NativeShutdownGraphics(); + } + graphicsContext->ShutdownFromRenderThread(); - graphicsContext = new AndroidJavaEGLGraphicsContext(); - NativeInitGraphics(graphicsContext); + ILOG("Shut down both threads. Now let's bring it up again!"); + + graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0); + if (useCPUThread) { + EmuThreadStart(); + } else { + NativeInitGraphics(graphicsContext); + } + graphicsContext->ThreadStart(); ILOG("Restored."); } else { ILOG("NativeApp.displayInit() first time"); - NativeInitGraphics(graphicsContext); + graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0); + graphicsContext->ThreadStart(); renderer_inited = true; } - NativeMessageReceived("recreateviews", ""); } @@ -470,29 +622,11 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv } } +void UpdateRunLoopAndroid(JNIEnv *env) { + NativeUpdate(); -// JavaEGL -extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, jobject obj) { - static bool hasSetThreadName = false; - if (!hasSetThreadName) { - hasSetThreadName = true; - setCurrentThreadName("AndroidRender"); - } - - if (renderer_inited) { - NativeUpdate(); - - NativeRender(graphicsContext); - time_update(); - } else { - ELOG("BAD: Ended up in nativeRender even though app has quit.%s", ""); - // Shouldn't really get here. Let's draw magenta. - // TODO: Should we have GL here? - glDepthMask(GL_TRUE); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClearColor(1.0, 0.0, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } + NativeRender(graphicsContext); + time_update(); std::lock_guard guard(frameCommandLock); if (!nativeActivity) { @@ -504,6 +638,21 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, ProcessFrameCommands(env); } +extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, jobject obj) { + static bool hasSetThreadName = false; + if (!hasSetThreadName) { + hasSetThreadName = true; + setCurrentThreadName("AndroidRender"); + } + + if (useCPUThread) { + // This is the "GPU thread". + graphicsContext->ThreadFrame(); + } else { + UpdateRunLoopAndroid(env); + } +} + void System_AskForPermission(SystemPermission permission) { switch (permission) { case SYSTEM_PERMISSION_STORAGE: @@ -768,18 +917,14 @@ static void ProcessFrameCommands(JNIEnv *env) { } extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { + // Needed for Vulkan, even if we're not using the old EGL path. + exitRenderLoop = false; // This is up here to prevent race conditions, in case we pause during init. renderLoopRunning = true; ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf); - // Need to get the local JNI env for the graphics thread. Used later in draw_text_android. - int res = javaVM->GetEnv((void **)&jniEnvGraphics, JNI_VERSION_1_6); - if (res != JNI_OK) { - ELOG("GetEnv failed: %d", res); - } - WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { @@ -793,14 +938,8 @@ retry: bool vulkan = g_Config.iGPUBackend == (int)GPUBackend::VULKAN; int tries = 0; - AndroidGraphicsContext *graphicsContext; - if (vulkan) { - graphicsContext = new AndroidVulkanContext(); - } else { - graphicsContext = new AndroidEGLGraphicsContext(); - } - if (!graphicsContext->Init(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { + if (!graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { ELOG("Failed to initialize graphics context."); if (!exitRenderLoop && (vulkan && tries < 2)) { @@ -844,13 +983,11 @@ retry: NativeShutdownGraphics(); renderer_inited = false; - ILOG("Shutting down graphics context."); - graphicsContext->Shutdown(); - delete graphicsContext; - graphicsContext = nullptr; + // Shut the graphics context down to the same state it was in when we entered the render thread. + ILOG("Shutting down graphics context from render thread..."); + graphicsContext->ShutdownFromRenderThread(); renderLoopRunning = false; WLOG("Render loop function exited."); - jniEnvGraphics = nullptr; return true; } diff --git a/android/jni/app-android.h b/android/jni/app-android.h index 04a849b1bc..49d0dab435 100644 --- a/android/jni/app-android.h +++ b/android/jni/app-android.h @@ -6,8 +6,7 @@ #include -extern JNIEnv *jniEnvMain; -extern JNIEnv *jniEnvGraphics; -extern JavaVM *javaVM; +jclass findClass(const char* name); +JNIEnv* getEnv(); #endif diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 01c2a107a1..96dadd6cf0 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -373,8 +373,7 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C switch (rot) { case 0: - // Auto is no longer supported. - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); break; case 1: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); @@ -388,6 +387,9 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C case 4: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); break; + case 5: + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + break; } } @@ -482,7 +484,7 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C gainAudioFocus(this.audioManager, this.audioFocusChangeListener); NativeApp.audioInit(); - if (javaGL) { + if (javaGL) { mGLSurfaceView = new NativeGLView(this); nativeRenderer = new NativeRenderer(this); mGLSurfaceView.setEGLContextClientVersion(2); @@ -538,7 +540,7 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C int requestedOr = getRequestedOrientation(); boolean requestedPortrait = requestedOr == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOr == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; boolean detectedPortrait = pixelHeight > pixelWidth; - if (badOrientationCount < 3 && requestedPortrait != detectedPortrait) { + if (badOrientationCount < 3 && requestedPortrait != detectedPortrait && requestedOr != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { Log.e(TAG, "Bad orientation detected (w=" + pixelWidth + " h=" + pixelHeight + "! Recreating activity."); badOrientationCount++; recreate(); diff --git a/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java b/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java index 2d53328573..1e13dba115 100644 --- a/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java +++ b/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java @@ -47,7 +47,7 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene Log.i(TAG, "MOGA initialized"); mController.setListener(this, new Handler()); } catch (Exception e) { - Log.i(TAG, "Moga failed to initialize"); + // Ignore. } } diff --git a/android/src/org/ppsspp/ppsspp/TextRenderer.java b/android/src/org/ppsspp/ppsspp/TextRenderer.java index 8c794a56a8..e2e4c37bef 100644 --- a/android/src/org/ppsspp/ppsspp/TextRenderer.java +++ b/android/src/org/ppsspp/ppsspp/TextRenderer.java @@ -26,12 +26,17 @@ public class TextRenderer { } } private static Point measureLine(String string, double textSize) { - p.setTextSize((float)textSize); - int w = (int)p.measureText(string); + int w; + if (string.length() > 0) { + p.setTextSize((float)textSize); + w = (int)p.measureText(string); + // Round width up to even already here to avoid annoyances from odd-width 16-bit textures which + // OpenGL does not like - each line must be 4-byte aligned + w = (w + 5) & ~1; + } else { + w = 1; + } int h = (int)(p.descent() - p.ascent() + 2.0f); - // Round width up to even already here to avoid annoyances from odd-width 16-bit textures which - // OpenGL does not like - each line must be 4-byte aligned - w = (w + 5) & ~1; Point p = new Point(); p.x = w; p.y = h; @@ -57,6 +62,10 @@ public class TextRenderer { int w = s.x; int h = s.y; + if (w == 0) + w = 1; + if (h == 0) + h = 1; Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); @@ -65,7 +74,8 @@ public class TextRenderer { String lines[] = string.replaceAll("\\r", "").split("\n"); float y = 1.0f; for (String line : lines) { - canvas.drawText(line, 1, -p.ascent() + y, p); + if (line.length() > 0) + canvas.drawText(line, 1, -p.ascent() + y, p); y += p.descent() - p.ascent(); } diff --git a/assets/gamecontrollerdb.txt b/assets/gamecontrollerdb.txt index 8b1e8ac772..7201505468 100644 --- a/assets/gamecontrollerdb.txt +++ b/assets/gamecontrollerdb.txt @@ -177,7 +177,7 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, 030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, 05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5, -030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, +030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, 030000004c050000cc09000011810000,Sony Interactive Entertainment Wireless Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, 050000004c050000cc09000000810000,Wireless Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, 030000004c0500006802000011810000,Sony PLAYSTATION(R)3 Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, @@ -185,3 +185,4 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5, 05000000c82d00002038000000010000,8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, 030000005e040000a102000000010000,Xbox 360 Wireless Receiver,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpdown:b14,dpleft:b11,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5, +050000004c050000cc09000001000000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, diff --git a/assets/lang b/assets/lang index 350f71780a..465f6bc726 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 350f71780adaaec0261d68149c093c6e1d86e215 +Subproject commit 465f6bc726cdc0e6fe186db6efe63fa09cefdc9b diff --git a/b.sh b/b.sh index c0cc2115ab..dbd616245f 100755 --- a/b.sh +++ b/b.sh @@ -9,6 +9,10 @@ do QT=1 CMAKE_ARGS="-DUSING_QT_UI=ON ${CMAKE_ARGS}" ;; + --qtbrew) echo "Qt enabled (homebrew)" + QT=1 + CMAKE_ARGS="-DUSING_QT_UI=ON -DCMAKE_PREFIX_PATH=$(brew --prefix qt5) ${CMAKE_ARGS}" + ;; --ios) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake ${CMAKE_ARGS}" TARGET_OS=iOS ;; @@ -43,6 +47,9 @@ do export CC=/usr/bin/clang export CXX=/usr/bin/clang++ ;; + --sanitize) echo "Enabling address-sanitizer if available" + CMAKE_ARGS="-DUSE_ADDRESS_SANITIZER=ON ${CMAKE_ARGS}" + ;; *) MAKE_OPT="$1 ${MAKE_OPT}" ;; esac diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 5656512d81..78a75db9d4 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -75,7 +75,6 @@ LOCAL_SRC_FILES :=\ gfx_es2/draw_buffer.cpp.arm \ gfx_es2/draw_text.cpp.arm \ gfx_es2/draw_text_android.cpp.arm \ - gfx/GLStateCache.cpp.arm \ gfx/gl_debug_log.cpp \ gfx/texture_atlas.cpp \ image/zim_load.cpp \ @@ -84,8 +83,11 @@ LOCAL_SRC_FILES :=\ thin3d/thin3d.cpp \ thin3d/thin3d_gl.cpp \ thin3d/thin3d_vulkan.cpp \ + thin3d/GLRenderManager.cpp \ + thin3d/GLQueueRunner.cpp \ thin3d/VulkanRenderManager.cpp \ thin3d/VulkanQueueRunner.cpp \ + thin3d/DataFormatGL.cpp \ ui/view.cpp \ ui/viewgroup.cpp \ ui/ui.cpp \ diff --git a/ext/native/base/timeutil.cpp b/ext/native/base/timeutil.cpp index 6d10fc62f2..f48c87a276 100644 --- a/ext/native/base/timeutil.cpp +++ b/ext/native/base/timeutil.cpp @@ -7,8 +7,6 @@ #ifdef _WIN32 #include #else -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" #include #include #endif @@ -41,25 +39,6 @@ uint64_t _frequency = 0; uint64_t _starttime = 0; double real_time_now() { -#ifdef __ANDROID__ - if (false && gl_extensions.EGL_NV_system_time) { - // This is needed to profile using PerfHUD on Tegra - if (_frequency == 0) { - _frequency = eglGetSystemTimeFrequencyNV(); - _starttime = eglGetSystemTimeNV(); - } - - uint64_t cur = eglGetSystemTimeNV(); - int64_t diff = cur - _starttime; - - return (double)diff / (double)_frequency; - } -#if 0 - // This clock is really "choppy" on Nexus 9! - struct timespec time; - clock_gettime(CLOCK_MONOTONIC_RAW, &time); - return time.tv_sec + time.tv_nsec / 1.0e9; -#else static time_t start; struct timeval tv; gettimeofday(&tv, NULL); @@ -68,18 +47,6 @@ double real_time_now() { } tv.tv_sec -= start; return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; -#endif - -#else - static time_t start; - struct timeval tv; - gettimeofday(&tv, NULL); - if (start == 0) { - start = tv.tv_sec; - } - tv.tv_sec -= start; - return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; -#endif } #endif diff --git a/ext/native/gfx/GLStateCache.cpp b/ext/native/gfx/GLStateCache.cpp deleted file mode 100644 index b4edffc1aa..0000000000 --- a/ext/native/gfx/GLStateCache.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include "base/logging.h" - -#include "gfx/GLStateCache.h" - -OpenGLState glstate; - -int OpenGLState::state_count = 0; - -void OpenGLState::Restore() { - int count = 0; - - blend.restore(); count++; - blendEquationSeparate.restore(); count++; - blendFuncSeparate.restore(); count++; - blendColor.restore(); count++; - - scissorTest.restore(); count++; - scissorRect.restore(); count++; - - cullFace.restore(); count++; - cullFaceMode.restore(); count++; - frontFace.restore(); count++; - - depthTest.restore(); count++; - depthRange.restore(); count++; - depthFunc.restore(); count++; - depthWrite.restore(); count++; - - colorMask.restore(); count++; - viewport.restore(); count++; - - stencilTest.restore(); count++; - stencilOp.restore(); count++; - stencilFunc.restore(); count++; - stencilMask.restore(); count++; - - dither.restore(); count++; - -#if !defined(USING_GLES2) - colorLogicOp.restore(); count++; - logicOp.restore(); count++; -#endif - - arrayBuffer.restore(); count++; - elementArrayBuffer.restore(); count++; - - if (count != state_count) { - FLOG("OpenGLState::Restore is missing some states"); - } -} diff --git a/ext/native/gfx/GLStateCache.h b/ext/native/gfx/GLStateCache.h deleted file mode 100644 index e46133709f..0000000000 --- a/ext/native/gfx/GLStateCache.h +++ /dev/null @@ -1,283 +0,0 @@ -#pragma once - -#include -#include // for memcmp - -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" - -// OpenGL state cache. -// Probably only really worth it in rendering cores on weak mobile hardware. -class OpenGLState { -private: - template - class BoolState { - private: - bool v; - public: - BoolState() : v(init) { - OpenGLState::state_count++; - } - - inline void set(bool value) { - if (value != v) { - v = value; - restore(); - } - } - inline void force(bool value) { - bool old = v; - set(value); - v = old; - } - inline void enable() { - set(true); - } - inline void disable() { - set(false); - } - operator bool() const { - return isset(); - } - inline bool isset() { - return v; - } - void restore() { - if (v) - glEnable(cap); - else - glDisable(cap); - } - }; - -#define STATE1(func, p1type, p1def) \ - class SavedState1_##func { \ - p1type p1; \ - public: \ - SavedState1_##func() : p1(p1def) { \ - OpenGLState::state_count++; \ - } \ - void set(p1type newp1) { \ - if (newp1 != p1) { \ - p1 = newp1; \ - restore(); \ - } \ - } \ - void force(p1type newp1) { \ - p1type old = p1; \ - set(newp1); \ - p1 = old; \ - } \ - inline void restore() { \ - func(p1); \ - } \ - } - -#define STATE2(func, p1type, p2type, p1def, p2def) \ - class SavedState2_##func { \ - p1type p1; \ - p2type p2; \ - public: \ - SavedState2_##func() : p1(p1def), p2(p2def) { \ - OpenGLState::state_count++; \ - } \ - inline void set(p1type newp1, p2type newp2) { \ - if (newp1 != p1 || newp2 != p2) { \ - p1 = newp1; \ - p2 = newp2; \ - restore(); \ - } \ - } \ - void force(p1type newp1, p2type newp2) { \ - p1type old1 = p1; \ - p2type old2 = p2; \ - set(newp1, newp2); \ - p1 = old1; \ - p2 = old2; \ - } \ - inline void restore() { \ - func(p1, p2); \ - } \ - } - -#define STATE3(func, p1type, p2type, p3type, p1def, p2def, p3def) \ - class SavedState3_##func { \ - p1type p1; \ - p2type p2; \ - p3type p3; \ - public: \ - SavedState3_##func() : p1(p1def), p2(p2def), p3(p3def) { \ - OpenGLState::state_count++; \ - } \ - inline void set(p1type newp1, p2type newp2, p3type newp3) { \ - if (newp1 != p1 || newp2 != p2 || newp3 != p3) { \ - p1 = newp1; \ - p2 = newp2; \ - p3 = newp3; \ - restore(); \ - } \ - } \ - void force(p1type newp1, p2type newp2, p3type newp3) { \ - p1type old1 = p1; \ - p2type old2 = p2; \ - p3type old3 = p3; \ - set(newp1, newp2, newp3); \ - p1 = old1; \ - p2 = old2; \ - p3 = old3; \ - } \ - inline void restore() { \ - func(p1, p2, p3); \ - } \ - } - - #define STATE4(func, p1type, p2type, p3type, p4type, p1def, p2def, p3def, p4def) \ - class SavedState4_##func { \ - p1type p1; \ - p2type p2; \ - p3type p3; \ - p4type p4; \ - public: \ - SavedState4_##func() : p1(p1def), p2(p2def), p3(p3def), p4(p4def) { \ - OpenGLState::state_count++; \ - } \ - inline void set(p1type newp1, p2type newp2, p3type newp3, p4type newp4) { \ - if (newp1 != p1 || newp2 != p2 || newp3 != p3 || newp4 != p4) { \ - p1 = newp1; \ - p2 = newp2; \ - p3 = newp3; \ - p4 = newp4; \ - restore(); \ - } \ - } \ - void force(p1type newp1, p2type newp2, p3type newp3, p4type newp4) { \ - p1type old1 = p1; \ - p2type old2 = p2; \ - p3type old3 = p3; \ - p4type old4 = p4; \ - set(newp1, newp2, newp3, newp4); \ - p1 = old1; \ - p2 = old2; \ - p3 = old3; \ - p4 = old4; \ - } \ - inline void restore() { \ - func(p1, p2, p3, p4); \ - } \ - } - -#define STATEFLOAT4(func, def) \ - class SavedState4_##func { \ - float p[4]; \ - public: \ - SavedState4_##func() { \ - for (int i = 0; i < 4; i++) {p[i] = def;} \ - OpenGLState::state_count++; \ - } \ - inline void set(const float v[4]) { \ - if (memcmp(p, v, sizeof(float) * 4)) { \ - memcpy(p, v, sizeof(float) * 4); \ - restore(); \ - } \ - } \ - void force(const float v[4]) { \ - float old[4]; \ - memcpy(old, p, sizeof(float) * 4); \ - set(v); \ - memcpy(p, old, sizeof(float) * 4); \ - } \ - inline void restore() { \ - func(p[0], p[1], p[2], p[3]); \ - } \ - } - -#define STATEBIND(func, target) \ - class SavedBind_##func_##target { \ - GLuint val_; \ - public: \ - SavedBind_##func_##target() { \ - val_ = 0; \ - OpenGLState::state_count++; \ - } \ - inline void bind(GLuint val) { \ - if (val_ != val) { \ - val_ = val; \ - restore(); \ - } \ - } \ - inline void force(GLuint val) { \ - GLuint old = val_; \ - bind(val); \ - val_ = old; \ - } \ - inline void unbind() { \ - bind(0); \ - } \ - inline void restore() { \ - func(target, val_); \ - } \ - } - -public: - static int state_count; - OpenGLState() {} - void Restore(); - - // When adding a state here, don't forget to add it to OpenGLState::Restore() too - - // Blending - BoolState blend; - STATE4(glBlendFuncSeparate, GLenum, GLenum, GLenum, GLenum, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blendFuncSeparate; - - // On OpenGL ES, using minmax blend requires glBlendEquationEXT (in theory at least but I don't think it's true in practice) - STATE2(glBlendEquationSeparate, GLenum, GLenum, GL_FUNC_ADD, GL_FUNC_ADD) blendEquationSeparate; - STATEFLOAT4(glBlendColor, 1.0f) blendColor; - - // Logic Ops. Not available on OpenGL ES at all. -#if !defined(USING_GLES2) - BoolState colorLogicOp; - STATE1(glLogicOp, GLenum, GL_COPY) logicOp; -#endif - - // Dither - BoolState dither; - - // Cull Face - BoolState cullFace; - STATE1(glCullFace, GLenum, GL_FRONT) cullFaceMode; - STATE1(glFrontFace, GLenum, GL_CCW) frontFace; - - // Depth Test - BoolState depthTest; -#if defined(USING_GLES2) - STATE2(glDepthRangef, float, float, 0.f, 1.f) depthRange; -#else - STATE2(glDepthRange, double, double, 0.0, 1.0) depthRange; -#endif - STATE1(glDepthFunc, GLenum, GL_LESS) depthFunc; - STATE1(glDepthMask, GLboolean, GL_TRUE) depthWrite; - - // Color Mask - STATE4(glColorMask, bool, bool, bool, bool, true, true, true, true) colorMask; - - // Viewport - STATE4(glViewport, GLint, GLint, GLsizei, GLsizei, 0, 0, 128, 128) viewport; - - // Scissor Test - BoolState scissorTest; - STATE4(glScissor, GLint, GLint, GLsizei, GLsizei, 0, 0, 128, 128) scissorRect; - - // Stencil Test - BoolState stencilTest; - STATE3(glStencilOp, GLenum, GLenum, GLenum, GL_KEEP, GL_KEEP, GL_KEEP) stencilOp; - STATE3(glStencilFunc, GLenum, GLint, GLuint, GL_ALWAYS, 0, 0xFF) stencilFunc; - STATE1(glStencilMask, GLuint, 0xFF) stencilMask; - - STATEBIND(glBindBuffer, GL_ARRAY_BUFFER) arrayBuffer; - STATEBIND(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER) elementArrayBuffer; -}; - -#undef STATE1 -#undef STATE2 - -extern OpenGLState glstate; diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index 2734d065b2..e797152554 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -11,8 +11,6 @@ #include "math/lin/matrix4x4.h" #include "thin3d/thin3d.h" -#undef DrawText - struct Atlas; enum { diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 68138ee9a4..f80994edd2 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -16,9 +16,9 @@ #include TextDrawerAndroid::TextDrawerAndroid(Draw::DrawContext *draw) : TextDrawer(draw) { - env_ = jniEnvGraphics; + env_ = getEnv(); const char *textRendererClassName = "org/ppsspp/ppsspp/TextRenderer"; - jclass localClass = env_->FindClass(textRendererClassName); + jclass localClass = findClass(textRendererClassName); cls_textRenderer = reinterpret_cast(env_->NewGlobalRef(localClass)); ILOG("cls_textRender: %p", cls_textRenderer); if (cls_textRenderer) { @@ -184,8 +184,13 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, jstring jstr = env_->NewStringUTF(text.c_str()); uint32_t textSize = env_->CallStaticIntMethod(cls_textRenderer, method_measureText, jstr, size); - int imageWidth = (textSize >> 16); - int imageHeight = (textSize & 0xFFFF); + int imageWidth = (short)(textSize >> 16); + int imageHeight = (short)(textSize & 0xFFFF); + if (imageWidth <= 0) + imageWidth = 1; + if (imageHeight <= 0) + imageHeight = 1; + jintArray imageData = (jintArray)env_->CallStaticObjectMethod(cls_textRenderer, method_renderText, jstr, size); env_->DeleteLocalRef(jstr); diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 7b523f47ab..7b6ca82561 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -140,6 +140,12 @@ void TextDrawerQt::ClearCache() { } cache_.clear(); sizeCache_.clear(); + // Also wipe the font map. + for (auto iter : fontMap_) { + delete iter.second; + } + fontMap_.clear(); + fontHash_ = 0; } void TextDrawerQt::DrawStringRect(DrawBuffer &target, const char *str, const Bounds &bounds, uint32_t color, int align) { diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 0476bd564e..5bc066f297 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -231,6 +231,13 @@ void TextDrawerWin32::DrawString(DrawBuffer &target, const char *str, float x, f size.cx = MAX_TEXT_WIDTH; if (size.cy > MAX_TEXT_HEIGHT) size.cy = MAX_TEXT_HEIGHT; + // Prevent zero-sized textures, which can occur. Not worth to avoid + // creating the texture altogether in this case. One example is a string + // containing only '\r\n', see issue #10764. + if (size.cx == 0) + size.cx = 1; + if (size.cy == 0) + size.cy = 1; entry = new TextStringEntry(); entry->width = size.cx; diff --git a/ext/native/gfx_es2/gl3stub.c b/ext/native/gfx_es2/gl3stub.c index f891c11fa9..57fe835761 100644 --- a/ext/native/gfx_es2/gl3stub.c +++ b/ext/native/gfx_es2/gl3stub.c @@ -135,6 +135,9 @@ GLboolean gl3stubInit() { FIND_PROC(glGetProgramResourceLocationIndexEXT); FIND_PROC(glGetFragDataIndexEXT); + /* EXT_buffer_storage */ + FIND_PROC(glBufferStorageEXT); + /* OES_copy_image, etc. */ FIND_PROC(glCopyImageSubDataOES); @@ -366,6 +369,9 @@ GL_APICALL void (* GL_APIENTRY glBindFragDataLocationEXT) (GLuint prog GL_APICALL GLint (* GL_APIENTRY glGetProgramResourceLocationIndexEXT) (GLuint program, GLenum programInterface, const GLchar *name); GL_APICALL GLint (* GL_APIENTRY glGetFragDataIndexEXT) (GLuint program, const GLchar *name); +/* EXT_buffer_storage */ +GL_APICALL void (* GL_APIENTRY glBufferStorageEXT) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); + /* OES_copy_image, etc. */ GL_APICALL void (* GL_APIENTRY glCopyImageSubDataOES) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); diff --git a/ext/native/gfx_es2/gl3stub.h b/ext/native/gfx_es2/gl3stub.h index acc630fa0e..080db197cf 100644 --- a/ext/native/gfx_es2/gl3stub.h +++ b/ext/native/gfx_es2/gl3stub.h @@ -260,6 +260,10 @@ typedef struct __GLsync *GLsync; #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 #define GL_RG 0x8227 #define GL_RG_INTEGER 0x8228 #define GL_R8 0x8229 @@ -500,9 +504,12 @@ extern GL_APICALL void (* GL_APIENTRY glBindFragDataLocationEXT) (GLui extern GL_APICALL GLint (* GL_APIENTRY glGetProgramResourceLocationIndexEXT) (GLuint program, GLenum programInterface, const GLchar *name); extern GL_APICALL GLint (* GL_APIENTRY glGetFragDataIndexEXT) (GLuint program, const GLchar *name); +/* EXT_buffer_storage */ +extern GL_APICALL void (* GL_APIENTRY glBufferStorageEXT) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); + /* OES_copy_image, etc. */ extern GL_APICALL void (* GL_APIENTRY glCopyImageSubDataOES) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - + #endif // IOS #ifdef __cplusplus diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index c758645fc9..966781cc75 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -77,6 +77,12 @@ void ProcessGPUFeatures() { } gl_extensions.bugs |= BUG_PVR_GENMIPMAP_HEIGHT_GREATER; } + + // TODO: Make this check more lenient. Disabled for all right now + // because it murders performance on Mali. + if (gl_extensions.gpuVendor != GPU_VENDOR_NVIDIA) { + gl_extensions.bugs |= BUG_ANY_MAP_BUFFER_RANGE_SLOW; + } } // http://stackoverflow.com/questions/16147700/opengl-es-using-tegra-specific-extensions-gl-ext-texture-array @@ -299,6 +305,7 @@ void CheckGLExtensions() { gl_extensions.OES_copy_image = strstr(extString, "GL_OES_copy_image") != 0; gl_extensions.EXT_copy_image = strstr(extString, "GL_EXT_copy_image") != 0; gl_extensions.ARB_copy_image = strstr(extString, "GL_ARB_copy_image") != 0; + gl_extensions.ARB_buffer_storage = strstr(extString, "GL_ARB_buffer_storage") != 0; gl_extensions.ARB_vertex_array_object = strstr(extString, "GL_ARB_vertex_array_object") != 0; gl_extensions.ARB_texture_float = strstr(extString, "GL_ARB_texture_float") != 0; gl_extensions.EXT_texture_filter_anisotropic = strstr(extString, "GL_EXT_texture_filter_anisotropic") != 0; @@ -317,6 +324,7 @@ void CheckGLExtensions() { gl_extensions.NV_shader_framebuffer_fetch = strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0; gl_extensions.ARM_shader_framebuffer_fetch = strstr(extString, "GL_ARM_shader_framebuffer_fetch") != 0; gl_extensions.OES_texture_float = strstr(extString, "GL_OES_texture_float") != 0; + gl_extensions.EXT_buffer_storage = strstr(extString, "GL_EXT_buffer_storage") != 0; #if defined(__ANDROID__) // On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though. @@ -393,6 +401,8 @@ void CheckGLExtensions() { } #endif + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &gl_extensions.maxVertexTextureUnits); + // This is probably a waste of time, implementations lie. if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility") || gl_extensions.VersionGEThan(4, 1)) { const GLint precisions[6] = { @@ -456,7 +466,7 @@ void CheckGLExtensions() { // ARB_vertex_attrib_binding = true; } if (gl_extensions.VersionGEThan(4, 4)) { - // ARB_buffer_storage = true; + gl_extensions.ARB_buffer_storage = true; } } diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index 2f405546b8..b26e923b55 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -23,6 +23,7 @@ enum { BUG_PVR_SHADER_PRECISION_BAD = 2, BUG_PVR_SHADER_PRECISION_TERRIBLE = 4, BUG_PVR_GENMIPMAP_HEIGHT_GREATER = 8, + BUG_ANY_MAP_BUFFER_RANGE_SLOW = 16, }; // Extensions to look at using: @@ -61,6 +62,7 @@ struct GLExtensions { bool ARB_vertex_array_object; bool ARB_texture_float; bool ARB_draw_instanced; + bool ARB_buffer_storage; // EXT bool EXT_swap_control_tear; @@ -75,6 +77,7 @@ struct GLExtensions { bool EXT_texture_filter_anisotropic; bool PBO_EXT; bool EXT_draw_instanced; + bool EXT_buffer_storage; // NV bool NV_shader_framebuffer_fetch; @@ -96,6 +99,8 @@ struct GLExtensions { int range[2][6][2]; // [vs,fs][lowf,mediumf,highf,lowi,mediumi,highi][min,max] int precision[2][6]; // [vs,fs][lowf...] + int maxVertexTextureUnits; + // greater-or-equal than bool VersionGEThan(int major, int minor, int sub = 0); }; diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 9ccbc1e644..8d43e4329d 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -232,7 +232,6 @@ - @@ -241,6 +240,10 @@ + + + + @@ -691,7 +694,6 @@ - @@ -699,6 +701,9 @@ + + + @@ -762,4 +767,4 @@ - + \ No newline at end of file diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index bec0f42cee..aecf223674 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -302,9 +302,6 @@ gfx - - gfx - thin3d @@ -332,6 +329,18 @@ base + + thin3d + + + thin3d + + + thin3d + + + thin3d + @@ -769,9 +778,6 @@ gfx - - gfx - thin3d @@ -799,6 +805,15 @@ ui + + thin3d + + + thin3d + + + thin3d + @@ -871,4 +886,4 @@ {06c6305a-a646-485b-85b9-645a24dd6553} - + \ No newline at end of file diff --git a/ext/native/thin3d/DataFormatGL.cpp b/ext/native/thin3d/DataFormatGL.cpp new file mode 100644 index 0000000000..5d48f15868 --- /dev/null +++ b/ext/native/thin3d/DataFormatGL.cpp @@ -0,0 +1,89 @@ +#include "thin3d/DataFormatGL.h" +#include "base/logging.h" +#include "Common/Log.h" + +namespace Draw { + +// TODO: Also output storage format (GL_RGBA8 etc) for modern GL usage. +bool Thin3DFormatToFormatAndType(DataFormat fmt, GLuint &internalFormat, GLuint &format, GLuint &type, int &alignment) { + alignment = 4; + switch (fmt) { + case DataFormat::R8G8B8A8_UNORM: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + break; + + case DataFormat::D32F: + internalFormat = GL_DEPTH_COMPONENT; + format = GL_DEPTH_COMPONENT; + type = GL_FLOAT; + break; + +#ifndef USING_GLES2 + case DataFormat::S8: + internalFormat = GL_STENCIL_INDEX; + format = GL_STENCIL_INDEX; + type = GL_UNSIGNED_BYTE; + alignment = 1; + break; +#endif + + case DataFormat::R8G8B8_UNORM: + internalFormat = GL_RGB; + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + alignment = 1; + break; + + case DataFormat::B4G4R4A4_UNORM_PACK16: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4; + alignment = 2; + break; + + case DataFormat::B5G6R5_UNORM_PACK16: + internalFormat = GL_RGB; + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + alignment = 2; + break; + + case DataFormat::B5G5R5A1_UNORM_PACK16: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_5_5_5_1; + alignment = 2; + break; + +#ifndef USING_GLES2 + case DataFormat::A4R4G4B4_UNORM_PACK16: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + alignment = 2; + break; + + case DataFormat::R5G6B5_UNORM_PACK16: + internalFormat = GL_RGB; + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5_REV; + alignment = 2; + break; + + case DataFormat::A1R5G5B5_UNORM_PACK16: + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + alignment = 2; + break; +#endif + + default: + return false; + } + return true; +} + +} diff --git a/ext/native/thin3d/DataFormatGL.h b/ext/native/thin3d/DataFormatGL.h new file mode 100644 index 0000000000..28b48f60ff --- /dev/null +++ b/ext/native/thin3d/DataFormatGL.h @@ -0,0 +1,10 @@ +#pragma once + +#include "gfx/gl_common.h" +#include "thin3d/DataFormat.h" + +namespace Draw { + +bool Thin3DFormatToFormatAndType(DataFormat fmt, GLuint &internalFormat, GLuint &format, GLuint &type, int &alignment); + +} diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp new file mode 100644 index 0000000000..f183dbe8c5 --- /dev/null +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -0,0 +1,1300 @@ +#include "Common/MemoryUtil.h" +#include "Core/Reporting.h" +#include "GLQueueRunner.h" +#include "GLRenderManager.h" +#include "DataFormatGL.h" +#include "base/logging.h" +#include "gfx/gl_common.h" +#include "gfx/gl_debug_log.h" +#include "gfx_es2/gpu_features.h" +#include "math/dataconv.h" + +#define TEXCACHE_NAME_CACHE_SIZE 16 + +#ifdef IOS +extern void bindDefaultFBO(); +#endif + +// Workaround for Retroarch. Simply declare +// extern GLuint g_defaultFBO; +// and set is as appropriate. Can adjust the variables in ext/native/base/display.h as +// appropriate. +GLuint g_defaultFBO = 0; + +void GLQueueRunner::CreateDeviceObjects() { + if (gl_extensions.EXT_texture_filter_anisotropic) { + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel_); + } else { + maxAnisotropyLevel_ = 0.0f; + } + + if (gl_extensions.ARB_vertex_array_object) { + glGenVertexArrays(1, &globalVAO_); + } + + // An eternal optimist. + sawOutOfMemory_ = false; + + // Populate some strings from the GL thread. + auto populate = [&](int name) { + const GLubyte *value = glGetString(name); + if (!value) + glStrings_[name] = "?"; + else + glStrings_[name] = (const char *)value; + }; + populate(GL_VENDOR); + populate(GL_RENDERER); + populate(GL_VERSION); + populate(GL_SHADING_LANGUAGE_VERSION); + if (!gl_extensions.IsCoreContext) { // Not OK to query this in core profile! + populate(GL_EXTENSIONS); + } +} + +void GLQueueRunner::DestroyDeviceObjects() { + if (!nameCache_.empty()) { + glDeleteTextures((GLsizei)nameCache_.size(), &nameCache_[0]); + nameCache_.clear(); + } + if (gl_extensions.ARB_vertex_array_object) { + glDeleteVertexArrays(1, &globalVAO_); + } + delete[] readbackBuffer_; + readbackBufferSize_ = 0; + delete[] tempBuffer_; + tempBufferSize_ = 0; +} + +void GLQueueRunner::RunInitSteps(const std::vector &steps) { + glActiveTexture(GL_TEXTURE0); + GLuint boundTexture = (GLuint)-1; + bool allocatedTextures = false; + + for (size_t i = 0; i < steps.size(); i++) { + const GLRInitStep &step = steps[i]; + switch (step.stepType) { + case GLRInitStepType::CREATE_TEXTURE: + { + GLRTexture *tex = step.create_texture.texture; + glGenTextures(1, &tex->texture); + glBindTexture(tex->target, tex->texture); + boundTexture = tex->texture; + break; + } + case GLRInitStepType::CREATE_BUFFER: + { + GLRBuffer *buffer = step.create_buffer.buffer; + glGenBuffers(1, &buffer->buffer); + glBindBuffer(buffer->target_, buffer->buffer); + glBufferData(buffer->target_, step.create_buffer.size, nullptr, step.create_buffer.usage); + break; + } + case GLRInitStepType::BUFFER_SUBDATA: + { + GLRBuffer *buffer = step.buffer_subdata.buffer; + glBindBuffer(GL_ARRAY_BUFFER, buffer->buffer); + glBufferSubData(GL_ARRAY_BUFFER, step.buffer_subdata.offset, step.buffer_subdata.size, step.buffer_subdata.data); + if (step.buffer_subdata.deleteData) + delete[] step.buffer_subdata.data; + break; + } + case GLRInitStepType::CREATE_PROGRAM: + { + GLRProgram *program = step.create_program.program; + program->program = glCreateProgram(); + _assert_msg_(G3D, step.create_program.num_shaders > 0, "Can't create a program with zero shaders"); + for (int j = 0; j < step.create_program.num_shaders; j++) { + _dbg_assert_msg_(G3D, step.create_program.shaders[j]->shader, "Can't create a program with a null shader"); + glAttachShader(program->program, step.create_program.shaders[j]->shader); + } + + for (auto iter : program->semantics_) { + glBindAttribLocation(program->program, iter.location, iter.attrib); + } + +#if !defined(USING_GLES2) + if (step.create_program.support_dual_source) { + // Dual source alpha + glBindFragDataLocationIndexed(program->program, 0, 0, "fragColor0"); + glBindFragDataLocationIndexed(program->program, 0, 1, "fragColor1"); + } else if (gl_extensions.VersionGEThan(3, 3, 0)) { + glBindFragDataLocation(program->program, 0, "fragColor0"); + } +#elif !defined(IOS) + if (gl_extensions.GLES3 && step.create_program.support_dual_source) { + glBindFragDataLocationIndexedEXT(program->program, 0, 0, "fragColor0"); + glBindFragDataLocationIndexedEXT(program->program, 0, 1, "fragColor1"); + } +#endif + glLinkProgram(program->program); + + GLint linkStatus = GL_FALSE; + glGetProgramiv(program->program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program->program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char *buf = new char[bufLength]; + glGetProgramInfoLog(program->program, bufLength, nullptr, buf); + + // TODO: Could be other than vs/fs. Also, we're assuming order here... + const char *vsDesc = step.create_program.shaders[0]->desc.c_str(); + const char *fsDesc = step.create_program.num_shaders > 1 ? step.create_program.shaders[1]->desc.c_str() : nullptr; + const char *vsCode = step.create_program.shaders[0]->code.c_str(); + const char *fsCode = step.create_program.num_shaders > 1 ? step.create_program.shaders[1]->code.c_str() : nullptr; + Reporting::ReportMessage("Error in shader program link: info: %s\nfs: %s\n%s\nvs: %s\n%s", buf, fsDesc, fsCode, vsDesc, vsCode); + + ELOG("Could not link program:\n %s", buf); + ERROR_LOG(G3D, "VS desc:\n%s", vsDesc); + ERROR_LOG(G3D, "FS desc:\n%s", fsDesc); + ERROR_LOG(G3D, "VS:\n%s\n", vsCode); + ERROR_LOG(G3D, "FS:\n%s\n", fsCode); + +#ifdef _WIN32 + OutputDebugStringUTF8(buf); + OutputDebugStringUTF8(vsCode); + if (fsCode) + OutputDebugStringUTF8(fsCode); +#endif + delete[] buf; + } else { + ELOG("Could not link program with %d shaders for unknown reason:", step.create_program.num_shaders); + } + break; + } + + glUseProgram(program->program); + + // Query all the uniforms. + for (size_t j = 0; j < program->queries_.size(); j++) { + auto &x = program->queries_[j]; + assert(x.name); + *x.dest = glGetUniformLocation(program->program, x.name); + } + + // Run initializers. + for (size_t j = 0; j < program->initialize_.size(); j++) { + auto &init = program->initialize_[j]; + GLint uniform = *init.uniform; + if (uniform != -1) { + switch (init.type) { + case 0: + glUniform1i(uniform, init.value); + } + } + } + break; + } + case GLRInitStepType::CREATE_SHADER: + { + GLuint shader = glCreateShader(step.create_shader.stage); + step.create_shader.shader->shader = shader; + const char *code = step.create_shader.code; + glShaderSource(shader, 1, &code, nullptr); + glCompileShader(shader); + GLint success = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { +#define MAX_INFO_LOG_SIZE 2048 + GLchar infoLog[MAX_INFO_LOG_SIZE]; + GLsizei len = 0; + glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog); + infoLog[len] = '\0'; +#ifdef __ANDROID__ + ELOG("Error in shader compilation! %s\n", infoLog); + ELOG("Shader source:\n%s\n", (const char *)code); +#endif + ERROR_LOG(G3D, "Error in shader compilation for: %s", step.create_shader.shader->desc.c_str()); + ERROR_LOG(G3D, "Info log: %s", infoLog); + ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); + Reporting::ReportMessage("Error in shader compilation: info: %s\n%s\n%s", infoLog, step.create_shader.shader->desc.c_str(), (const char *)code); +#ifdef SHADERLOG + OutputDebugStringUTF8(infoLog); +#endif + step.create_shader.shader->valid = false; + step.create_shader.shader->failed = true; + } + // Before we throw away the code, attach it to the shader for debugging. + step.create_shader.shader->code = code; + delete[] step.create_shader.code; + step.create_shader.shader->valid = true; + break; + } + case GLRInitStepType::CREATE_INPUT_LAYOUT: + { + GLRInputLayout *layout = step.create_input_layout.inputLayout; + // Nothing to do unless we want to create vertexbuffer objects (GL 4.5) + break; + } + case GLRInitStepType::CREATE_FRAMEBUFFER: + { + boundTexture = (GLuint)-1; + InitCreateFramebuffer(step); + allocatedTextures = true; + break; + } + case GLRInitStepType::TEXTURE_IMAGE: + { + GLRTexture *tex = step.texture_image.texture; + CHECK_GL_ERROR_IF_DEBUG(); + if (boundTexture != tex->texture) { + glBindTexture(tex->target, tex->texture); + boundTexture = tex->texture; + } + if (!step.texture_image.data) + Crash(); + // For things to show in RenderDoc, need to split into glTexImage2D(..., nullptr) and glTexSubImage. + glTexImage2D(tex->target, step.texture_image.level, step.texture_image.internalFormat, step.texture_image.width, step.texture_image.height, 0, step.texture_image.format, step.texture_image.type, step.texture_image.data); + allocatedTextures = true; + if (step.texture_image.allocType == GLRAllocType::ALIGNED) { + FreeAlignedMemory(step.texture_image.data); + } else { + delete[] step.texture_image.data; + } + CHECK_GL_ERROR_IF_DEBUG(); + tex->wrapS = GL_CLAMP_TO_EDGE; + tex->wrapT = GL_CLAMP_TO_EDGE; + tex->magFilter = step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST; + tex->minFilter = step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST; + glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, tex->wrapS); + glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, tex->wrapT); + glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, tex->magFilter); + glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, tex->minFilter); + break; + } + case GLRInitStepType::TEXTURE_FINALIZE: + { + GLRTexture *tex = step.texture_finalize.texture; + if (boundTexture != tex->texture) { + glBindTexture(tex->target, tex->texture); + boundTexture = tex->texture; + } + glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, step.texture_finalize.maxLevel); + tex->maxLod = (float)step.texture_finalize.maxLevel; + if (step.texture_finalize.genMips) { + glGenerateMipmap(tex->target); + } + break; + } + default: + Crash(); + break; + } + } + + // TODO: Use GL_KHR_no_error or a debug callback, where supported? + if (allocatedTextures) { + // Users may use replacements or scaling, with high render resolutions, and run out of VRAM. + // This detects that, rather than looking like PPSSPP is broken. + // Calling glGetError() isn't great, but at the end of init shouldn't be too bad... + GLenum err = glGetError(); + if (err == GL_OUT_OF_MEMORY) { + WARN_LOG_REPORT(G3D, "GL ran out of GPU memory; switching to low memory mode"); + sawOutOfMemory_ = true; + } else if (err != GL_NO_ERROR) { + // We checked the err anyway, might as well log if there is one. + WARN_LOG(G3D, "Got an error after init: %08x (%s)", err, GLEnumToString(err).c_str()); + } + } +} + +void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { + GLRFramebuffer *fbo = step.create_framebuffer.framebuffer; + +#ifndef USING_GLES2 + if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) { + fbo_ext_create(step); + } else if (!gl_extensions.ARB_framebuffer_object) { + return; + } + // If GLES2, we have basic FBO support and can just proceed. +#endif + CHECK_GL_ERROR_IF_DEBUG(); + + // Color texture is same everywhere + glGenFramebuffers(1, &fbo->handle); + glGenTextures(1, &fbo->color_texture.texture); + fbo->color_texture.target = GL_TEXTURE_2D; + fbo->color_texture.maxLod = 0.0f; + + // Create the surfaces. + glBindTexture(GL_TEXTURE_2D, fbo->color_texture.texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + fbo->color_texture.wrapS = GL_CLAMP_TO_EDGE; + fbo->color_texture.wrapT = GL_CLAMP_TO_EDGE; + fbo->color_texture.magFilter = GL_LINEAR; + fbo->color_texture.minFilter = GL_LINEAR; + fbo->color_texture.canWrap = false; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fbo->color_texture.wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fbo->color_texture.wrapT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fbo->color_texture.magFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, fbo->color_texture.minFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + if (gl_extensions.IsGLES) { + if (gl_extensions.OES_packed_depth_stencil) { + ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", fbo->width, fbo->height); + // Standard method + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil combined + glGenRenderbuffers(1, &fbo->z_stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, fbo->width, fbo->height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + } else { + ILOG("Creating %i x %i FBO using separate stencil", fbo->width, fbo->height); + // TEGRA + fbo->z_stencil_buffer = 0; + // 16/24-bit Z, separate 8-bit stencil + glGenRenderbuffers(1, &fbo->z_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_buffer); + // Don't forget to make sure fbo_standard_z_depth() matches. + glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, fbo->width, fbo->height); + + // 8-bit stencil buffer + glGenRenderbuffers(1, &fbo->stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fbo->width, fbo->height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); + } + } else { + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil + glGenRenderbuffers(1, &fbo->z_stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fbo->width, fbo->height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE: + // ILOG("Framebuffer verified complete."); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + break; + default: + FLOG("Other framebuffer error: %i", status); + break; + } + + // Unbind state we don't need + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + CHECK_GL_ERROR_IF_DEBUG(); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; +} + +void GLQueueRunner::RunSteps(const std::vector &steps) { + for (size_t i = 0; i < steps.size(); i++) { + const GLRStep &step = *steps[i]; + switch (step.stepType) { + case GLRStepType::RENDER: + PerformRenderPass(step); + break; + case GLRStepType::COPY: + PerformCopy(step); + break; + case GLRStepType::BLIT: + PerformBlit(step); + break; + case GLRStepType::READBACK: + PerformReadback(step); + break; + case GLRStepType::READBACK_IMAGE: + PerformReadbackImage(step); + break; + default: + Crash(); + break; + } + delete steps[i]; + } +} + +void GLQueueRunner::LogSteps(const std::vector &steps) { + +} + + +void GLQueueRunner::PerformBlit(const GLRStep &step) { + // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing + // in ES 2.0 that actually separate them anyway of course, so doesn't matter. + fbo_bind_fb_target(false, step.blit.dst->handle); + fbo_bind_fb_target(true, step.blit.src->handle); + + int srcX1 = step.blit.srcRect.x; + int srcY1 = step.blit.srcRect.y; + int srcX2 = step.blit.srcRect.x + step.blit.srcRect.w; + int srcY2 = step.blit.srcRect.y + step.blit.srcRect.h; + int dstX1 = step.blit.dstRect.x; + int dstY1 = step.blit.dstRect.y; + int dstX2 = step.blit.dstRect.x + step.blit.dstRect.w; + int dstY2 = step.blit.dstRect.y + step.blit.dstRect.h; + + if (gl_extensions.GLES3 || gl_extensions.ARB_framebuffer_object) { + glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, step.blit.aspectMask, step.blit.filter ? GL_LINEAR : GL_NEAREST); + CHECK_GL_ERROR_IF_DEBUG(); +#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC. + } else if (gl_extensions.NV_framebuffer_blit) { + glBlitFramebufferNV(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, step.blit.aspectMask, step.blit.filter ? GL_LINEAR : GL_NEAREST); + CHECK_GL_ERROR_IF_DEBUG(); +#endif // defined(USING_GLES2) && defined(__ANDROID__) + } else { + ERROR_LOG(G3D, "GLQueueRunner: Tried to blit without the capability"); + } +} + +void GLQueueRunner::PerformRenderPass(const GLRStep &step) { + // Don't execute empty renderpasses. + if (step.commands.empty()) { + // Nothing to do. + return; + } + + PerformBindFramebufferAsRenderTarget(step); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DITHER); + glEnable(GL_SCISSOR_TEST); +#ifndef USING_GLES2 + glDisable(GL_COLOR_LOGIC_OP); +#endif + + /* +#ifndef USING_GLES2 + if (g_Config.iInternalResolution == 0) { + glLineWidth(std::max(1, (int)(renderWidth_ / 480))); + glPointSize(std::max(1.0f, (float)(renderWidth_ / 480.f))); + } else { + glLineWidth(g_Config.iInternalResolution); + glPointSize((float)g_Config.iInternalResolution); + } +#endif + */ + + if (gl_extensions.ARB_vertex_array_object) { + glBindVertexArray(globalVAO_); + } + + GLRFramebuffer *fb = step.render.framebuffer; + GLRProgram *curProgram = nullptr; + int activeSlot = 0; + glActiveTexture(GL_TEXTURE0 + activeSlot); + + // State filtering tracking. + int attrMask = 0; + int colorMask = -1; + int depthMask = -1; + int depthFunc = -1; + int logicOp = -1; + GLuint curArrayBuffer = (GLuint)-1; + GLuint curElemArrayBuffer = (GLuint)-1; + bool depthEnabled = false; + bool stencilEnabled = false; + bool blendEnabled = false; + bool cullEnabled = false; + bool ditherEnabled = false; + bool logicEnabled = false; + GLuint blendEqColor = (GLuint)-1; + GLuint blendEqAlpha = (GLuint)-1; + + GLRTexture *curTex[8]{}; + + auto &commands = step.commands; + for (const auto &c : commands) { + switch (c.cmd) { + case GLRRenderCommand::DEPTH: + if (c.depth.enabled) { + if (!depthEnabled) { + glEnable(GL_DEPTH_TEST); + depthEnabled = true; + } + if (c.depth.write != depthMask) { + glDepthMask(c.depth.write); + depthMask = c.depth.write; + } + if (c.depth.func != depthFunc) { + glDepthFunc(c.depth.func); + depthFunc = c.depth.func; + } + } else if (!c.depth.enabled && depthEnabled) { + glDisable(GL_DEPTH_TEST); + depthEnabled = false; + } + break; + case GLRRenderCommand::STENCILFUNC: + if (c.stencilFunc.enabled) { + if (!stencilEnabled) { + glEnable(GL_STENCIL_TEST); + stencilEnabled = true; + } + glStencilFunc(c.stencilFunc.func, c.stencilFunc.ref, c.stencilFunc.compareMask); + } else if (stencilEnabled) { + glDisable(GL_STENCIL_TEST); + stencilEnabled = false; + } + break; + case GLRRenderCommand::STENCILOP: + glStencilOp(c.stencilOp.sFail, c.stencilOp.zFail, c.stencilOp.pass); + glStencilMask(c.stencilOp.writeMask); + break; + case GLRRenderCommand::BLEND: + if (c.blend.enabled) { + if (!blendEnabled) { + glEnable(GL_BLEND); + blendEnabled = true; + } + if (blendEqColor != c.blend.funcColor || blendEqAlpha != c.blend.funcAlpha) { + glBlendEquationSeparate(c.blend.funcColor, c.blend.funcAlpha); + blendEqColor = c.blend.funcColor; + blendEqAlpha = c.blend.funcAlpha; + } + glBlendFuncSeparate(c.blend.srcColor, c.blend.dstColor, c.blend.srcAlpha, c.blend.dstAlpha); + } else if (!c.blend.enabled && blendEnabled) { + glDisable(GL_BLEND); + blendEnabled = false; + } + if (c.blend.mask != colorMask) { + glColorMask(c.blend.mask & 1, (c.blend.mask >> 1) & 1, (c.blend.mask >> 2) & 1, (c.blend.mask >> 3) & 1); + colorMask = c.blend.mask; + } + break; + case GLRRenderCommand::LOGICOP: +#ifndef USING_GLES2 + if (c.logic.enabled) { + if (!logicEnabled) { + glEnable(GL_COLOR_LOGIC_OP); + logicEnabled = true; + } + if (logicOp != c.logic.logicOp) { + glLogicOp(c.logic.logicOp); + } + } else if (!c.logic.enabled && logicEnabled) { + glDisable(GL_COLOR_LOGIC_OP); + logicEnabled = false; + } +#endif + break; + case GLRRenderCommand::CLEAR: + // Scissor test is on, and should be on after leaving this case. If we disable it, + // we re-enable it at the end. + if (c.clear.scissorW == 0) { + glDisable(GL_SCISSOR_TEST); + } else { + glScissor(c.clear.scissorX, c.clear.scissorY, c.clear.scissorW, c.clear.scissorH); + } + if (c.clear.colorMask != colorMask) { + glColorMask(c.clear.colorMask & 1, (c.clear.colorMask >> 1) & 1, (c.clear.colorMask >> 2) & 1, (c.clear.colorMask >> 3) & 1); + colorMask = c.clear.colorMask; + } + if (c.clear.clearMask & GL_COLOR_BUFFER_BIT) { + float color[4]; + Uint8x4ToFloat4(color, c.clear.clearColor); + glClearColor(color[0], color[1], color[2], color[3]); + } + if (c.clear.clearMask & GL_DEPTH_BUFFER_BIT) { +#if defined(USING_GLES2) + glClearDepthf(c.clear.clearZ); +#else + glClearDepth(c.clear.clearZ); +#endif + } + if (c.clear.clearMask & GL_STENCIL_BUFFER_BIT) { + glClearStencil(c.clear.clearStencil); + } + glClear(c.clear.clearMask); + if (c.clear.scissorW == 0) { + glEnable(GL_SCISSOR_TEST); + } + break; + case GLRRenderCommand::INVALIDATE: + { + GLenum attachments[3]; + int count = 0; + if (c.clear.clearMask & GL_COLOR_BUFFER_BIT) + attachments[count++] = GL_COLOR_ATTACHMENT0; + if (c.clear.clearMask & GL_DEPTH_BUFFER_BIT) + attachments[count++] = GL_DEPTH_ATTACHMENT; + if (c.clear.clearMask & GL_STENCIL_BUFFER_BIT) + attachments[count++] = GL_STENCIL_BUFFER_BIT; + glInvalidateFramebuffer(GL_FRAMEBUFFER, count, attachments); + break; + } + case GLRRenderCommand::BLENDCOLOR: + glBlendColor(c.blendColor.color[0], c.blendColor.color[1], c.blendColor.color[2], c.blendColor.color[3]); + break; + case GLRRenderCommand::VIEWPORT: + { + float y = c.viewport.vp.y; + if (!curFB_) + y = curFBHeight_ - y - c.viewport.vp.h; + + // TODO: Support FP viewports through glViewportArrays + glViewport((GLint)c.viewport.vp.x, (GLint)y, (GLsizei)c.viewport.vp.w, (GLsizei)c.viewport.vp.h); +#if !defined(USING_GLES2) + glDepthRange(c.viewport.vp.minZ, c.viewport.vp.maxZ); +#else + glDepthRangef(c.viewport.vp.minZ, c.viewport.vp.maxZ); +#endif + break; + } + case GLRRenderCommand::SCISSOR: + { + int y = c.scissor.rc.y; + if (!curFB_) + y = curFBHeight_ - y - c.scissor.rc.h; + glScissor(c.scissor.rc.x, y, c.scissor.rc.w, c.scissor.rc.h); + break; + } + case GLRRenderCommand::UNIFORM4F: + { + int loc = c.uniform4.loc ? *c.uniform4.loc : -1; + if (c.uniform4.name) { + loc = curProgram->GetUniformLoc(c.uniform4.name); + } + if (loc >= 0) { + switch (c.uniform4.count) { + case 1: + glUniform1f(loc, c.uniform4.v[0]); + break; + case 2: + glUniform2fv(loc, 1, c.uniform4.v); + break; + case 3: + glUniform3fv(loc, 1, c.uniform4.v); + break; + case 4: + glUniform4fv(loc, 1, c.uniform4.v); + break; + } + } + break; + } + case GLRRenderCommand::UNIFORM4I: + { + int loc = c.uniform4.loc ? *c.uniform4.loc : -1; + if (c.uniform4.name) { + loc = curProgram->GetUniformLoc(c.uniform4.name); + } + if (loc >= 0) { + switch (c.uniform4.count) { + case 1: + glUniform1iv(loc, 1, (GLint *)&c.uniform4.v[0]); + break; + case 2: + glUniform2iv(loc, 1, (GLint *)c.uniform4.v); + break; + case 3: + glUniform3iv(loc, 1, (GLint *)c.uniform4.v); + break; + case 4: + glUniform4iv(loc, 1, (GLint *)c.uniform4.v); + break; + } + } + break; + } + case GLRRenderCommand::UNIFORMMATRIX: + { + int loc = c.uniform4.loc ? *c.uniform4.loc : -1; + if (c.uniform4.name) { + loc = curProgram->GetUniformLoc(c.uniform4.name); + } + if (loc >= 0) { + glUniformMatrix4fv(loc, 1, false, c.uniformMatrix4.m); + } + break; + } + case GLRRenderCommand::BINDTEXTURE: + { + GLint slot = c.texture.slot; + if (slot != activeSlot) { + glActiveTexture(GL_TEXTURE0 + slot); + activeSlot = slot; + } + if (c.texture.texture) { + if (curTex[slot] != c.texture.texture) { + glBindTexture(c.texture.texture->target, c.texture.texture->texture); + curTex[slot] = c.texture.texture; + } + } else { + glBindTexture(GL_TEXTURE_2D, 0); // Which target? Well we only use this one anyway... + curTex[slot] = nullptr; + } + break; + } + case GLRRenderCommand::BIND_FB_TEXTURE: + { + GLint slot = c.bind_fb_texture.slot; + if (slot != activeSlot) { + glActiveTexture(GL_TEXTURE0 + slot); + activeSlot = slot; + } + if (c.bind_fb_texture.aspect == GL_COLOR_BUFFER_BIT) { + if (curTex[slot] != &c.bind_fb_texture.framebuffer->color_texture) + glBindTexture(GL_TEXTURE_2D, c.bind_fb_texture.framebuffer->color_texture.texture); + curTex[slot] = &c.bind_fb_texture.framebuffer->color_texture; + } else { + // TODO: Depth texturing? + curTex[slot] = nullptr; + } + break; + } + case GLRRenderCommand::BINDPROGRAM: + { + if (curProgram != c.program.program) { + glUseProgram(c.program.program->program); + curProgram = c.program.program; + } + break; + } + case GLRRenderCommand::BIND_VERTEX_BUFFER: + { + // TODO: Add fast path for glBindVertexBuffer + GLRInputLayout *layout = c.bindVertexBuffer.inputLayout; + GLuint buf = c.bindVertexBuffer.buffer ? c.bindVertexBuffer.buffer->buffer : 0; + assert(!c.bindVertexBuffer.buffer->Mapped()); + if (buf != curArrayBuffer) { + glBindBuffer(GL_ARRAY_BUFFER, buf); + curArrayBuffer = buf; + } + int enable = layout->semanticsMask_ & ~attrMask; + int disable = (~layout->semanticsMask_) & attrMask; + for (int i = 0; i < 7; i++) { // SEM_MAX + if (enable & (1 << i)) { + glEnableVertexAttribArray(i); + } + if (disable & (1 << i)) { + glDisableVertexAttribArray(i); + } + } + attrMask = layout->semanticsMask_; + for (size_t i = 0; i < layout->entries.size(); i++) { + auto &entry = layout->entries[i]; + glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, entry.stride, (const void *)(c.bindVertexBuffer.offset + entry.offset)); + } + break; + } + case GLRRenderCommand::BIND_BUFFER: + { + if (c.bind_buffer.target == GL_ARRAY_BUFFER) { + Crash(); + } else if (c.bind_buffer.target == GL_ELEMENT_ARRAY_BUFFER) { + GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer : 0; + assert(!c.bind_buffer.buffer->Mapped()); + if (buf != curElemArrayBuffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); + curElemArrayBuffer = buf; + } + } else { + GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer : 0; + assert(!c.bind_buffer.buffer->Mapped()); + glBindBuffer(c.bind_buffer.target, buf); + } + break; + } + case GLRRenderCommand::GENMIPS: + // TODO: Should we include the texture handle in the command? + // Also, should this not be an init command? + glGenerateMipmap(GL_TEXTURE_2D); + break; + case GLRRenderCommand::DRAW: + glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); + break; + case GLRRenderCommand::DRAW_INDEXED: + if (c.drawIndexed.instances == 1) { + glDrawElements(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices); + } else { + glDrawElementsInstanced(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices, c.drawIndexed.instances); + } + break; + case GLRRenderCommand::TEXTURESAMPLER: + { + GLint slot = c.textureSampler.slot; + if (slot != activeSlot) { + glActiveTexture(GL_TEXTURE0 + slot); + activeSlot = slot; + } + GLRTexture *tex = curTex[slot]; + if (!tex) { + break; + } + if (tex->canWrap) { + if (tex->wrapS != c.textureSampler.wrapS) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c.textureSampler.wrapS); + tex->wrapS = c.textureSampler.wrapS; + } + if (tex->wrapT != c.textureSampler.wrapT) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c.textureSampler.wrapT); + tex->wrapT = c.textureSampler.wrapT; + } + } + if (tex->magFilter != c.textureSampler.magFilter) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, c.textureSampler.magFilter); + tex->magFilter = c.textureSampler.magFilter; + } + if (tex->minFilter != c.textureSampler.minFilter) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c.textureSampler.minFilter); + tex->minFilter = c.textureSampler.minFilter; + } + if (tex->anisotropy != c.textureSampler.anisotropy) { + if (c.textureSampler.anisotropy != 0.0f) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, c.textureSampler.anisotropy); + } + tex->anisotropy = c.textureSampler.anisotropy; + } + break; + } + case GLRRenderCommand::TEXTURELOD: + { + GLint slot = c.textureSampler.slot; + if (slot != activeSlot) { + glActiveTexture(GL_TEXTURE0 + slot); + activeSlot = slot; + } + GLRTexture *tex = curTex[slot]; + if (!tex) { + break; + } +#ifndef USING_GLES2 + if (tex->lodBias != c.textureLod.lodBias) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, c.textureLod.lodBias); + tex->lodBias = c.textureLod.lodBias; + } +#endif + if (tex->minLod != c.textureLod.minLod) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, c.textureLod.minLod); + tex->minLod = c.textureLod.minLod; + } + if (tex->maxLod != c.textureLod.maxLod) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, c.textureLod.maxLod); + tex->maxLod = c.textureLod.maxLod; + } + break; + } + case GLRRenderCommand::RASTER: + if (c.raster.cullEnable) { + if (!cullEnabled) { + glEnable(GL_CULL_FACE); + cullEnabled = true; + } + glFrontFace(c.raster.frontFace); + glCullFace(c.raster.cullFace); + } else if (!c.raster.cullEnable && cullEnabled) { + glDisable(GL_CULL_FACE); + cullEnabled = false; + } + if (c.raster.ditherEnable) { + if (!ditherEnabled) { + glEnable(GL_DITHER); + ditherEnabled = true; + } + } else if (!c.raster.ditherEnable && ditherEnabled) { + glDisable(GL_DITHER); + ditherEnabled = false; + } + break; + default: + Crash(); + break; + } + } + + for (int i = 0; i < 7; i++) { + if (attrMask & (1 << i)) { + glDisableVertexAttribArray(i); + } + } + + if (activeSlot != 0) { + glActiveTexture(GL_TEXTURE0); + activeSlot = 0; // doesn't matter, just nice. + } + + // Wipe out the current state. + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (gl_extensions.ARB_vertex_array_object) { + glBindVertexArray(0); + } + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); +#ifndef USING_GLES2 + glDisable(GL_COLOR_LOGIC_OP); +#endif + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +} + +void GLQueueRunner::PerformCopy(const GLRStep &step) { + GLuint srcTex = 0; + GLuint dstTex = 0; + GLuint target = GL_TEXTURE_2D; + + const GLRect2D &srcRect = step.copy.srcRect; + const GLOffset2D &dstPos = step.copy.dstPos; + + GLRFramebuffer *src = step.copy.src; + GLRFramebuffer *dst = step.copy.dst; + + int srcLevel = 0; + int dstLevel = 0; + int srcZ = 0; + int dstZ = 0; + int depth = 1; + + switch (step.copy.aspectMask) { + case GL_COLOR_BUFFER_BIT: + srcTex = src->color_texture.texture; + dstTex = dst->color_texture.texture; + break; + case GL_DEPTH_BUFFER_BIT: + // TODO: Support depth copies. + _assert_msg_(G3D, false, "Depth copies not yet supported - soon"); + target = GL_RENDERBUFFER; + /* + srcTex = src->depth.texture; + dstTex = src->depth.texture; + */ + break; + } + + _dbg_assert_(G3D, srcTex); + _dbg_assert_(G3D, dstTex); + +#if defined(USING_GLES2) +#ifndef IOS + glCopyImageSubDataOES( + srcTex, target, srcLevel, srcRect.x, srcRect.y, srcZ, + dstTex, target, dstLevel, dstPos.x, dstPos.y, dstZ, + srcRect.w, srcRect.h, depth); +#endif +#else + if (gl_extensions.ARB_copy_image) { + glCopyImageSubData( + srcTex, target, srcLevel, srcRect.x, srcRect.y, srcZ, + dstTex, target, dstLevel, dstPos.x, dstPos.y, dstZ, + srcRect.w, srcRect.h, depth); + } else if (gl_extensions.NV_copy_image) { + // Older, pre GL 4.x NVIDIA cards. + glCopyImageSubDataNV( + srcTex, target, srcLevel, srcRect.x, srcRect.y, srcZ, + dstTex, target, dstLevel, dstPos.x, dstPos.y, dstZ, + srcRect.w, srcRect.h, depth); + } +#endif +} + +void GLQueueRunner::PerformReadback(const GLRStep &pass) { + using namespace Draw; + + GLRFramebuffer *fb = pass.readback.src; + + fbo_bind_fb_target(true, fb ? fb->handle : 0); + + // Reads from the "bound for read" framebuffer. + if (gl_extensions.GLES3 || !gl_extensions.IsGLES) + glReadBuffer(GL_COLOR_ATTACHMENT0); + + CHECK_GL_ERROR_IF_DEBUG(); + + // Always read back in 8888 format. + const GLuint internalFormat = GL_RGBA; + const GLuint format = GL_RGBA; + const GLuint type = GL_UNSIGNED_BYTE; + const int srcAlignment = 4; + int dstAlignment = (int)DataFormatSizeInBytes(pass.readback.dstFormat); + + int pixelStride = pass.readback.srcRect.w; + // Apply the correct alignment. + glPixelStorei(GL_PACK_ALIGNMENT, srcAlignment); + if (!gl_extensions.IsGLES || gl_extensions.GLES3) { + // Some drivers seem to require we specify this. See #8254. + glPixelStorei(GL_PACK_ROW_LENGTH, pixelStride); + } + + GLRect2D rect = pass.readback.srcRect; + + bool convert = pass.readback.dstFormat != DataFormat::R8G8B8A8_UNORM; + + int tempSize = srcAlignment * rect.w * rect.h; + int readbackSize = dstAlignment * rect.w * rect.h; + if (convert && tempSize > tempBufferSize_) { + delete[] tempBuffer_; + tempBuffer_ = new uint8_t[tempSize]; + tempBufferSize_ = tempSize; + } + if (readbackSize > readbackBufferSize_) { + delete[] readbackBuffer_; + readbackBuffer_ = new uint8_t[readbackSize]; + readbackBufferSize_ = readbackSize; + } + + glReadPixels(rect.x, rect.y, rect.w, rect.h, format, type, convert ? tempBuffer_ : readbackBuffer_); + #ifdef DEBUG_READ_PIXELS + LogReadPixelsError(glGetError()); + #endif + if (!gl_extensions.IsGLES || gl_extensions.GLES3) { + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + } + if (convert) { + ConvertFromRGBA8888(readbackBuffer_, tempBuffer_, pixelStride, pixelStride, rect.w, rect.h, pass.readback.dstFormat); + } + + CHECK_GL_ERROR_IF_DEBUG(); +} + +void GLQueueRunner::PerformReadbackImage(const GLRStep &pass) { + GLRTexture *tex = pass.readback_image.texture; + + glBindTexture(GL_TEXTURE_2D, tex->texture); + + CHECK_GL_ERROR_IF_DEBUG(); + +#ifndef USING_GLES2 + int pixelStride = pass.readback_image.srcRect.w; + glPixelStorei(GL_PACK_ALIGNMENT, 4); + + GLRect2D rect = pass.readback.srcRect; + + int size = 4 * rect.w * rect.h; + if (size > readbackBufferSize_) { + delete[] readbackBuffer_; + readbackBuffer_ = new uint8_t[size]; + readbackBufferSize_ = size; + } + + glPixelStorei(GL_PACK_ALIGNMENT, 4); + glGetTexImage(GL_TEXTURE_2D, pass.readback_image.mipLevel, GL_RGBA, GL_UNSIGNED_BYTE, readbackBuffer_); +#endif + + CHECK_GL_ERROR_IF_DEBUG(); +} + +void GLQueueRunner::PerformBindFramebufferAsRenderTarget(const GLRStep &pass) { + if (pass.render.framebuffer) { + curFBWidth_ = pass.render.framebuffer->width; + curFBHeight_ = pass.render.framebuffer->height; + } else { + curFBWidth_ = targetWidth_; + curFBHeight_ = targetHeight_; + } + + curFB_ = pass.render.framebuffer; + if (curFB_) { + // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing + // in ES 2.0 that actually separate them anyway of course, so doesn't matter. + fbo_bind_fb_target(false, curFB_->handle); + } else { + fbo_unbind(); + // Backbuffer is now bound. + } +} + +void GLQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels) { + // TODO: Maybe move data format conversion here, and always read back 8888. Drivers + // don't usually provide very optimized conversion implementations, though some do. + // Just need to be careful about dithering, which may break Danganronpa. + int bpp = (int)Draw::DataFormatSizeInBytes(destFormat); + for (int y = 0; y < height; y++) { + memcpy(pixels + y * pixelStride * bpp, readbackBuffer_ + y * width * bpp, width * bpp); + } +} + +GLuint GLQueueRunner::AllocTextureName() { + if (nameCache_.empty()) { + nameCache_.resize(TEXCACHE_NAME_CACHE_SIZE); + glGenTextures(TEXCACHE_NAME_CACHE_SIZE, &nameCache_[0]); + } + u32 name = nameCache_.back(); + nameCache_.pop_back(); + return name; +} + +// On PC, we always use GL_DEPTH24_STENCIL8. +// On Android, we try to use what's available. + +#ifndef USING_GLES2 +void GLQueueRunner::fbo_ext_create(const GLRInitStep &step) { + GLRFramebuffer *fbo = step.create_framebuffer.framebuffer; + + // Color texture is same everywhere + glGenFramebuffersEXT(1, &fbo->handle); + glGenTextures(1, &fbo->color_texture.texture); + + // Create the surfaces. + glBindTexture(GL_TEXTURE_2D, fbo->color_texture.texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + fbo->color_texture.target = GL_TEXTURE_2D; + fbo->color_texture.wrapS = GL_CLAMP_TO_EDGE; + fbo->color_texture.wrapT = GL_CLAMP_TO_EDGE; + fbo->color_texture.magFilter = GL_LINEAR; + fbo->color_texture.minFilter = GL_LINEAR; + fbo->color_texture.maxLod = 0.0f; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fbo->color_texture.wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fbo->color_texture.wrapT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, fbo->color_texture.magFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fbo->color_texture.minFilter); + + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil + glGenRenderbuffersEXT(1, &fbo->z_stencil_buffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, fbo->width, fbo->height); + // glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height); + + // Bind it all together + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE_EXT: + // ILOG("Framebuffer verified complete."); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + break; + default: + FLOG("Other framebuffer error: %i", status); + break; + } + // Unbind state we don't need + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; +} +#endif + +GLenum GLQueueRunner::fbo_get_fb_target(bool read, GLuint **cached) { + bool supportsBlit = gl_extensions.ARB_framebuffer_object; + if (gl_extensions.IsGLES) { + supportsBlit = (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit); + } + + // Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV. + if (supportsBlit) { + if (read) { + *cached = ¤tReadHandle_; + return GL_READ_FRAMEBUFFER; + } else { + *cached = ¤tDrawHandle_; + return GL_DRAW_FRAMEBUFFER; + } + } else { + *cached = ¤tDrawHandle_; + return GL_FRAMEBUFFER; + } +} + +void GLQueueRunner::fbo_bind_fb_target(bool read, GLuint name) { + CHECK_GL_ERROR_IF_DEBUG(); + GLuint *cached; + GLenum target = fbo_get_fb_target(read, &cached); + if (*cached != name) { + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + glBindFramebuffer(target, name); + } else { +#ifndef USING_GLES2 + glBindFramebufferEXT(target, name); +#endif + } + *cached = name; + } + CHECK_GL_ERROR_IF_DEBUG(); +} + +void GLQueueRunner::fbo_unbind() { + CHECK_GL_ERROR_IF_DEBUG(); +#ifndef USING_GLES2 + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); + } else if (gl_extensions.EXT_framebuffer_object) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_defaultFBO); + } +#else + glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); +#endif + +#ifdef IOS + bindDefaultFBO(); +#endif + + currentDrawHandle_ = 0; + currentReadHandle_ = 0; + CHECK_GL_ERROR_IF_DEBUG(); +} + +GLRFramebuffer::~GLRFramebuffer() { + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + if (handle) { + glBindFramebuffer(GL_FRAMEBUFFER, handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); + glDeleteFramebuffers(1, &handle); + } + if (z_stencil_buffer) + glDeleteRenderbuffers(1, &z_stencil_buffer); + if (z_buffer) + glDeleteRenderbuffers(1, &z_buffer); + if (stencil_buffer) + glDeleteRenderbuffers(1, &stencil_buffer); + } else if (gl_extensions.EXT_framebuffer_object) { +#ifndef USING_GLES2 + if (handle) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, handle); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_defaultFBO); + glDeleteFramebuffersEXT(1, &handle); + } + if (z_stencil_buffer) + glDeleteRenderbuffers(1, &z_stencil_buffer); + if (z_buffer) + glDeleteRenderbuffers(1, &z_buffer); + if (stencil_buffer) + glDeleteRenderbuffers(1, &stencil_buffer); +#endif + } +} diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h new file mode 100644 index 0000000000..9119b0d05f --- /dev/null +++ b/ext/native/thin3d/GLQueueRunner.h @@ -0,0 +1,405 @@ +#pragma once + +#include +#include +#include + +#include "gfx/gl_common.h" +#include "thin3d/DataFormat.h" + +struct GLRViewport { + float x, y, w, h, minZ, maxZ; +}; + +struct GLRect2D { + int x, y, w, h; +}; + +struct GLOffset2D { + int x, y; +}; + +enum class GLRAllocType { + NEW, + ALIGNED, +}; + +class GLRShader; +class GLRTexture; +class GLRBuffer; +class GLRFramebuffer; +class GLRProgram; +class GLRInputLayout; + +enum class GLRRenderCommand : uint8_t { + DEPTH, + STENCILFUNC, + STENCILOP, + BLEND, + BLENDCOLOR, + LOGICOP, + UNIFORM4I, + UNIFORM4F, + UNIFORMMATRIX, + TEXTURESAMPLER, + TEXTURELOD, + VIEWPORT, + SCISSOR, + RASTER, + CLEAR, + INVALIDATE, + BINDPROGRAM, + BINDTEXTURE, + BIND_FB_TEXTURE, + BIND_VERTEX_BUFFER, + BIND_BUFFER, + GENMIPS, + DRAW, + DRAW_INDEXED, + PUSH_CONSTANTS, +}; + +// TODO: Bloated since the biggest struct decides the size. Will need something more efficient (separate structs with shared +// type field, smashed right after each other?) +// Also, all GLenums are really only 16 bits. +struct GLRRenderData { + GLRRenderCommand cmd; + union { + struct { + GLboolean enabled; + GLenum srcColor; + GLenum dstColor; + GLenum srcAlpha; + GLenum dstAlpha; + GLenum funcColor; + GLenum funcAlpha; + int mask; + } blend; + struct { + float color[4]; + } blendColor; + struct { + GLboolean enabled; + GLenum logicOp; + } logic; + struct { + GLboolean enabled; + GLboolean write; + GLenum func; + } depth; + struct { + GLboolean enabled; + GLenum func; + uint8_t ref; + uint8_t compareMask; + } stencilFunc; + struct { + GLenum sFail; + GLenum zFail; + GLenum pass; + uint8_t writeMask; + } stencilOp; // also write mask + struct { + GLenum mode; // primitive + GLint buffer; + GLint first; + GLint count; + } draw; + struct { + GLenum mode; // primitive + GLint count; + GLint instances; + GLint indexType; + void *indices; + } drawIndexed; + struct { + const char *name; // if null, use loc + GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation. + GLint count; + float v[4]; + } uniform4; + struct { + const char *name; // if null, use loc + GLint *loc; + float m[16]; + } uniformMatrix4; + struct { + uint32_t clearColor; + float clearZ; + uint8_t clearStencil; + uint8_t colorMask; // Like blend, but for the clear. + GLuint clearMask; // GL_COLOR_BUFFER_BIT etc + int16_t scissorX; + int16_t scissorY; + int16_t scissorW; + int16_t scissorH; + } clear; + struct { + int slot; + GLRTexture *texture; + } texture; + struct { + int slot; + GLRFramebuffer *framebuffer; + int aspect; + } bind_fb_texture; + struct { + GLRBuffer *buffer; + GLuint target; + } bind_buffer; + struct { + GLRProgram *program; + } program; + struct { + GLRInputLayout *inputLayout; + GLRBuffer *buffer; + size_t offset; + } bindVertexBuffer; + struct { + int slot; + GLenum wrapS; + GLenum wrapT; + GLenum magFilter; + GLenum minFilter; // also includes mip. GL... + float anisotropy; + } textureSampler; + struct { + int slot; + float minLod; + float maxLod; + float lodBias; + } textureLod; + struct { + GLRViewport vp; + } viewport; + struct { + GLRect2D rc; + } scissor; + struct { + GLboolean cullEnable; + GLenum frontFace; + GLenum cullFace; + GLboolean ditherEnable; + } raster; + }; +}; + +// Unlike in Vulkan, we can't create stuff on the main thread, but need to +// defer this too. A big benefit will be that we'll be able to do all creation +// at the start of the frame. +enum class GLRInitStepType : uint8_t { + CREATE_TEXTURE, + CREATE_SHADER, + CREATE_PROGRAM, + CREATE_BUFFER, + CREATE_INPUT_LAYOUT, + CREATE_FRAMEBUFFER, + + TEXTURE_IMAGE, + TEXTURE_FINALIZE, + BUFFER_SUBDATA, +}; + +struct GLRInitStep { + GLRInitStep(GLRInitStepType _type) : stepType(_type) {} + GLRInitStepType stepType; + union { + struct { + GLRTexture *texture; + GLenum target; + } create_texture; + struct { + GLRShader *shader; + // This char arrays needs to be allocated with new[]. + char *code; + GLuint stage; + } create_shader; + struct { + GLRProgram *program; + GLRShader *shaders[3]; + int num_shaders; + bool support_dual_source; + } create_program; + struct { + GLRBuffer *buffer; + int size; + GLuint usage; + } create_buffer; + struct { + GLRInputLayout *inputLayout; + } create_input_layout; + struct { + GLRFramebuffer *framebuffer; + } create_framebuffer; + struct { + GLRBuffer *buffer; + int offset; + int size; + uint8_t *data; // owned, delete[]-d + bool deleteData; + } buffer_subdata; + struct { + GLRTexture *texture; + GLenum internalFormat; + GLenum format; + GLenum type; + int level; + int width; + int height; + GLRAllocType allocType; + bool linearFilter; + uint8_t *data; // owned, delete[]-d + } texture_image; + struct { + GLRTexture *texture; + int maxLevel; + bool genMips; + } texture_finalize; + }; +}; + +enum class GLRStepType : uint8_t { + RENDER, + COPY, + BLIT, + READBACK, + READBACK_IMAGE, +}; + +enum class GLRRenderPassAction { + DONT_CARE, + CLEAR, + KEEP, +}; + +class GLRFramebuffer; + +enum { + GLR_ASPECT_COLOR = 1, + GLR_ASPECT_DEPTH = 2, + GLR_ASPECT_STENCIL = 3, +}; + +struct GLRStep { + GLRStep(GLRStepType _type) : stepType(_type) {} + GLRStepType stepType; + std::vector commands; + union { + struct { + GLRFramebuffer *framebuffer; + int numDraws; + } render; + struct { + GLRFramebuffer *src; + GLRFramebuffer *dst; + GLRect2D srcRect; + GLOffset2D dstPos; + int aspectMask; + } copy; + struct { + GLRFramebuffer *src; + GLRFramebuffer *dst; + GLRect2D srcRect; + GLRect2D dstRect; + int aspectMask; + GLboolean filter; + } blit; + struct { + int aspectMask; + GLRFramebuffer *src; + GLRect2D srcRect; + Draw::DataFormat dstFormat; + } readback; + struct { + GLRTexture *texture; + GLRect2D srcRect; + int mipLevel; + } readback_image; + }; +}; + +class GLQueueRunner { +public: + GLQueueRunner() {} + + void RunInitSteps(const std::vector &steps); + + void RunSteps(const std::vector &steps); + void LogSteps(const std::vector &steps); + + void CreateDeviceObjects(); + void DestroyDeviceObjects(); + + inline int RPIndex(GLRRenderPassAction color, GLRRenderPassAction depth) { + return (int)depth * 3 + (int)color; + } + + void CopyReadbackBuffer(int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels); + + void Resize(int width, int height) { + targetWidth_ = width; + targetHeight_ = height; + } + + bool SawOutOfMemory() { + return sawOutOfMemory_; + } + + std::string GetGLString(int name) const { + auto it = glStrings_.find(name); + return it != glStrings_.end() ? it->second : ""; + } + +private: + void InitCreateFramebuffer(const GLRInitStep &step); + + void PerformBindFramebufferAsRenderTarget(const GLRStep &pass); + void PerformRenderPass(const GLRStep &pass); + void PerformCopy(const GLRStep &pass); + void PerformBlit(const GLRStep &pass); + void PerformReadback(const GLRStep &pass); + void PerformReadbackImage(const GLRStep &pass); + + void LogRenderPass(const GLRStep &pass); + void LogCopy(const GLRStep &pass); + void LogBlit(const GLRStep &pass); + void LogReadback(const GLRStep &pass); + void LogReadbackImage(const GLRStep &pass); + + void ResizeReadbackBuffer(size_t requiredSize); + + void fbo_ext_create(const GLRInitStep &step); + void fbo_bind_fb_target(bool read, GLuint name); + GLenum fbo_get_fb_target(bool read, GLuint **cached); + void fbo_unbind(); + + GLRFramebuffer *curFB_ = nullptr; + + GLuint globalVAO_ = 0; + + int curFBWidth_ = 0; + int curFBHeight_ = 0; + int targetWidth_ = 0; + int targetHeight_ = 0; + + // Readback buffer. Currently we only support synchronous readback, so we only really need one. + // We size it generously. + uint8_t *readbackBuffer_ = nullptr; + int readbackBufferSize_ = 0; + // Temp buffer for color conversion + uint8_t *tempBuffer_ = nullptr; + int tempBufferSize_ = 0; + + float maxAnisotropyLevel_ = 0.0f; + + // Framebuffer state? + GLuint currentDrawHandle_ = 0; + GLuint currentReadHandle_ = 0; + + GLuint AllocTextureName(); + // Texture name cache. Ripped straight from TextureCacheGLES. + std::vector nameCache_; + std::unordered_map glStrings_; + + bool sawOutOfMemory_ = false; +}; diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp new file mode 100644 index 0000000000..d5f648b86a --- /dev/null +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -0,0 +1,793 @@ +#include + +#include "GLRenderManager.h" +#include "gfx_es2/gpu_features.h" +#include "thread/threadutil.h" +#include "base/logging.h" +#include "GPU/GPUState.h" +#include "Common/MemoryUtil.h" + +#if 0 // def _DEBUG +#define VLOG ILOG +#else +#define VLOG(...) +#endif + +void GLDeleter::Perform() { + for (auto shader : shaders) { + delete shader; + } + shaders.clear(); + for (auto program : programs) { + delete program; + } + programs.clear(); + for (auto buffer : buffers) { + delete buffer; + } + buffers.clear(); + for (auto texture : textures) { + delete texture; + } + textures.clear(); + for (auto inputLayout : inputLayouts) { + delete inputLayout; + } + inputLayouts.clear(); + for (auto framebuffer : framebuffers) { + delete framebuffer; + } + framebuffers.clear(); +} + +GLRenderManager::GLRenderManager() { + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + + } +} + +GLRenderManager::~GLRenderManager() { + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + _assert_(frameData_[i].deleter.IsEmpty()); + _assert_(frameData_[i].deleter_prev.IsEmpty()); + } + // Was anything deleted during shutdown? + deleter_.Perform(); + _assert_(deleter_.IsEmpty()); +} + +void GLRenderManager::ThreadStart() { + queueRunner_.CreateDeviceObjects(); + threadFrame_ = threadInitFrame_; + + bool mapBuffers = (gl_extensions.bugs & BUG_ANY_MAP_BUFFER_RANGE_SLOW) == 0; + bool hasBufferStorage = gl_extensions.ARB_buffer_storage || gl_extensions.EXT_buffer_storage; + if (!gl_extensions.VersionGEThan(3, 0, 0) && gl_extensions.IsGLES && !hasBufferStorage) { + // Force disable if it wouldn't work anyway. + mapBuffers = false; + } + + // Notes on buffer mapping: + // NVIDIA GTX 9xx / 2017-10 drivers - mapping improves speed, basic unmap seems best. + // PowerVR GX6xxx / iOS 10.3 - mapping has little improvement, explicit flush is slower. + if (mapBuffers) { + switch (gl_extensions.gpuVendor) { + case GPU_VENDOR_NVIDIA: + bufferStrategy_ = GLBufferStrategy::FRAME_UNMAP; + break; + + case GPU_VENDOR_QUALCOMM: + bufferStrategy_ = GLBufferStrategy::FLUSH_INVALIDATE_UNMAP; + break; + + default: + bufferStrategy_ = GLBufferStrategy::SUBDATA; + } + } else { + bufferStrategy_ = GLBufferStrategy::SUBDATA; + } +} + +void GLRenderManager::ThreadEnd() { + ILOG("ThreadEnd"); + + // Wait for any shutdown to complete in StopThread(). + std::unique_lock lock(mutex_); + queueRunner_.DestroyDeviceObjects(); + VLOG("PULL: Quitting"); + + // Good point to run all the deleters to get rid of leftover objects. + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + frameData_[i].deleter.Perform(); + frameData_[i].deleter_prev.Perform(); + for (int j = 0; j < (int)frameData_[i].steps.size(); j++) { + delete frameData_[i].steps[j]; + } + frameData_[i].steps.clear(); + frameData_[i].initSteps.clear(); + } + deleter_.Perform(); + + for (int i = 0; i < (int)steps_.size(); i++) { + delete steps_[i]; + } + steps_.clear(); + initSteps_.clear(); +} + +bool GLRenderManager::ThreadFrame() { + std::unique_lock lock(mutex_); + if (!run_) + return false; + + // In case of syncs or other partial completion, we keep going until we complete a frame. + do { + if (nextFrame) { + threadFrame_++; + if (threadFrame_ >= MAX_INFLIGHT_FRAMES) + threadFrame_ = 0; + } + FrameData &frameData = frameData_[threadFrame_]; + { + std::unique_lock lock(frameData.pull_mutex); + while (!frameData.readyForRun && run_) { + VLOG("PULL: Waiting for frame[%d].readyForRun", threadFrame_); + frameData.pull_condVar.wait(lock); + } + if (!frameData.readyForRun && !run_) { + // This means we're out of frames to render and run_ is false, so bail. + return false; + } + VLOG("PULL: Setting frame[%d].readyForRun = false", threadFrame_); + frameData.readyForRun = false; + frameData.deleter_prev.Perform(); + frameData.deleter_prev.Take(frameData.deleter); + // Previously we had a quick exit here that avoided calling Run() if run_ was suddenly false, + // but that created a race condition where frames could end up not finished properly on resize etc. + + // Only increment next time if we're done. + nextFrame = frameData.type == GLRRunType::END; + assert(frameData.type == GLRRunType::END || frameData.type == GLRRunType::SYNC); + } + VLOG("PULL: Running frame %d", threadFrame_); + if (firstFrame) { + ILOG("Running first frame (%d)", threadFrame_); + firstFrame = false; + } + Run(threadFrame_); + VLOG("PULL: Finished frame %d", threadFrame_); + } while (!nextFrame); + return true; +} + +void GLRenderManager::StopThread() { + // Since we don't control the thread directly, this will only pause the thread. + + if (run_) { + run_ = false; + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + auto &frameData = frameData_[i]; + { + std::unique_lock lock(frameData.push_mutex); + frameData.push_condVar.notify_all(); + } + { + std::unique_lock lock(frameData.pull_mutex); + frameData.pull_condVar.notify_all(); + } + } + + // Wait until we've definitely stopped the threadframe. + std::unique_lock lock(mutex_); + + ILOG("GL submission thread paused. Frame=%d", curFrame_); + + // Eat whatever has been queued up for this frame if anything. + Wipe(); + + // Wait for any fences to finish and be resignaled, so we don't have sync issues. + // Also clean out any queued data, which might refer to things that might not be valid + // when we restart... + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + auto &frameData = frameData_[i]; + std::unique_lock lock(frameData.push_mutex); + if (frameData.readyForRun || frameData.steps.size() != 0) { + Crash(); + } + frameData.readyForRun = false; + frameData.readyForSubmit = false; + for (size_t i = 0; i < frameData.steps.size(); i++) { + delete frameData.steps[i]; + } + frameData.steps.clear(); + frameData.initSteps.clear(); + + while (!frameData.readyForFence) { + VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (stop)", i); + frameData.push_condVar.wait(lock); + } + } + } else { + ILOG("GL submission thread was already paused."); + } +} + +void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil) { + assert(insideFrame_); + // Eliminate dupes. + if (steps_.size() && steps_.back()->render.framebuffer == fb && steps_.back()->stepType == GLRStepType::RENDER) { + if (color != GLRRenderPassAction::CLEAR && depth != GLRRenderPassAction::CLEAR && stencil != GLRRenderPassAction::CLEAR) { + // We don't move to a new step, this bind was unnecessary and we can safely skip it. + return; + } + } + if (curRenderStep_ && curRenderStep_->commands.size() == 0) { + VLOG("Empty render step. Usually happens after uploading pixels.."); + } + + GLRStep *step = new GLRStep{ GLRStepType::RENDER }; + // This is what queues up new passes, and can end previous ones. + step->render.framebuffer = fb; + step->render.numDraws = 0; + steps_.push_back(step); + + GLuint clearMask = 0; + GLRRenderData data; + data.cmd = GLRRenderCommand::CLEAR; + if (color == GLRRenderPassAction::CLEAR) { + clearMask |= GL_COLOR_BUFFER_BIT; + data.clear.clearColor = clearColor; + } + if (depth == GLRRenderPassAction::CLEAR) { + clearMask |= GL_DEPTH_BUFFER_BIT; + data.clear.clearZ = clearDepth; + } + if (stencil == GLRRenderPassAction::CLEAR) { + clearMask |= GL_STENCIL_BUFFER_BIT; + data.clear.clearStencil = clearStencil; + } + if (clearMask) { + data.clear.scissorX = 0; + data.clear.scissorY = 0; + data.clear.scissorW = 0; + data.clear.scissorH = 0; + data.clear.clearMask = clearMask; + data.clear.colorMask = 0xF; + step->commands.push_back(data); + } + curRenderStep_ = step; + + // Every step clears this state. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); +} + +void GLRenderManager::BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BIND_FB_TEXTURE }; + data.bind_fb_texture.slot = binding; + data.bind_fb_texture.framebuffer = fb; + data.bind_fb_texture.aspect = aspectBit; + curRenderStep_->commands.push_back(data); +} + +void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask) { + GLRStep *step = new GLRStep{ GLRStepType::COPY }; + step->copy.srcRect = srcRect; + step->copy.dstPos = dstPos; + step->copy.src = src; + step->copy.dst = dst; + step->copy.aspectMask = aspectMask; + steps_.push_back(step); + + // Every step clears this state. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); +} + +void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter) { + GLRStep *step = new GLRStep{ GLRStepType::BLIT }; + step->blit.srcRect = srcRect; + step->blit.dstRect = dstRect; + step->blit.src = src; + step->blit.dst = dst; + step->blit.aspectMask = aspectMask; + step->blit.filter = filter; + steps_.push_back(step); + + // Every step clears this state. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); +} + +bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { + GLRStep *step = new GLRStep{ GLRStepType::READBACK }; + step->readback.src = src; + step->readback.srcRect = { x, y, w, h }; + step->readback.aspectMask = aspectBits; + step->readback.dstFormat = destFormat; + steps_.push_back(step); + + // Every step clears this state. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); + + curRenderStep_ = nullptr; + FlushSync(); + + Draw::DataFormat srcFormat; + if (aspectBits & GL_COLOR_BUFFER_BIT) { + srcFormat = Draw::DataFormat::R8G8B8A8_UNORM; + } else if (aspectBits & GL_STENCIL_BUFFER_BIT) { + // Copies from stencil are always S8. + srcFormat = Draw::DataFormat::S8; + } else if (aspectBits & GL_DEPTH_BUFFER_BIT) { + // TODO: Do this properly. + srcFormat = Draw::DataFormat::D24_S8; + } else { + _assert_(false); + } + queueRunner_.CopyReadbackBuffer(w, h, srcFormat, destFormat, pixelStride, pixels); + return true; +} + +void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { + GLRStep *step = new GLRStep{ GLRStepType::READBACK_IMAGE }; + step->readback_image.texture = texture; + step->readback_image.mipLevel = mipLevel; + step->readback_image.srcRect = { x, y, w, h }; + steps_.push_back(step); + + // Every step clears this state. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); + + curRenderStep_ = nullptr; + FlushSync(); + + queueRunner_.CopyReadbackBuffer(w, h, Draw::DataFormat::R8G8B8A8_UNORM, destFormat, pixelStride, pixels); +} + +void GLRenderManager::BeginFrame() { + VLOG("BeginFrame"); + + int curFrame = GetCurFrame(); + FrameData &frameData = frameData_[curFrame]; + + // Make sure the very last command buffer from the frame before the previous has been fully executed. + { + std::unique_lock lock(frameData.push_mutex); + while (!frameData.readyForFence) { + VLOG("PUSH: Waiting for frame[%d].readyForFence = 1", curFrame); + frameData.push_condVar.wait(lock); + } + frameData.readyForFence = false; + frameData.readyForSubmit = true; + } + + VLOG("PUSH: Fencing %d", curFrame); + + // glFenceSync(&frameData.fence...) + + // Must be after the fence - this performs deletes. + VLOG("PUSH: BeginFrame %d", curFrame); + if (!run_) { + WLOG("BeginFrame while !run_!"); + } + + // vulkan_->BeginFrame(); + // In GL, we have to do deletes on the submission thread. + + insideFrame_ = true; +} + +void GLRenderManager::Finish() { + curRenderStep_ = nullptr; + int curFrame = GetCurFrame(); + FrameData &frameData = frameData_[curFrame]; + { + std::unique_lock lock(frameData.pull_mutex); + VLOG("PUSH: Frame[%d].readyForRun = true, notifying pull", curFrame); + frameData.steps = std::move(steps_); + steps_.clear(); + frameData.initSteps = std::move(initSteps_); + initSteps_.clear(); + frameData.readyForRun = true; + frameData.type = GLRRunType::END; + frameData_[curFrame_].deleter.Take(deleter_); + } + + // Notify calls do not in fact need to be done with the mutex locked. + frameData.pull_condVar.notify_all(); + + curFrame_++; + if (curFrame_ >= MAX_INFLIGHT_FRAMES) + curFrame_ = 0; + + insideFrame_ = false; +} + +void GLRenderManager::BeginSubmitFrame(int frame) { + FrameData &frameData = frameData_[frame]; + if (!frameData.hasBegun) { + frameData.hasBegun = true; + } +} + +// Render thread +void GLRenderManager::Submit(int frame, bool triggerFence) { + FrameData &frameData = frameData_[frame]; + + // In GL, submission happens automatically in Run(). + + // When !triggerFence, we notify after syncing with Vulkan. + + if (triggerFence) { + VLOG("PULL: Frame %d.readyForFence = true", frame); + + std::unique_lock lock(frameData.push_mutex); + assert(frameData.readyForSubmit); + frameData.readyForFence = true; + frameData.readyForSubmit = false; + frameData.push_condVar.notify_all(); + } +} + +// Render thread +void GLRenderManager::EndSubmitFrame(int frame) { + FrameData &frameData = frameData_[frame]; + frameData.hasBegun = false; + + Submit(frame, true); + + if (!frameData.skipSwap) { + if (swapIntervalChanged_) { + swapIntervalChanged_ = false; + if (swapIntervalFunction_) { + swapIntervalFunction_(swapInterval_); + } + } + if (swapFunction_) { + swapFunction_(); + } + } else { + frameData.skipSwap = false; + } +} + +// Render thread +void GLRenderManager::Run(int frame) { + BeginSubmitFrame(frame); + + FrameData &frameData = frameData_[frame]; + + auto &stepsOnThread = frameData_[frame].steps; + auto &initStepsOnThread = frameData_[frame].initSteps; + // queueRunner_.LogSteps(stepsOnThread); + queueRunner_.RunInitSteps(initStepsOnThread); + + // Run this after RunInitSteps so any fresh GLRBuffers for the pushbuffers can get created. + for (auto iter : frameData.activePushBuffers) { + iter->Flush(); + iter->UnmapDevice(); + } + + queueRunner_.RunSteps(stepsOnThread); + stepsOnThread.clear(); + initStepsOnThread.clear(); + + for (auto iter : frameData.activePushBuffers) { + iter->MapDevice(bufferStrategy_); + } + + switch (frameData.type) { + case GLRRunType::END: + EndSubmitFrame(frame); + break; + + case GLRRunType::SYNC: + EndSyncFrame(frame); + break; + + default: + assert(false); + } + + VLOG("PULL: Finished running frame %d", frame); +} + +void GLRenderManager::FlushSync() { + // TODO: Reset curRenderStep_? + int curFrame = curFrame_; + FrameData &frameData = frameData_[curFrame]; + { + std::unique_lock lock(frameData.pull_mutex); + VLOG("PUSH: Frame[%d].readyForRun = true (sync)", curFrame); + frameData.initSteps = std::move(initSteps_); + initSteps_.clear(); + frameData.steps = std::move(steps_); + steps_.clear(); + frameData.readyForRun = true; + assert(frameData.readyForFence == false); + frameData.type = GLRRunType::SYNC; + frameData.pull_condVar.notify_all(); + } + { + std::unique_lock lock(frameData.push_mutex); + // Wait for the flush to be hit, since we're syncing. + while (!frameData.readyForFence) { + VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (sync)", curFrame); + frameData.push_condVar.wait(lock); + } + frameData.readyForFence = false; + frameData.readyForSubmit = true; + } +} + +// Render thread +void GLRenderManager::EndSyncFrame(int frame) { + FrameData &frameData = frameData_[frame]; + Submit(frame, false); + + // glFinish is not actually necessary here, and won't be until we start using + // glBufferStorage. Then we need to use fences. + // glFinish(); + + // At this point we can resume filling the command buffers for the current frame since + // we know the device is idle - and thus all previously enqueued command buffers have been processed. + // No need to switch to the next frame number. + + { + std::unique_lock lock(frameData.push_mutex); + frameData.readyForFence = true; + frameData.readyForSubmit = true; + frameData.push_condVar.notify_all(); + } +} + +void GLRenderManager::Wipe() { + initSteps_.clear(); + for (auto step : steps_) { + delete step; + } + steps_.clear(); +} + +void GLRenderManager::WaitUntilQueueIdle() { + // Just wait for all frames to be ready. + for (int i = 0; i < MAX_INFLIGHT_FRAMES; i++) { + FrameData &frameData = frameData_[i]; + + std::unique_lock lock(frameData.push_mutex); + // Ignore unsubmitted frames. + while (!frameData.readyForFence && frameData.readyForRun) { + VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (wait idle)", i); + frameData.push_condVar.wait(lock); + } + } +} + +GLPushBuffer::GLPushBuffer(GLRenderManager *render, GLuint target, size_t size) : render_(render), target_(target), size_(size) { + bool res = AddBuffer(); + assert(res); +} + +GLPushBuffer::~GLPushBuffer() { + assert(buffers_.empty()); +} + +void GLPushBuffer::Map() { + assert(!writePtr_); + auto &info = buffers_[buf_]; + writePtr_ = info.deviceMemory ? info.deviceMemory : info.localMemory; + info.flushOffset = 0; + // Force alignment. This is needed for PushAligned() to work as expected. + while ((intptr_t)writePtr_ & 15) { + writePtr_++; + offset_++; + info.flushOffset++; + } + assert(writePtr_); +} + +void GLPushBuffer::Unmap() { + assert(writePtr_); + if (!buffers_[buf_].deviceMemory) { + // Here we simply upload the data to the last buffer. + // Might be worth trying with size_ instead of offset_, so the driver can replace + // the whole buffer. At least if it's close. + render_->BufferSubdata(buffers_[buf_].buffer, 0, offset_, buffers_[buf_].localMemory, false); + } else { + buffers_[buf_].flushOffset = offset_; + } + writePtr_ = nullptr; +} + +void GLPushBuffer::Flush() { + // Must be called from the render thread. + buffers_[buf_].flushOffset = offset_; + if (!buffers_[buf_].deviceMemory && writePtr_) { + auto &info = buffers_[buf_]; + if (info.flushOffset != 0) { + assert(info.buffer->buffer); + glBindBuffer(target_, info.buffer->buffer); + glBufferSubData(target_, 0, info.flushOffset, info.localMemory); + } + + // Here we will submit all the draw calls, with the already known buffer and offsets. + // Might as well reset the write pointer here and start over the current buffer. + writePtr_ = info.localMemory; + offset_ = 0; + info.flushOffset = 0; + } + + // For device memory, we flush all buffers here. + if ((strategy_ & GLBufferStrategy::MASK_FLUSH) != 0) { + for (auto &info : buffers_) { + if (info.flushOffset == 0 || !info.deviceMemory) + continue; + + glBindBuffer(target_, info.buffer->buffer); + glFlushMappedBufferRange(target_, 0, info.flushOffset); + info.flushOffset = 0; + } + } +} + +bool GLPushBuffer::AddBuffer() { + BufInfo info; + info.localMemory = (uint8_t *)AllocateAlignedMemory(size_, 16); + info.buffer = render_->CreateBuffer(target_, size_, GL_DYNAMIC_DRAW); + buf_ = buffers_.size(); + buffers_.push_back(info); + return true; +} + +void GLPushBuffer::Destroy() { + for (BufInfo &info : buffers_) { + // This will automatically unmap device memory, if needed. + render_->DeleteBuffer(info.buffer); + FreeAlignedMemory(info.localMemory); + } + buffers_.clear(); +} + +void GLPushBuffer::NextBuffer(size_t minSize) { + // First, unmap the current memory. + Unmap(); + + buf_++; + if (buf_ >= buffers_.size() || minSize > size_) { + // Before creating the buffer, adjust to the new size_ if necessary. + while (size_ < minSize) { + size_ <<= 1; + } + + bool res = AddBuffer(); + assert(res); + if (!res) { + // Let's try not to crash at least? + buf_ = 0; + } + } + + // Now, move to the next buffer and map it. + offset_ = 0; + Map(); +} + +void GLPushBuffer::Defragment() { + if (buffers_.size() <= 1) { + // Let's take this chance to jetison localMemory we don't need. + for (auto &info : buffers_) { + if (info.deviceMemory) { + FreeAlignedMemory(info.localMemory); + info.localMemory = nullptr; + } + } + + return; + } + + // Okay, we have more than one. Destroy them all and start over with a larger one. + size_t newSize = size_ * buffers_.size(); + Destroy(); + + size_ = newSize; + bool res = AddBuffer(); + assert(res); +} + +size_t GLPushBuffer::GetTotalSize() const { + size_t sum = 0; + if (buffers_.size() > 1) + sum += size_ * (buffers_.size() - 1); + sum += offset_; + return sum; +} + +void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { + strategy_ = strategy; + if (strategy_ == GLBufferStrategy::SUBDATA) { + return; + } + + bool mapChanged = false; + for (auto &info : buffers_) { + if (!info.buffer->buffer || info.deviceMemory) { + // Can't map - no device buffer associated yet or already mapped. + continue; + } + + info.deviceMemory = (uint8_t *)info.buffer->Map(strategy_); + mapChanged = mapChanged || info.deviceMemory != nullptr; + + if (!info.deviceMemory && !info.localMemory) { + // Somehow it failed, let's dodge crashing. + info.localMemory = (uint8_t *)AllocateAlignedMemory(info.buffer->size_, 16); + mapChanged = true; + } + + assert(info.localMemory || info.deviceMemory); + } + + if (writePtr_ && mapChanged) { + // This can happen during a sync. Remap. + writePtr_ = nullptr; + Map(); + } +} + +void GLPushBuffer::UnmapDevice() { + for (auto &info : buffers_) { + if (info.deviceMemory) { + // TODO: Technically this can return false? + info.buffer->Unmap(); + info.deviceMemory = nullptr; + } + } +} + +void *GLRBuffer::Map(GLBufferStrategy strategy) { + assert(buffer != 0); + + GLbitfield access = GL_MAP_WRITE_BIT; + if ((strategy & GLBufferStrategy::MASK_FLUSH) != 0) { + access |= GL_MAP_FLUSH_EXPLICIT_BIT; + } + if ((strategy & GLBufferStrategy::MASK_INVALIDATE) != 0) { + access |= GL_MAP_INVALIDATE_BUFFER_BIT; + } + + void *p = nullptr; + bool allowNativeBuffer = strategy != GLBufferStrategy::SUBDATA; + if (allowNativeBuffer) { + glBindBuffer(target_, buffer); + + if (gl_extensions.ARB_buffer_storage || gl_extensions.EXT_buffer_storage) { +#ifndef IOS + if (!hasStorage_) { + GLbitfield storageFlags = access & ~(GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +#ifdef USING_GLES2 + glBufferStorageEXT(target_, size_, nullptr, storageFlags); +#else + glBufferStorage(target_, size_, nullptr, storageFlags); +#endif + hasStorage_ = true; + } +#endif + p = glMapBufferRange(target_, 0, size_, access); + } else if (gl_extensions.VersionGEThan(3, 0, 0)) { + // GLES3 or desktop 3. + p = glMapBufferRange(target_, 0, size_, access); + } else { +#ifndef USING_GLES2 + p = glMapBuffer(target_, GL_READ_WRITE); +#endif + } + } + + mapped_ = p != nullptr; + return p; +} + +bool GLRBuffer::Unmap() { + glBindBuffer(target_, buffer); + mapped_ = false; + return glUnmapBuffer(target_) == GL_TRUE; +} diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h new file mode 100644 index 0000000000..e697aa3220 --- /dev/null +++ b/ext/native/thin3d/GLRenderManager.h @@ -0,0 +1,908 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "gfx/gl_common.h" +#include "math/dataconv.h" +#include "Common/Log.h" +#include "GLQueueRunner.h" + +class GLRInputLayout; +class GLPushBuffer; + +class GLRTexture { +public: + ~GLRTexture() { + if (texture) { + glDeleteTextures(1, &texture); + } + } + GLuint texture = 0; + // Could also trust OpenGL defaults I guess.. + GLenum target = 0xFFFF; + GLenum wrapS = 0xFFFF; + GLenum wrapT = 0xFFFF; + GLenum magFilter = 0xFFFF; + GLenum minFilter = 0xFFFF; + bool canWrap = true; + float anisotropy = -100000.0f; + float minLod = -1000.0f; + float maxLod = 1000.0f; + float lodBias = 0.0f; +}; + +class GLRFramebuffer { +public: + GLRFramebuffer(int _width, int _height, bool z_stencil) + : width(_width), height(_height), z_stencil_(z_stencil) { + } + + ~GLRFramebuffer(); + + int numShadows = 1; // TODO: Support this. + + GLuint handle = 0; + GLRTexture color_texture; + GLuint z_stencil_buffer = 0; // Either this is set, or the two below. + GLuint z_buffer = 0; + GLuint stencil_buffer = 0; + + int width; + int height; + GLuint colorDepth; + + bool z_stencil_; +}; + +// We need to create some custom heap-allocated types so we can forward things that need to be created on the GL thread, before +// they've actually been created. + +class GLRShader { +public: + ~GLRShader() { + if (shader) { + glDeleteShader(shader); + } + } + GLuint shader = 0; + bool valid = false; + // Warning: Won't know until a future frame. + bool failed = false; + std::string desc; + std::string code; +}; + +class GLRProgram { +public: + ~GLRProgram() { + if (program) { + glDeleteProgram(program); + } + } + struct Semantic { + int location; + const char *attrib; + }; + + struct UniformLocQuery { + GLint *dest; + const char *name; + }; + + struct Initializer { + GLint *uniform; + int type; + int value; + }; + + GLuint program = 0; + std::vector semantics_; + std::vector queries_; + std::vector initialize_; + + struct UniformInfo { + int loc_; + }; + + // Must ONLY be called from GLQueueRunner! + // Also it's pretty slow... + int GetUniformLoc(const char *name) { + auto iter = uniformCache_.find(std::string(name)); + int loc = -1; + if (iter != uniformCache_.end()) { + loc = iter->second.loc_; + } else { + loc = glGetUniformLocation(program, name); + UniformInfo info; + info.loc_ = loc; + uniformCache_[name] = info; + } + return loc; + } + std::unordered_map uniformCache_; +}; + +enum class GLBufferStrategy { + SUBDATA = 0, + + MASK_FLUSH = 0x10, + MASK_INVALIDATE = 0x20, + + // Map/unmap the buffer each frame. + FRAME_UNMAP = 1, + // Map/unmap and also invalidate the buffer on map. + INVALIDATE_UNMAP = MASK_INVALIDATE, + // Map/unmap and explicitly flushed changed ranges. + FLUSH_UNMAP = MASK_FLUSH, + // Map/unmap, invalidate on map, and explicit flush. + FLUSH_INVALIDATE_UNMAP = MASK_FLUSH | MASK_INVALIDATE, +}; + +static inline int operator &(const GLBufferStrategy &lhs, const GLBufferStrategy &rhs) { + return (int)lhs & (int)rhs; +} + +class GLRBuffer { +public: + GLRBuffer(GLuint target, size_t size) : target_(target), size_((int)size) {} + ~GLRBuffer() { + if (buffer) { + glDeleteBuffers(1, &buffer); + } + } + + void *Map(GLBufferStrategy strategy); + bool Unmap(); + + bool Mapped() { + return mapped_; + } + + GLuint buffer = 0; + GLuint target_; + int size_; + +private: + bool mapped_ = false; + bool hasStorage_ = false; +}; + +enum class GLRRunType { + END, + SYNC, +}; + +class GLDeleter { +public: + void Perform(); + + bool IsEmpty() const { + return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty(); + } + void Take(GLDeleter &other) { + _assert_msg_(G3D, IsEmpty(), "Deleter already has stuff"); + shaders = std::move(other.shaders); + programs = std::move(other.programs); + buffers = std::move(other.buffers); + textures = std::move(other.textures); + inputLayouts = std::move(other.inputLayouts); + framebuffers = std::move(other.framebuffers); + other.shaders.clear(); + other.programs.clear(); + other.buffers.clear(); + other.textures.clear(); + other.inputLayouts.clear(); + other.framebuffers.clear(); + } + + std::vector shaders; + std::vector programs; + std::vector buffers; + std::vector textures; + std::vector inputLayouts; + std::vector framebuffers; +}; + +class GLRInputLayout { +public: + struct Entry { + int location; + int count; + GLenum type; + GLboolean normalized; + int stride; + intptr_t offset; + }; + std::vector entries; + int semanticsMask_ = 0; +}; + +// Note: The GLRenderManager is created and destroyed on the render thread, and the latter +// happens after the emu thread has been destroyed. Therefore, it's safe to run wild deleting stuff +// directly in the destructor. +class GLRenderManager { +public: + GLRenderManager(); + ~GLRenderManager(); + + void ThreadStart(); + void ThreadEnd(); + bool ThreadFrame(); // Returns false to request exiting the loop. + + // Makes sure that the GPU has caught up enough that we can start writing buffers of this frame again. + void BeginFrame(); + // Can run on a different thread! + void Finish(); + void Run(int frame); + + // Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown. + void Wipe(); + + // Wait until no frames are pending. Use during shutdown before freeing pointers. + void WaitUntilQueueIdle(); + + // Creation commands. These were not needed in Vulkan since there we can do that on the main thread. + GLRTexture *CreateTexture(GLenum target) { + GLRInitStep step{ GLRInitStepType::CREATE_TEXTURE }; + step.create_texture.texture = new GLRTexture(); + step.create_texture.texture->target = target; + initSteps_.push_back(step); + return step.create_texture.texture; + } + + GLRBuffer *CreateBuffer(GLuint target, size_t size, GLuint usage) { + GLRInitStep step{ GLRInitStepType::CREATE_BUFFER }; + step.create_buffer.buffer = new GLRBuffer(target, size); + step.create_buffer.size = (int)size; + step.create_buffer.usage = usage; + initSteps_.push_back(step); + return step.create_buffer.buffer; + } + + GLRShader *CreateShader(GLuint stage, const std::string &code, const std::string &desc) { + GLRInitStep step{ GLRInitStepType::CREATE_SHADER }; + step.create_shader.shader = new GLRShader(); + step.create_shader.shader->desc = desc; + step.create_shader.stage = stage; + step.create_shader.code = new char[code.size() + 1]; + memcpy(step.create_shader.code, code.data(), code.size() + 1); + initSteps_.push_back(step); + return step.create_shader.shader; + } + + GLRFramebuffer *CreateFramebuffer(int width, int height, bool z_stencil) { + GLRInitStep step{ GLRInitStepType::CREATE_FRAMEBUFFER }; + step.create_framebuffer.framebuffer = new GLRFramebuffer(width, height, z_stencil); + initSteps_.push_back(step); + return step.create_framebuffer.framebuffer; + } + + // Can't replace uniform initializers with direct calls to SetUniform() etc because there might + // not be an active render pass. + GLRProgram *CreateProgram( + std::vector shaders, std::vector semantics, std::vector queries, + std::vector initalizers, bool supportDualSource) { + GLRInitStep step{ GLRInitStepType::CREATE_PROGRAM }; + assert(shaders.size() <= ARRAY_SIZE(step.create_program.shaders)); + step.create_program.program = new GLRProgram(); + step.create_program.program->semantics_ = semantics; + step.create_program.program->queries_ = queries; + step.create_program.program->initialize_ = initalizers; + step.create_program.support_dual_source = supportDualSource; + _assert_msg_(G3D, shaders.size() > 0, "Can't create a program with zero shaders"); + for (size_t i = 0; i < shaders.size(); i++) { + step.create_program.shaders[i] = shaders[i]; + } +#ifdef _DEBUG + for (auto &iter : queries) { + assert(iter.name); + } + for (auto &sem : semantics) { + assert(sem.attrib); + } +#endif + step.create_program.num_shaders = (int)shaders.size(); + initSteps_.push_back(step); + return step.create_program.program; + } + + GLRInputLayout *CreateInputLayout(std::vector &entries) { + GLRInitStep step{ GLRInitStepType::CREATE_INPUT_LAYOUT }; + step.create_input_layout.inputLayout = new GLRInputLayout(); + step.create_input_layout.inputLayout->entries = entries; + for (auto &iter : step.create_input_layout.inputLayout->entries) { + step.create_input_layout.inputLayout->semanticsMask_ |= 1 << iter.location; + } + initSteps_.push_back(step); + return step.create_input_layout.inputLayout; + } + + void DeleteShader(GLRShader *shader) { + deleter_.shaders.push_back(shader); + } + void DeleteProgram(GLRProgram *program) { + deleter_.programs.push_back(program); + } + void DeleteBuffer(GLRBuffer *buffer) { + deleter_.buffers.push_back(buffer); + } + void DeleteTexture(GLRTexture *texture) { + deleter_.textures.push_back(texture); + } + void DeleteInputLayout(GLRInputLayout *inputLayout) { + deleter_.inputLayouts.push_back(inputLayout); + } + void DeleteFramebuffer(GLRFramebuffer *framebuffer) { + deleter_.framebuffers.push_back(framebuffer); + } + + void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil); + void BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment); + bool CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); + void CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); + + void CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask); + void BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter); + + // Takes ownership of data if deleteData = true. + void BufferSubdata(GLRBuffer *buffer, size_t offset, size_t size, uint8_t *data, bool deleteData = true) { + // TODO: Maybe should be a render command instead of an init command? When possible it's better as + // an init command, that's for sure. + GLRInitStep step{ GLRInitStepType::BUFFER_SUBDATA }; + _dbg_assert_(G3D, offset >= 0); + _dbg_assert_(G3D, offset <= buffer->size_ - size); + step.buffer_subdata.buffer = buffer; + step.buffer_subdata.offset = (int)offset; + step.buffer_subdata.size = (int)size; + step.buffer_subdata.data = data; + step.buffer_subdata.deleteData = deleteData; + initSteps_.push_back(step); + } + + // Takes ownership over the data pointer and delete[]-s it. + void TextureImage(GLRTexture *texture, int level, int width, int height, GLenum internalFormat, GLenum format, GLenum type, uint8_t *data, GLRAllocType allocType = GLRAllocType::NEW, bool linearFilter = false) { + GLRInitStep step{ GLRInitStepType::TEXTURE_IMAGE }; + step.texture_image.texture = texture; + step.texture_image.data = data; + step.texture_image.internalFormat = internalFormat; + step.texture_image.format = format; + step.texture_image.type = type; + step.texture_image.level = level; + step.texture_image.width = width; + step.texture_image.height = height; + step.texture_image.allocType = allocType; + step.texture_image.linearFilter = linearFilter; + initSteps_.push_back(step); + } + + void FinalizeTexture(GLRTexture *texture, int maxLevels, bool genMips) { + GLRInitStep step{ GLRInitStepType::TEXTURE_FINALIZE }; + step.texture_finalize.texture = texture; + step.texture_finalize.maxLevel = maxLevels; + step.texture_finalize.genMips = genMips; + initSteps_.push_back(step); + } + + void BindTexture(int slot, GLRTexture *tex) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BINDTEXTURE }; + _dbg_assert_(G3D, slot < 16); + data.texture.slot = slot; + data.texture.texture = tex; + curRenderStep_->commands.push_back(data); + } + + void BindProgram(GLRProgram *program) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BINDPROGRAM }; + _dbg_assert_(G3D, program != nullptr); + data.program.program = program; + curRenderStep_->commands.push_back(data); + } + + void BindPixelPackBuffer(GLRBuffer *buffer) { // Want to support an offset but can't in ES 2.0. We supply an offset when binding the buffers instead. + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BIND_BUFFER }; + data.bind_buffer.buffer = buffer; + data.bind_buffer.target = GL_PIXEL_PACK_BUFFER; + curRenderStep_->commands.push_back(data); + } + + void BindIndexBuffer(GLRBuffer *buffer) { // Want to support an offset but can't in ES 2.0. We supply an offset when binding the buffers instead. + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BIND_BUFFER}; + data.bind_buffer.buffer = buffer; + data.bind_buffer.target = GL_ELEMENT_ARRAY_BUFFER; + curRenderStep_->commands.push_back(data); + } + + void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + assert(inputLayout); + GLRRenderData data{ GLRRenderCommand::BIND_VERTEX_BUFFER }; + data.bindVertexBuffer.inputLayout = inputLayout; + data.bindVertexBuffer.offset = offset; + data.bindVertexBuffer.buffer = buffer; + curRenderStep_->commands.push_back(data); + } + + void SetDepth(bool enabled, bool write, GLenum func) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::DEPTH }; + data.depth.enabled = enabled; + data.depth.write = write; + data.depth.func = func; + curRenderStep_->commands.push_back(data); + } + + void SetViewport(const GLRViewport &vp) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::VIEWPORT }; + data.viewport.vp = vp; + curRenderStep_->commands.push_back(data); + } + + void SetScissor(const GLRect2D &rc) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::SCISSOR }; + data.scissor.rc = rc; + curRenderStep_->commands.push_back(data); + } + + void SetUniformI(GLint *loc, int count, const int *udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORM4I }; + data.uniform4.loc = loc; + data.uniform4.count = count; + memcpy(data.uniform4.v, udata, sizeof(int) * count); + curRenderStep_->commands.push_back(data); + } + + void SetUniformI1(GLint *loc, int udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORM4I }; + data.uniform4.loc = loc; + data.uniform4.count = 1; + memcpy(data.uniform4.v, &udata, sizeof(udata)); + curRenderStep_->commands.push_back(data); + } + + void SetUniformF(GLint *loc, int count, const float *udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; + data.uniform4.loc = loc; + data.uniform4.count = count; + memcpy(data.uniform4.v, udata, sizeof(float) * count); + curRenderStep_->commands.push_back(data); + } + + void SetUniformF1(GLint *loc, const float udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; + data.uniform4.loc = loc; + data.uniform4.count = 1; + memcpy(data.uniform4.v, &udata, sizeof(float)); + curRenderStep_->commands.push_back(data); + } + + void SetUniformF(const char *name, int count, const float *udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; + data.uniform4.name = name; + data.uniform4.count = count; + memcpy(data.uniform4.v, udata, sizeof(float) * count); + curRenderStep_->commands.push_back(data); + } + + void SetUniformM4x4(GLint *loc, const float *udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORMMATRIX }; + data.uniformMatrix4.loc = loc; + memcpy(data.uniformMatrix4.m, udata, sizeof(float) * 16); + curRenderStep_->commands.push_back(data); + } + + void SetUniformM4x4(const char *name, const float *udata) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::UNIFORMMATRIX }; + data.uniformMatrix4.name = name; + memcpy(data.uniformMatrix4.m, udata, sizeof(float) * 16); + curRenderStep_->commands.push_back(data); + } + + void SetBlendAndMask(int colorMask, bool blendEnabled, GLenum srcColor, GLenum dstColor, GLenum srcAlpha, GLenum dstAlpha, GLenum funcColor, GLenum funcAlpha) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BLEND }; + data.blend.mask = colorMask; + data.blend.enabled = blendEnabled; + data.blend.srcColor = srcColor; + data.blend.dstColor = dstColor; + data.blend.srcAlpha = srcAlpha; + data.blend.dstAlpha = dstAlpha; + data.blend.funcColor = funcColor; + data.blend.funcAlpha = funcAlpha; + curRenderStep_->commands.push_back(data); + } + + void SetNoBlendAndMask(int colorMask) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BLEND }; + data.blend.mask = colorMask; + data.blend.enabled = false; + curRenderStep_->commands.push_back(data); + } + +#ifndef USING_GLES2 + void SetLogicOp(bool enabled, GLenum logicOp) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::LOGICOP }; + data.logic.enabled = enabled; + data.logic.logicOp = logicOp; + curRenderStep_->commands.push_back(data); + } +#endif + + void SetStencilFunc(bool enabled, GLenum func, uint8_t refValue, uint8_t compareMask) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::STENCILFUNC }; + data.stencilFunc.enabled = enabled; + data.stencilFunc.func = func; + data.stencilFunc.ref = refValue; + data.stencilFunc.compareMask = compareMask; + curRenderStep_->commands.push_back(data); + } + + void SetStencilOp(uint8_t writeMask, GLenum sFail, GLenum zFail, GLenum pass) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::STENCILOP }; + data.stencilOp.writeMask = writeMask; + data.stencilOp.sFail = sFail; + data.stencilOp.zFail = zFail; + data.stencilOp.pass = pass; + curRenderStep_->commands.push_back(data); + } + + void SetStencilDisabled() { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data; + data.cmd = GLRRenderCommand::STENCILFUNC; + data.stencilFunc.enabled = false; + curRenderStep_->commands.push_back(data); + } + + void SetBlendFactor(const float color[4]) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::BLENDCOLOR }; + CopyFloat4(data.blendColor.color, color); + curRenderStep_->commands.push_back(data); + } + + void SetRaster(GLboolean cullEnable, GLenum frontFace, GLenum cullFace, GLboolean ditherEnable) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::RASTER }; + data.raster.cullEnable = cullEnable; + data.raster.frontFace = frontFace; + data.raster.cullFace = cullFace; + data.raster.ditherEnable = ditherEnable; + curRenderStep_->commands.push_back(data); + } + + // Modifies the current texture as per GL specs, not global state. + void SetTextureSampler(int slot, GLenum wrapS, GLenum wrapT, GLenum magFilter, GLenum minFilter, float anisotropy) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::TEXTURESAMPLER }; + data.textureSampler.slot = slot; + data.textureSampler.wrapS = wrapS; + data.textureSampler.wrapT = wrapT; + data.textureSampler.magFilter = magFilter; + data.textureSampler.minFilter = minFilter; + data.textureSampler.anisotropy = anisotropy; + curRenderStep_->commands.push_back(data); + } + + void SetTextureLod(int slot, float minLod, float maxLod, float lodBias) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::TEXTURELOD}; + data.textureLod.slot = slot; + data.textureLod.minLod = minLod; + data.textureLod.maxLod = maxLod; + data.textureLod.lodBias = lodBias; + curRenderStep_->commands.push_back(data); + } + + // If scissorW == 0, no scissor is applied. + void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask, int colorMask, int scissorX, int scissorY, int scissorW, int scissorH) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::CLEAR }; + _assert_(clearMask != 0); // What would be the point? + data.clear.clearMask = clearMask; + data.clear.clearColor = clearColor; + data.clear.clearZ = clearZ; + data.clear.clearStencil = clearStencil; + data.clear.colorMask = colorMask; + data.clear.scissorX = scissorX; + data.clear.scissorY = scissorY; + data.clear.scissorW = scissorW; + data.clear.scissorH = scissorH; + curRenderStep_->commands.push_back(data); + } + + void Invalidate(int invalidateMask) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::INVALIDATE }; + data.clear.clearMask = invalidateMask; + curRenderStep_->commands.push_back(data); + } + + void Draw(GLenum mode, int first, int count) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::DRAW }; + data.draw.mode = mode; + data.draw.first = first; + data.draw.count = count; + data.draw.buffer = 0; + curRenderStep_->commands.push_back(data); + curRenderStep_->render.numDraws++; + } + + void DrawIndexed(GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::DRAW_INDEXED }; + data.drawIndexed.mode = mode; + data.drawIndexed.count = count; + data.drawIndexed.indexType = indexType; + data.drawIndexed.instances = instances; + data.drawIndexed.indices = indices; + curRenderStep_->commands.push_back(data); + curRenderStep_->render.numDraws++; + } + + enum { MAX_INFLIGHT_FRAMES = 3 }; + + int GetCurFrame() const { + return curFrame_; + } + + void Resize(int width, int height) { + targetWidth_ = width; + targetHeight_ = height; + queueRunner_.Resize(width, height); + } + + // When using legacy functionality for push buffers (glBufferData), we need to flush them + // before actually making the glDraw* calls. It's best if the render manager handles that. + void RegisterPushBuffer(int frame, GLPushBuffer *buffer) { + frameData_[frame].activePushBuffers.insert(buffer); + } + + void UnregisterPushBuffer(int frame, GLPushBuffer *buffer) { + auto iter = frameData_[frame].activePushBuffers.find(buffer); + _assert_(iter != frameData_[frame].activePushBuffers.end()); + frameData_[frame].activePushBuffers.erase(iter); + } + + void SetSwapFunction(std::function swapFunction) { + swapFunction_ = swapFunction; + } + + void SetSwapIntervalFunction(std::function swapIntervalFunction) { + swapIntervalFunction_ = swapIntervalFunction; + } + + void SwapInterval(int interval) { + if (interval != swapInterval_) { + swapInterval_ = interval; + swapIntervalChanged_ = true; + } + } + + void StopThread(); + + bool SawOutOfMemory() { + return queueRunner_.SawOutOfMemory(); + } + + // Only supports a common subset. + std::string GetGLString(int name) const { + return queueRunner_.GetGLString(name); + } + +private: + void BeginSubmitFrame(int frame); + void EndSubmitFrame(int frame); + void Submit(int frame, bool triggerFence); + + // Bad for performance but sometimes necessary for synchronous CPU readbacks (screenshots and whatnot). + void FlushSync(); + void EndSyncFrame(int frame); + + // Per-frame data, round-robin so we can overlap submission with execution of the previous frame. + struct FrameData { + std::mutex push_mutex; + std::condition_variable push_condVar; + + std::mutex pull_mutex; + std::condition_variable pull_condVar; + + bool readyForFence = true; + bool readyForRun = false; + bool readyForSubmit = false; + bool skipSwap = false; + GLRRunType type = GLRRunType::END; + + // GLuint fence; For future AZDO stuff? + std::vector steps; + std::vector initSteps; + + // Swapchain. + bool hasBegun = false; + uint32_t curSwapchainImage = -1; + + GLDeleter deleter; + GLDeleter deleter_prev; + std::set activePushBuffers; + }; + + FrameData frameData_[MAX_INFLIGHT_FRAMES]; + + // Submission time state + bool insideFrame_ = false; + GLRStep *curRenderStep_ = nullptr; + std::vector steps_; + std::vector initSteps_; + + // Execution time state + bool run_ = true; + // Thread is managed elsewhere, and should call ThreadFrame. + std::mutex mutex_; + int threadInitFrame_ = 0; + GLQueueRunner queueRunner_; + + // Thread state + int threadFrame_; + + bool nextFrame = false; + bool firstFrame = true; + + GLDeleter deleter_; + + int curFrame_ = 0; + + std::function swapFunction_; + std::function swapIntervalFunction_; + GLBufferStrategy bufferStrategy_ = GLBufferStrategy::SUBDATA; + + int swapInterval_ = 0; + bool swapIntervalChanged_ = true; + + int targetWidth_ = 0; + int targetHeight_ = 0; +}; + +// Similar to VulkanPushBuffer but is currently less efficient - it collects all the data in +// RAM then does a big memcpy/buffer upload at the end of the frame. This is at least a lot +// faster than the hundreds of buffer uploads or memory array buffers we used before. +// On modern GL we could avoid the copy using glBufferStorage but not sure it's worth the +// trouble. +class GLPushBuffer { +public: + struct BufInfo { + GLRBuffer *buffer = nullptr; + uint8_t *localMemory = nullptr; + uint8_t *deviceMemory = nullptr; + size_t flushOffset = 0; + }; + +public: + GLPushBuffer(GLRenderManager *render, GLuint target, size_t size); + ~GLPushBuffer(); + + void Destroy(); + + void Reset() { offset_ = 0; } + + // Needs context in case of defragment. + void Begin() { + buf_ = 0; + offset_ = 0; + // Note: we must defrag because some buffers may be smaller than size_. + Defragment(); + Map(); + assert(writePtr_); + } + + void BeginNoReset() { + Map(); + } + + void End() { + Unmap(); + } + + void Map(); + void Unmap(); + + // When using the returned memory, make sure to bind the returned vkbuf. + // This will later allow for handling overflow correctly. + size_t Allocate(size_t numBytes, GLRBuffer **vkbuf) { + size_t out = offset_; + if (offset_ + ((numBytes + 3) & ~3) >= size_) { + NextBuffer(numBytes); + out = offset_; + offset_ += (numBytes + 3) & ~3; + } else { + offset_ += (numBytes + 3) & ~3; // Round up to 4 bytes. + } + *vkbuf = buffers_[buf_].buffer; + return out; + } + + // Returns the offset that should be used when binding this buffer to get this data. + size_t Push(const void *data, size_t size, GLRBuffer **vkbuf) { + assert(writePtr_); + size_t off = Allocate(size, vkbuf); + memcpy(writePtr_ + off, data, size); + return off; + } + + uint32_t PushAligned(const void *data, size_t size, int align, GLRBuffer **vkbuf) { + assert(writePtr_); + offset_ = (offset_ + align - 1) & ~(align - 1); + size_t off = Allocate(size, vkbuf); + memcpy(writePtr_ + off, data, size); + return (uint32_t)off; + } + + size_t GetOffset() const { + return offset_; + } + + // "Zero-copy" variant - you can write the data directly as you compute it. + // Recommended. + void *Push(size_t size, uint32_t *bindOffset, GLRBuffer **vkbuf) { + assert(writePtr_); + size_t off = Allocate(size, vkbuf); + *bindOffset = (uint32_t)off; + return writePtr_ + off; + } + void *PushAligned(size_t size, uint32_t *bindOffset, GLRBuffer **vkbuf, int align) { + assert(writePtr_); + offset_ = (offset_ + align - 1) & ~(align - 1); + size_t off = Allocate(size, vkbuf); + *bindOffset = (uint32_t)off; + return writePtr_ + off; + } + + size_t GetTotalSize() const; + + void Flush(); + +protected: + void MapDevice(GLBufferStrategy strategy); + void UnmapDevice(); + +private: + bool AddBuffer(); + void NextBuffer(size_t minSize); + void Defragment(); + + GLRenderManager *render_; + std::vector buffers_; + size_t buf_ = 0; + size_t offset_ = 0; + size_t size_ = 0; + uint8_t *writePtr_ = nullptr; + GLuint target_; + GLBufferStrategy strategy_ = GLBufferStrategy::SUBDATA; + + friend class GLRenderManager; +}; diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index e693dc834a..2bbf6c2705 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -95,17 +95,26 @@ void VulkanQueueRunner::InitBackbufferRenderPass() { attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; // Don't care about storing backbuffer Z - we clear it anyway. attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + attachments[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + attachments[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; +#else attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +#endif attachments[1].flags = 0; VkAttachmentReference color_reference{}; color_reference.attachment = 0; +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + color_reference.layout = VK_IMAGE_LAYOUT_GENERAL; +#else color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +#endif VkAttachmentReference depth_reference{}; depth_reference.attachment = 1; - depth_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depth_reference.layout = attachments[1].finalLayout; VkSubpassDescription subpass{}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; @@ -141,8 +150,8 @@ void VulkanQueueRunner::InitBackbufferRenderPass() { assert(res == VK_SUCCESS); } -VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction) { - RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction }; +VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction, VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout) { + RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction, prevColorLayout, prevDepthLayout, finalColorLayout }; auto pass = renderPasses_.Get(key); if (pass) { return pass; @@ -166,8 +175,13 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadActio attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // TODO: Look into auto-transitioning to SAMPLED when appropriate. +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + attachments[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + attachments[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; +#else + attachments[0].initialLayout = prevColorLayout; + attachments[0].finalLayout = finalColorLayout; +#endif attachments[0].flags = 0; attachments[1].format = vulkan_->GetDeviceInfo().preferredDepthStencilFormat; @@ -196,8 +210,13 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadActio } attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + attachments[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; + attachments[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; +#else + attachments[1].initialLayout = prevDepthLayout; attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +#endif attachments[1].flags = 0; VkAttachmentReference color_reference{}; @@ -220,12 +239,104 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadActio subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = nullptr; + VkSubpassDependency deps[2]{}; + int numDeps = 0; + switch (prevColorLayout) { + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Already the right color layout. Unclear that we need to do a lot here.. + break; + case VK_IMAGE_LAYOUT_GENERAL: + // We came from the Mali workaround, and are transitioning back to COLOR_ATTACHMENT_OPTIMAL. + deps[numDeps].srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_SHADER_READ_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_TRANSFER_WRITE_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + default: + _dbg_assert_msg_(G3D, false, "GetRenderPass: Unexpected color layout %d", (int)prevColorLayout); + break; + } + + switch (prevDepthLayout) { + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Already the right depth layout. Unclear that we need to do a lot here.. + break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_SHADER_READ_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + deps[numDeps].srcAccessMask |= VK_ACCESS_TRANSFER_WRITE_BIT; + deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + default: + _dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected depth layout %d", (int)prevDepthLayout); + break; + } + + if (deps[numDeps].srcAccessMask) { + deps[numDeps].srcSubpass = VK_SUBPASS_EXTERNAL; + deps[numDeps].dstSubpass = 0; + deps[numDeps].dependencyFlags = 0; + deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + deps[numDeps].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + numDeps++; + } + + // And the final transition. + // Don't need to transition it if VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. + switch (finalColorLayout) { + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + deps[numDeps].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + deps[numDeps].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + deps[numDeps].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_UNDEFINED: + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Nothing to do. + break; + } + + if (deps[numDeps].dstAccessMask) { + deps[numDeps].srcSubpass = 0; + deps[numDeps].dstSubpass = VK_SUBPASS_EXTERNAL; + deps[numDeps].dependencyFlags = 0; + deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + deps[numDeps].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + numDeps++; + } + VkRenderPassCreateInfo rp{ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO }; rp.attachmentCount = 2; rp.pAttachments = attachments; rp.subpassCount = 1; rp.pSubpasses = &subpass; - rp.dependencyCount = 0; + + if (numDeps) { + rp.dependencyCount = numDeps; + rp.pDependencies = deps; + } VkResult res = vkCreateRenderPass(vulkan_->GetDevice(), &rp, nullptr, &pass); _assert_(res == VK_SUCCESS); @@ -236,12 +347,54 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadActio void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, const std::vector &steps) { // Optimizes renderpasses, then sequences them. // Planned optimizations: - // * Push down empty "Clear/Store" renderpasses, and merge them with the first "Load/Store" to the same framebuffer. - // (These happen in Wipeout) // * Create copies of render target that are rendered to multiple times and textured from in sequence, and push those render passes // as early as possible in the frame (Wipeout billboards). - for (int i = 0; i < steps.size(); i++) { + // Push down empty "Clear/Store" renderpasses, and merge them with the first "Load/Store" to the same framebuffer. + // Actually let's just bother with the first one for now. This affects Wipeout Pure. + for (int j = 0; j < (int)steps.size() - 1; j++) { + if (steps[j]->stepType == VKRStepType::RENDER && + steps[j]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + // Just leave it at color_optimal. + steps[j]->render.finalColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + + if (steps.size() > 1 && steps[j]->stepType == VKRStepType::RENDER && + steps[j]->render.numDraws == 0 && + steps[j]->render.color == VKRRenderPassAction::CLEAR && + steps[j]->render.stencil == VKRRenderPassAction::CLEAR && + steps[j]->render.depth == VKRRenderPassAction::CLEAR) { + + // Drop the first step, and merge it into the next step that touches the same framebuffer. + for (size_t i = j + 1; i < steps.size(); i++) { + if (steps[i]->stepType == VKRStepType::RENDER && + steps[i]->render.framebuffer == steps[j]->render.framebuffer) { + if (steps[i]->render.color != VKRRenderPassAction::CLEAR) { + steps[i]->render.color = VKRRenderPassAction::CLEAR; + steps[i]->render.clearColor = steps[j]->render.clearColor; + } + if (steps[i]->render.depth != VKRRenderPassAction::CLEAR) { + steps[i]->render.depth = VKRRenderPassAction::CLEAR; + steps[i]->render.clearDepth = steps[j]->render.clearDepth; + } + if (steps[i]->render.stencil != VKRRenderPassAction::CLEAR) { + steps[i]->render.stencil = VKRRenderPassAction::CLEAR; + steps[i]->render.clearStencil = steps[j]->render.clearStencil; + } + // Cheaply skip the first step. + steps[j]->stepType = VKRStepType::RENDER_SKIP; + break; + } else if (steps[i]->stepType == VKRStepType::COPY && + steps[i]->copy.src == steps[j]->render.framebuffer) { + // Can't eliminate the clear if a game copies from it before it's + // rendered to. However this should be rare. + break; + } + } + } + } + + for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; switch (step.stepType) { case VKRStepType::RENDER: @@ -259,6 +412,8 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, const std::vector &steps) { ILOG("======================================="); - for (int i = 0; i < steps.size(); i++) { + for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; switch (step.stepType) { case VKRStepType::RENDER: @@ -284,6 +439,9 @@ void VulkanQueueRunner::LogSteps(const std::vector &steps) { case VKRStepType::READBACK_IMAGE: LogReadbackImage(step); break; + case VKRStepType::RENDER_SKIP: + ILOG("(skipped render pass)"); + break; } } } @@ -390,8 +548,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } } - // Don't execute empty renderpasses. - if (step.commands.empty() && step.render.color == VKRRenderPassAction::KEEP && step.render.depthStencil == VKRRenderPassAction::KEEP) { + // Don't execute empty renderpasses that keep the contents. + if (step.commands.empty() && step.render.color == VKRRenderPassAction::KEEP && step.render.depth == VKRRenderPassAction::KEEP && step.render.stencil == VKRRenderPassAction::KEEP) { // Nothing to do. return; } @@ -498,43 +656,9 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } vkCmdEndRenderPass(cmd); - // Transition the framebuffer if requested. - // Don't need to transition it if VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. - if (fb && step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED && step.render.finalColorLayout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = fb->color.layout; - barrier.subresourceRange.layerCount = 1; - barrier.subresourceRange.levelCount = 1; - barrier.image = fb->color.image; - barrier.srcAccessMask = 0; - switch (barrier.oldLayout) { - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; - default: - Crash(); - } - barrier.newLayout = step.render.finalColorLayout; - switch (barrier.newLayout) { - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - break; - default: - Crash(); - } - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - // we're between passes so it's OK. - // ARM Best Practices guide recommends these stage bits. - vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); - fb->color.layout = barrier.newLayout; + // The renderpass handles the layout transition. + if (fb) { + fb->color.layout = step.render.finalColorLayout; } } @@ -550,72 +674,36 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step framebuf = fb->framebuf; w = fb->width; h = fb->height; - // Now, if the image needs transitioning, let's transition. - // The backbuffer does not, that's handled by VulkanContext. - if (step.render.framebuffer->color.layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - VkAccessFlags srcAccessMask = 0; - VkPipelineStageFlags srcStage = 0; - switch (fb->color.layout) { - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - break; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - break; - default: - _dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected color layout %d", (int)fb->color.layout); - break; - } - // Due to a known bug in the Mali driver, pass the level count explicitly. - TransitionImageLayout2(cmd, fb->color.image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, - fb->color.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - srcStage, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - srcAccessMask, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT); - fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - } - if (fb->depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { - VkAccessFlags srcAccessMask = 0; - VkPipelineStageFlags srcStage = 0; - - switch (fb->depth.layout) { - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - break; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - break; - default: - _dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected depth layout %d", (int)fb->color.layout); - break; - } - - // Due to a known bug in the Mali driver, pass the level count explicitly (last param). - TransitionImageLayout2(cmd, fb->depth.image, 0, 1, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, - fb->depth.layout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - srcStage, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - srcAccessMask, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT); - fb->depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + // Mali driver on S8 (Android O) and S9 mishandles renderpasses that do just a clear + // and then no draw calls. Memory transaction elimination gets mis-flagged or something. + // To avoid this, we transition to GENERAL and back in this case (ARM-approved workaround). + // See pull request #10723. + bool maliBugWorkaround = step.render.numDraws == 0 && + step.render.color == VKRRenderPassAction::CLEAR && + vulkan_->GetPhysicalDeviceProperties().driverVersion == 0xaa9c4b29; + if (maliBugWorkaround) { + TransitionImageLayout2(cmd, step.render.framebuffer->color.image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + fb->color.layout, VK_IMAGE_LAYOUT_GENERAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + fb->color.layout = VK_IMAGE_LAYOUT_GENERAL; } - renderPass = GetRenderPass(step.render.color, step.render.depthStencil, step.render.depthStencil); + renderPass = GetRenderPass( + step.render.color, step.render.depth, step.render.stencil, + fb->color.layout, fb->depth.layout, step.render.finalColorLayout); + + // We now do any layout pretransitions as part of the render pass. + fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + fb->depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + if (step.render.color == VKRRenderPassAction::CLEAR) { Uint8x4ToFloat4(clearVal[0].color.float32, step.render.clearColor); numClearVals = 1; } - if (step.render.depthStencil == VKRRenderPassAction::CLEAR) { + if (step.render.depth == VKRRenderPassAction::CLEAR || step.render.stencil == VKRRenderPassAction::CLEAR) { clearVal[1].depthStencil.depth = step.render.clearDepth; clearVal[1].depthStencil.stencil = step.render.clearStencil; numClearVals = 2; @@ -833,6 +921,24 @@ void VulkanQueueRunner::SetupTransitionToTransferSrc(VKRImage &img, VkImageMemor barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; img.layout = barrier.newLayout; + + // NOTE: Must do this AFTER updating img.layout to avoid behaviour differences. +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) { + if (barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || barrier.oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + if (barrier.newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || barrier.newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + if (aspect != VK_IMAGE_ASPECT_COLOR_BIT) { + if (barrier.oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || barrier.oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + if (barrier.newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || barrier.newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif } void VulkanQueueRunner::SetupTransitionToTransferDst(VKRImage &img, VkImageMemoryBarrier &barrier, VkPipelineStageFlags &stage, VkImageAspectFlags aspect) { @@ -869,6 +975,24 @@ void VulkanQueueRunner::SetupTransitionToTransferDst(VKRImage &img, VkImageMemor barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; img.layout = barrier.newLayout; + + // NOTE: Must do this AFTER updating img.layout to avoid behaviour differences. +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) { + if (barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || barrier.oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + if (barrier.newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || barrier.newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_DEPTH_STENCIL + if (aspect != VK_IMAGE_ASPECT_COLOR_BIT) { + if (barrier.oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || barrier.oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + if (barrier.newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || barrier.newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + } +#endif } void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd) { diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index 1049a5bb80..ff536a803a 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -32,7 +32,7 @@ struct VkRenderData { VkPipelineLayout pipelineLayout; VkDescriptorSet ds; int numUboOffsets; - uint32_t uboOffsets[3]; + uint32_t uboOffsets[2]; VkBuffer vbuffer; VkDeviceSize voffset; uint32_t count; @@ -41,7 +41,7 @@ struct VkRenderData { VkPipelineLayout pipelineLayout; VkDescriptorSet ds; int numUboOffsets; - uint32_t uboOffsets[3]; + uint32_t uboOffsets[2]; VkBuffer vbuffer; // might need to increase at some point VkDeviceSize voffset; VkBuffer ibuffer; @@ -82,6 +82,7 @@ struct VkRenderData { enum class VKRStepType : uint8_t { RENDER, + RENDER_SKIP, COPY, BLIT, READBACK, @@ -108,7 +109,8 @@ struct VKRStep { struct { VKRFramebuffer *framebuffer; VKRRenderPassAction color; - VKRRenderPassAction depthStencil; + VKRRenderPassAction depth; + VKRRenderPassAction stencil; uint32_t clearColor; float clearDepth; int clearStencil; @@ -159,7 +161,8 @@ public: VkRenderPass GetBackbufferRenderPass() const { return backbufferRenderPass_; } - VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction); + VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction, + VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout); inline int RPIndex(VKRRenderPassAction color, VKRRenderPassAction depth) { return (int)depth * 3 + (int)color; @@ -200,6 +203,10 @@ private: VKRRenderPassAction colorAction; VKRRenderPassAction depthAction; VKRRenderPassAction stencilAction; + VkImageLayout prevColorLayout; + VkImageLayout prevDepthLayout; + VkImageLayout finalColorLayout; + // TODO: Also pre-transition depth, for copies etc. }; // Renderpasses, all combinations of preserving or clearing or dont-care-ing fb contents. diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index f57bf4eab0..299bd19073 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1,4 +1,6 @@ #include + +#include "Common/Log.h" #include "base/logging.h" #include "Common/Vulkan/VulkanContext.h" @@ -392,16 +394,16 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { return frameData_[curFrame].initCmd; } -void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, uint32_t clearColor, float clearDepth, uint8_t clearStencil) { +void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil) { assert(insideFrame_); // Eliminate dupes. if (steps_.size() && steps_.back()->render.framebuffer == fb && steps_.back()->stepType == VKRStepType::RENDER) { - if (color != VKRRenderPassAction::CLEAR && depth != VKRRenderPassAction::CLEAR) { + if (color != VKRRenderPassAction::CLEAR && depth != VKRRenderPassAction::CLEAR && stencil != VKRRenderPassAction::CLEAR) { // We don't move to a new step, this bind was unnecessary and we can safely skip it. return; } } - if (curRenderStep_ && curRenderStep_->commands.size() == 0 && curRenderStep_->render.color == VKRRenderPassAction::KEEP && curRenderStep_->render.depthStencil == VKRRenderPassAction::KEEP) { + if (curRenderStep_ && curRenderStep_->commands.size() == 0 && curRenderStep_->render.color == VKRRenderPassAction::KEEP && curRenderStep_->render.depth == VKRRenderPassAction::KEEP && curRenderStep_->render.stencil == VKRRenderPassAction::KEEP) { // Can trivially kill the last empty render step. assert(steps_.back() == curRenderStep_); delete steps_.back(); @@ -416,7 +418,8 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR // This is what queues up new passes, and can end previous ones. step->render.framebuffer = fb; step->render.color = color; - step->render.depthStencil = depth; + step->render.depth= depth; + step->render.stencil = stencil; step->render.clearColor = clearColor; step->render.clearDepth = clearDepth; step->render.clearStencil = clearStencil; @@ -620,7 +623,8 @@ void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearSten curRenderStep_->render.clearDepth = clearZ; curRenderStep_->render.clearStencil = clearStencil; curRenderStep_->render.color = (clearMask & VK_IMAGE_ASPECT_COLOR_BIT) ? VKRRenderPassAction::CLEAR : VKRRenderPassAction::KEEP; - curRenderStep_->render.depthStencil = (clearMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) ? VKRRenderPassAction::CLEAR : VKRRenderPassAction::KEEP; + curRenderStep_->render.depth = (clearMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? VKRRenderPassAction::CLEAR : VKRRenderPassAction::KEEP; + curRenderStep_->render.stencil = (clearMask & VK_IMAGE_ASPECT_STENCIL_BIT) ? VKRRenderPassAction::CLEAR : VKRRenderPassAction::KEEP; } else { VkRenderData data{ VKRRenderCommand::CLEAR }; data.clear.clearColor = clearColor; @@ -632,15 +636,36 @@ void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearSten } void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask) { - _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x < 0"); - _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y < 0"); - _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x + extent > width"); - _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y + extent > height"); - _dbg_assert_msg_(G3D, dstPos.x >= 0, "dstPos offset x < 0"); - _dbg_assert_msg_(G3D, dstPos.y >= 0, "dstPos offset y < 0"); + _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); + _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); + _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); + _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); + + _dbg_assert_msg_(G3D, srcRect.extent.width > 0, "copy srcwidth == 0"); + _dbg_assert_msg_(G3D, srcRect.extent.height > 0, "copy srcheight == 0"); + + _dbg_assert_msg_(G3D, dstPos.x >= 0, "dstPos offset x (%d) < 0", dstPos.x); + _dbg_assert_msg_(G3D, dstPos.y >= 0, "dstPos offset y (%d) < 0", dstPos.y); _dbg_assert_msg_(G3D, dstPos.x + srcRect.extent.width <= (uint32_t)dst->width, "dstPos + extent x > width"); _dbg_assert_msg_(G3D, dstPos.y + srcRect.extent.height <= (uint32_t)dst->height, "dstPos + extent y > height"); + for (int i = (int)steps_.size() - 1; i >= 0; i--) { + if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { + if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + } + break; + } + } + for (int i = (int)steps_.size() - 1; i >= 0; i--) { + if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == dst) { + if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + } + break; + } + } + VKRStep *step = new VKRStep{ VKRStepType::COPY }; step->copy.aspectMask = aspectMask; @@ -655,10 +680,10 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, } void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter) { - _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x < 0"); - _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y < 0"); - _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x + extent > width"); - _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y + extent > height"); + _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); + _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); + _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); + _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); _dbg_assert_msg_(G3D, srcRect.extent.width > 0, "blit srcwidth == 0"); _dbg_assert_msg_(G3D, srcRect.extent.height > 0, "blit srcheight == 0"); @@ -692,12 +717,8 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - break; - } - else if (steps_[i]->render.finalColorLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - Crash(); - // May need to shadow the framebuffer if we re-order passes later. } + break; } } @@ -755,13 +776,13 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { frameData.skipSwap = true; } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); } VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; res = vkBeginCommandBuffer(frameData.mainCmd, &begin); - _assert_msg_(G3D, res == VK_SUCCESS, "vkBeginCommandBuffer failed! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkBeginCommandBuffer failed! result=%s", VulkanResultToString(res)); queueRunner_.SetBackbuffer(framebuffers_[frameData.curSwapchainImage], swapchainImages_[frameData.curSwapchainImage].image); @@ -773,11 +794,11 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { FrameData &frameData = frameData_[frame]; if (frameData.hasInitCommands) { VkResult res = vkEndCommandBuffer(frameData.initCmd); - _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res)); } VkResult res = vkEndCommandBuffer(frameData.mainCmd); - _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res)); VkCommandBuffer cmdBufs[2]; int numCmdBufs = 0; @@ -793,7 +814,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); } numCmdBufs = 0; } @@ -817,7 +838,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%d", (int)splitSubmit_, (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); } // When !triggerFence, we notify after syncing with Vulkan. @@ -849,7 +870,7 @@ void VulkanRenderManager::EndSubmitFrame(int frame) { if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) { // ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain. } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueuePresentKHR failed! result=%d", (int)res); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res)); } } else { frameData.skipSwap = false; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 322738d44f..1443aacc83 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -12,6 +12,7 @@ #include "Common/Vulkan/VulkanContext.h" #include "math/dataconv.h" +#include "math/math_util.h" #include "thin3d/DataFormat.h" #include "thin3d/VulkanQueueRunner.h" @@ -99,7 +100,7 @@ public: // Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown. void Wipe(); - void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, uint32_t clearColor, float clearDepth, uint8_t clearStencil); + void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil); VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment); bool CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); @@ -109,6 +110,7 @@ public: void BindPipeline(VkPipeline pipeline) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(G3D, pipeline != VK_NULL_HANDLE); VkRenderData data{ VKRRenderCommand::BIND_PIPELINE }; data.pipeline.pipeline = pipeline; curRenderStep_->commands.push_back(data); @@ -117,7 +119,14 @@ public: void SetViewport(const VkViewport &vp) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); VkRenderData data{ VKRRenderCommand::VIEWPORT }; - data.viewport.vp = vp; + data.viewport.vp.x = vp.x; + data.viewport.vp.y = vp.y; + data.viewport.vp.width = vp.width; + data.viewport.vp.height = vp.height; + // We can't allow values outside this range unless we use VK_EXT_depth_range_unrestricted. + // Sometimes state mapping produces 65536/65535 which is slightly outside. + data.viewport.vp.maxDepth = clamp_value(vp.maxDepth, 0.0f, 1.0f); + data.viewport.vp.minDepth = clamp_value(vp.minDepth, 0.0f, 1.0f); curRenderStep_->commands.push_back(data); } @@ -167,6 +176,7 @@ public: data.draw.vbuffer = vbuffer; data.draw.voffset = voffset; data.draw.numUboOffsets = numUboOffsets; + assert(numUboOffsets <= ARRAY_SIZE(data.drawIndexed.uboOffsets)); for (int i = 0; i < numUboOffsets; i++) data.draw.uboOffsets[i] = uboOffsets[i]; curRenderStep_->commands.push_back(data); @@ -185,6 +195,7 @@ public: data.drawIndexed.ibuffer = ibuffer; data.drawIndexed.ioffset = ioffset; data.drawIndexed.numUboOffsets = numUboOffsets; + assert(numUboOffsets <= ARRAY_SIZE(data.drawIndexed.uboOffsets)); for (int i = 0; i < numUboOffsets; i++) data.drawIndexed.uboOffsets[i] = uboOffsets[i]; data.drawIndexed.indexType = indexType; @@ -195,14 +206,16 @@ public: VkCommandBuffer GetInitCmd(); VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction) { - return queueRunner_.GetRenderPass(colorLoadAction, depthLoadAction, stencilLoadAction); + return queueRunner_.GetRenderPass(colorLoadAction, depthLoadAction, stencilLoadAction, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } VkRenderPass GetBackbufferRenderPass() { return queueRunner_.GetBackbufferRenderPass(); } VkRenderPass GetCompatibleRenderPass() { if (curRenderStep_ && curRenderStep_->render.framebuffer != nullptr) { - return queueRunner_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR); + return queueRunner_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } else { return queueRunner_.GetBackbufferRenderPass(); } diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index 0cde248021..b877eb6765 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -336,17 +336,25 @@ bool DrawContext::CreatePresets() { return vsPresets_[VS_TEXTURE_COLOR_2D] && vsPresets_[VS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D] && fsPresets_[FS_COLOR_2D]; } -DrawContext::~DrawContext() { +void DrawContext::DestroyPresets() { for (int i = 0; i < VS_MAX_PRESET; i++) { - if (vsPresets_[i]) + if (vsPresets_[i]) { vsPresets_[i]->Release(); + vsPresets_[i] = nullptr; + } } for (int i = 0; i < FS_MAX_PRESET; i++) { - if (fsPresets_[i]) + if (fsPresets_[i]) { fsPresets_[i]->Release(); + fsPresets_[i] = nullptr; + } } } +DrawContext::~DrawContext() { + DestroyPresets(); +} + // TODO: SSE/NEON // Could also make C fake-simd for 64-bit, two 8888 pixels fit in a register :) void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t srcStride, uint32_t width, uint32_t height, DataFormat format) { @@ -391,6 +399,7 @@ void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, u break; case Draw::DataFormat::R8G8B8A8_UNORM: case Draw::DataFormat::UNDEFINED: + default: // Not possible. break; } diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 9c993727d2..d4f4134e65 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -6,7 +6,7 @@ #pragma once -#include +#include #include #include #include @@ -16,26 +16,6 @@ class Matrix4x4; -#ifdef _WIN32 -#ifndef NOMINMAX -#define NOMINMAX -#endif -#define WIN32_LEAN_AND_MEAN -#include -#include -struct IDirect3DDevice9; -struct IDirect3D9; -struct IDirect3DDevice9Ex; -struct IDirect3D9Ex; -struct ID3D11Device; -struct ID3D11DeviceContext; -struct ID3D11Device1; -struct ID3D11DeviceContext1; - -#endif - -class VulkanContext; - namespace Draw { // Useful in UBOs @@ -543,6 +523,7 @@ class DrawContext { public: virtual ~DrawContext(); bool CreatePresets(); + void DestroyPresets(); virtual const DeviceCaps &GetDeviceCaps() const = 0; virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0; @@ -589,7 +570,10 @@ public: // color must be 0, for now. virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0; - virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) = 0; + // deprecated + virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) { + return 0; + } virtual void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) = 0; @@ -632,7 +616,7 @@ public: virtual void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) = 0; // Necessary to correctly flip scissor rectangles etc for OpenGL. - void SetTargetSize(int w, int h) { + virtual void SetTargetSize(int w, int h) { targetWidth_ = w; targetHeight_ = h; } @@ -660,17 +644,8 @@ protected: int targetHeight_; }; -DrawContext *T3DCreateGLContext(); - extern const UniformBufferDesc UBPresetDesc; -#ifdef _WIN32 -DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); -DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd); -#endif - -DrawContext *T3DCreateVulkanContext(VulkanContext *context, bool split); - // UBs for the preset shaders struct VsTexColUB { diff --git a/ext/native/thin3d/thin3d_create.h b/ext/native/thin3d/thin3d_create.h new file mode 100644 index 0000000000..3d4ea0f1a4 --- /dev/null +++ b/ext/native/thin3d/thin3d_create.h @@ -0,0 +1,38 @@ +#pragma once + +#include "thin3d/thin3d.h" + +// Separated this stuff into its own file so we don't get Windows.h included if all we want is the thin3d declarations. + +#ifdef _WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#define WIN32_LEAN_AND_MEAN +#include +#include +struct IDirect3DDevice9; +struct IDirect3D9; +struct IDirect3DDevice9Ex; +struct IDirect3D9Ex; +struct ID3D11Device; +struct ID3D11DeviceContext; +struct ID3D11Device1; +struct ID3D11DeviceContext1; + +#endif + +class VulkanContext; + +namespace Draw { + +DrawContext *T3DCreateGLContext(); + +#ifdef _WIN32 +DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); +DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd); +#endif + +DrawContext *T3DCreateVulkanContext(VulkanContext *context, bool split); + +} // namespace Draw diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 95f9f6532a..5ef1af4874 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -9,23 +9,15 @@ #include "math/dataconv.h" #include "math/lin/matrix4x4.h" #include "thin3d/thin3d.h" +#include "thin3d/DataFormatGL.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" -#include "gfx/GLStateCache.h" #include "gfx_es2/gpu_features.h" -#ifdef IOS -extern void bindDefaultFBO(); -#endif +#include "thin3d/GLRenderManager.h" // #define DEBUG_READ_PIXELS 1 -// Workaround for Retroarch. Simply declare -// extern GLuint g_defaultFBO; -// and set is as appropriate. Can adjust the variables in ext/native/base/display.h as -// appropriate. -GLuint g_defaultFBO = 0; - namespace Draw { static const unsigned short compToGL[] = { @@ -170,29 +162,11 @@ public: bool enabled; GLuint eqCol, eqAlpha; GLuint srcCol, srcAlpha, dstCol, dstAlpha; - bool logicEnabled; - GLuint logicOp; int colorMask; // uint32_t fixedColor; - void Apply() { - if (enabled) { - glEnable(GL_BLEND); - glBlendEquationSeparate(eqCol, eqAlpha); - glBlendFuncSeparate(srcCol, dstCol, srcAlpha, dstAlpha); - } else { - glDisable(GL_BLEND); - } - glColorMask(colorMask & 1, (colorMask >> 1) & 1, (colorMask >> 2) & 1, (colorMask >> 3) & 1); - -#if !defined(USING_GLES2) - if (logicEnabled) { - glEnable(GL_COLOR_LOGIC_OP); - glLogicOp(logicOp); - } else { - glDisable(GL_COLOR_LOGIC_OP); - } -#endif + void Apply(GLRenderManager *render) { + render->SetBlendAndMask(colorMask, enabled, srcCol, dstCol, srcAlpha, dstAlpha, eqCol, eqAlpha); } }; @@ -212,7 +186,7 @@ public: bool depthWriteEnabled; GLuint depthComp; // TODO: Two-sided - GLboolean stencilEnabled; + bool stencilEnabled; GLuint stencilFail; GLuint stencilZFail; GLuint stencilPass; @@ -221,36 +195,17 @@ public: uint8_t stencilCompareMask; uint8_t stencilWriteMask; - void Apply() { - if (depthTestEnabled) { - glEnable(GL_DEPTH_TEST); - glDepthFunc(depthComp); - glDepthMask(depthWriteEnabled); - } else { - glDisable(GL_DEPTH_TEST); - } - if (stencilEnabled) { - glEnable(GL_STENCIL_TEST); - glStencilOpSeparate(GL_FRONT_AND_BACK, stencilFail, stencilZFail, stencilPass); - glStencilFuncSeparate(GL_FRONT_AND_BACK, stencilCompareOp, stencilReference, stencilCompareMask); - glStencilMaskSeparate(GL_FRONT_AND_BACK, stencilWriteMask); - } else { - glDisable(GL_STENCIL_TEST); - } + void Apply(GLRenderManager *render) { + render->SetDepth(depthTestEnabled, depthWriteEnabled, depthComp); + render->SetStencilFunc(stencilEnabled, stencilCompareOp, stencilReference, stencilCompareMask); + render->SetStencilOp(stencilWriteMask, stencilFail, stencilZFail, stencilPass); } }; class OpenGLRasterState : public RasterState { public: - void Apply() { - glEnable(GL_SCISSOR_TEST); - if (!cullEnable) { - glDisable(GL_CULL_FACE); - return; - } - glEnable(GL_CULL_FACE); - glFrontFace(frontFace); - glCullFace(cullMode); + void Apply(GLRenderManager *render) { + render->SetRaster(cullEnable, frontFace, cullMode, false); } GLboolean cullEnable; @@ -275,17 +230,18 @@ GLuint ShaderStageToOpenGL(ShaderStage stage) { class OpenGLShaderModule : public ShaderModule { public: - OpenGLShaderModule(ShaderStage stage) : stage_(stage) { + OpenGLShaderModule(GLRenderManager *render, ShaderStage stage) : render_(render), stage_(stage) { + DLOG("Shader module created (%p)", this); glstage_ = ShaderStageToOpenGL(stage); } ~OpenGLShaderModule() { if (shader_) - glDeleteShader(shader_); + render_->DeleteShader(shader_); } - bool Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize); - GLuint GetShader() const { + bool Compile(GLRenderManager *render, ShaderLanguage language, const uint8_t *data, size_t dataSize); + GLRShader *GetShader() const { return shader_; } const std::string &GetSource() const { return source_; } @@ -298,19 +254,17 @@ public: } private: + GLRenderManager *render_; ShaderStage stage_; ShaderLanguage language_; - GLuint shader_ = 0; + GLRShader *shader_ = nullptr; GLuint glstage_ = 0; bool ok_ = false; std::string source_; // So we can recompile in case of context loss. }; -bool OpenGLShaderModule::Compile(ShaderLanguage language, const uint8_t *data, size_t dataSize) { +bool OpenGLShaderModule::Compile(GLRenderManager *render, ShaderLanguage language, const uint8_t *data, size_t dataSize) { source_ = std::string((const char *)data); - shader_ = glCreateShader(glstage_); - language_ = language; - std::string temp; // Add the prelude on automatically. if (glstage_ == GL_FRAGMENT_SHADER || glstage_ == GL_VERTEX_SHADER) { @@ -318,59 +272,36 @@ bool OpenGLShaderModule::Compile(ShaderLanguage language, const uint8_t *data, s source_ = temp.c_str(); } - const char *code = source_.c_str(); - glShaderSource(shader_, 1, &code, nullptr); - glCompileShader(shader_); - GLint success = 0; - glGetShaderiv(shader_, GL_COMPILE_STATUS, &success); - if (!success) { -#define MAX_INFO_LOG_SIZE 2048 - GLchar infoLog[MAX_INFO_LOG_SIZE]; - GLsizei len = 0; - glGetShaderInfoLog(shader_, MAX_INFO_LOG_SIZE, &len, infoLog); - infoLog[len] = '\0'; - glDeleteShader(shader_); - shader_ = 0; - ILOG("%s Shader compile error:\n%s", glstage_ == GL_FRAGMENT_SHADER ? "Fragment" : "Vertex", infoLog); - } - ok_ = success != 0; - return ok_; + shader_ = render->CreateShader(glstage_, source_, "thin3d"); + return true; } class OpenGLInputLayout : public InputLayout { public: + OpenGLInputLayout(GLRenderManager *render) : render_(render) {} ~OpenGLInputLayout(); - void Apply(const void *base = nullptr); - void Unapply(); - void Compile(); + void Compile(const InputLayoutDesc &desc); bool RequiresBuffer() { - return id_ != 0; + return false; } - InputLayoutDesc desc; - - int semanticsMask_; // Fast way to check what semantics to enable/disable. - int stride_; - GLuint id_; - bool needsEnable_; - intptr_t lastBase_; -}; - -struct UniformInfo { - int loc_; + GLRInputLayout *inputLayout_; + int stride; +private: + GLRenderManager *render_; }; class OpenGLPipeline : public Pipeline { public: - OpenGLPipeline() { - program_ = 0; + OpenGLPipeline(GLRenderManager *render) : render_(render) { } ~OpenGLPipeline() { + DLOG("OpenGLPipeline released"); for (auto &iter : shaders) { iter->Release(); } - glDeleteProgram(program_); + render_->DeleteProgram(program_); if (depthStencil) depthStencil->Release(); if (blend) blend->Release(); if (raster) raster->Release(); @@ -379,8 +310,6 @@ public: bool LinkShaders(); - int GetUniformLoc(const char *name); - bool RequiresBuffer() override { return inputLayout->RequiresBuffer(); } @@ -395,9 +324,9 @@ public: // TODO: Optimize by getting the locations first and putting in a custom struct UniformBufferDesc dynamicUniforms; - GLuint program_; + GLRProgram *program_ = nullptr; private: - std::map uniformCache_; + GLRenderManager *render_; }; class OpenGLFramebuffer; @@ -408,6 +337,11 @@ public: OpenGLContext(); virtual ~OpenGLContext(); + void SetTargetSize(int w, int h) override { + DrawContext::SetTargetSize(w, h); + renderManager_.Resize(w, h); + } + const DeviceCaps &GetDeviceCaps() const override { return caps_; } @@ -432,6 +366,9 @@ public: Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override; + void BeginFrame() override; + void EndFrame() override; + void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override; @@ -443,8 +380,6 @@ public: // color must be 0, for now. void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; - uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override; - void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; void BindSamplerStates(int start, int count, SamplerState **states) override { @@ -458,26 +393,16 @@ public: } void SetScissorRect(int left, int top, int width, int height) override { - int y = top; - if (!curFB_) { - // We render "upside down" to the backbuffer since GL is silly. - y = targetHeight_ - (top + height); - } - glstate.scissorRect.set(left, y, width, height); + renderManager_.SetScissor({ left, top, width, height }); } void SetViewports(int count, Viewport *viewports) override { - // TODO: Use glViewportArrayv. - glViewport((GLint)viewports[0].TopLeftX, (GLint)viewports[0].TopLeftY, (GLsizei)viewports[0].Width, (GLsizei)viewports[0].Height); -#if defined(USING_GLES2) - glDepthRangef(viewports[0].MinDepth, viewports[0].MaxDepth); -#else - glDepthRange(viewports[0].MinDepth, viewports[0].MaxDepth); -#endif + // Same structure, different name. + renderManager_.SetViewport((GLRViewport &)*viewports); } void SetBlendFactor(float color[4]) override { - glBlendColor(color[0], color[1], color[2], color[3]); + renderManager_.SetBlendFactor(color); } void BindTextures(int start, int count, Texture **textures) override; @@ -511,7 +436,7 @@ public: } else { return "OpenGL"; } - case VENDORSTRING: return (const char *)glGetString(GL_VENDOR); + case VENDORSTRING: return renderManager_.GetGLString(GL_VENDOR); case VENDOR: switch (caps_.vendor) { case GPUVendor::VENDOR_AMD: return "VENDOR_AMD"; @@ -526,42 +451,47 @@ public: return "VENDOR_UNKNOWN"; } break; - case DRIVER: return (const char *)glGetString(GL_RENDERER); - case SHADELANGVERSION: return (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); - case APIVERSION: return (const char *)glGetString(GL_VERSION); + case DRIVER: return renderManager_.GetGLString(GL_RENDERER); + case SHADELANGVERSION: return renderManager_.GetGLString(GL_SHADING_LANGUAGE_VERSION); + case APIVERSION: return renderManager_.GetGLString(GL_VERSION); default: return "?"; } } uintptr_t GetNativeObject(NativeObject obj) override { - return 0; + switch (obj) { + case NativeObject::RENDER_MANAGER: + return (uintptr_t)&renderManager_; + default: + return 0; + } } void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override {} private: - OpenGLFramebuffer *fbo_ext_create(const FramebufferDesc &desc); - void fbo_bind_fb_target(bool read, GLuint name); - GLenum fbo_get_fb_target(bool read, GLuint **cached); - void fbo_unbind(); void ApplySamplers(); + GLRenderManager renderManager_; + std::vector boundSamplers_; OpenGLTexture *boundTextures_[8]{}; int maxTextures_ = 0; DeviceCaps caps_{}; - + // Bound state OpenGLPipeline *curPipeline_ = nullptr; OpenGLBuffer *curVBuffers_[4]{}; int curVBufferOffsets_[4]{}; OpenGLBuffer *curIBuffer_ = nullptr; int curIBufferOffset_ = 0; - OpenGLFramebuffer *curFB_; - // Framebuffer state - GLuint currentDrawHandle_ = 0; - GLuint currentReadHandle_ = 0; + // Frames in flight is not such a strict concept as with Vulkan until we start using glBufferStorage and fences. + // But might as well have the structure ready, and can't hurt to rotate buffers. + struct FrameData { + GLPushBuffer *push; + }; + FrameData frameData_[GLRenderManager::MAX_INFLIGHT_FRAMES]; }; OpenGLContext::OpenGLContext() { @@ -591,16 +521,37 @@ OpenGLContext::OpenGLContext() { caps_.vendor = GPUVendor::VENDOR_UNKNOWN; break; } + for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { + frameData_[i].push = new GLPushBuffer(&renderManager_, GL_ARRAY_BUFFER, 64 * 1024); + renderManager_.RegisterPushBuffer(i, frameData_[i].push); + } } OpenGLContext::~OpenGLContext() { + DestroyPresets(); + for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { + renderManager_.UnregisterPushBuffer(i, frameData_[i].push); + frameData_[i].push->Destroy(); + delete frameData_[i].push; + } boundSamplers_.clear(); } +void OpenGLContext::BeginFrame() { + renderManager_.BeginFrame(); + FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; + frameData.push->Begin(); +} + +void OpenGLContext::EndFrame() { + FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; + frameData.push->End(); // upload the data! + renderManager_.Finish(); +} + InputLayout *OpenGLContext::CreateInputLayout(const InputLayoutDesc &desc) { - OpenGLInputLayout *fmt = new OpenGLInputLayout(); - fmt->desc = desc; - fmt->Compile(); + OpenGLInputLayout *fmt = new OpenGLInputLayout(&renderManager_); + fmt->Compile(desc); return fmt; } @@ -628,7 +579,7 @@ inline bool isPowerOf2(int n) { class OpenGLTexture : public Texture { public: - OpenGLTexture(const TextureDesc &desc); + OpenGLTexture(GLRenderManager *render, const TextureDesc &desc); ~OpenGLTexture(); bool HasMips() const { @@ -638,17 +589,15 @@ public: return canWrap_; } TextureType GetType() const { return type_; } - void Bind() { - glBindTexture(target_, tex_); + void Bind(int stage) { + render_->BindTexture(stage, tex_); } - void AutoGenMipmaps(); - private: void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data); - GLuint tex_ = 0; - GLuint target_ = 0; + GLRenderManager *render_; + GLRTexture *tex_; DataFormat format_; TextureType type_; @@ -657,7 +606,7 @@ private: bool canWrap_; }; -OpenGLTexture::OpenGLTexture(const TextureDesc &desc) { +OpenGLTexture::OpenGLTexture(GLRenderManager *render, const TextureDesc &desc) : render_(render) { generatedMips_ = false; canWrap_ = true; width_ = desc.width; @@ -665,16 +614,14 @@ OpenGLTexture::OpenGLTexture(const TextureDesc &desc) { depth_ = desc.depth; format_ = desc.format; type_ = desc.type; - target_ = TypeToTarget(desc.type); + GLenum target = TypeToTarget(desc.type); + tex_ = render->CreateTexture(target); + canWrap_ = isPowerOf2(width_) && isPowerOf2(height_); mipLevels_ = desc.mipLevels; if (!desc.initData.size()) return; - glActiveTexture(GL_TEXTURE0 + 0); - glGenTextures(1, &tex_); - glBindTexture(target_, tex_); - int level = 0; for (auto data : desc.initData) { SetImageData(0, 0, 0, width_, height_, depth_, level, 0, data); @@ -684,141 +631,37 @@ OpenGLTexture::OpenGLTexture(const TextureDesc &desc) { } mipLevels_ = desc.generateMips ? desc.mipLevels : level; -#ifdef USING_GLES2 - if (gl_extensions.GLES3) { - glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, mipLevels_ - 1); - } -#else - glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, mipLevels_ - 1); -#endif - glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, mipLevels_ > 1 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); - glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - + bool genMips = false; if ((int)desc.initData.size() < desc.mipLevels && desc.generateMips) { - ILOG("Generating mipmaps"); - AutoGenMipmaps(); + // Assumes the texture is bound for editing + genMips = true; + generatedMips_ = true; } + render->FinalizeTexture(tex_, mipLevels_, genMips); - // Unbind. - glBindTexture(target_, 0); } OpenGLTexture::~OpenGLTexture() { if (tex_) { - glDeleteTextures(1, &tex_); + render_->DeleteTexture(tex_); tex_ = 0; generatedMips_ = false; } } -void OpenGLTexture::AutoGenMipmaps() { - if (!generatedMips_) { - glBindTexture(target_, tex_); - glGenerateMipmap(target_); - generatedMips_ = true; - } -} - class OpenGLFramebuffer : public Framebuffer { public: - OpenGLFramebuffer() {} - ~OpenGLFramebuffer(); + OpenGLFramebuffer(GLRenderManager *render) : render_(render) {} + ~OpenGLFramebuffer() { + render_->DeleteFramebuffer(framebuffer); + } - GLuint handle = 0; - GLuint color_texture = 0; - GLuint z_stencil_buffer = 0; // Either this is set, or the two below. - GLuint z_buffer = 0; - GLuint stencil_buffer = 0; + GLRenderManager *render_; + GLRFramebuffer *framebuffer; - int width; - int height; FBColorDepth colorDepth; }; - -// TODO: Also output storage format (GL_RGBA8 etc) for modern GL usage. -static bool Thin3DFormatToFormatAndType(DataFormat fmt, GLuint &internalFormat, GLuint &format, GLuint &type, int &alignment) { - alignment = 4; - switch (fmt) { - case DataFormat::R8G8B8A8_UNORM: - internalFormat = GL_RGBA; - format = GL_RGBA; - type = GL_UNSIGNED_BYTE; - break; - - case DataFormat::D32F: - internalFormat = GL_DEPTH_COMPONENT; - format = GL_DEPTH_COMPONENT; - type = GL_FLOAT; - break; - -#ifndef USING_GLES2 - case DataFormat::S8: - internalFormat = GL_STENCIL_INDEX; - format = GL_STENCIL_INDEX; - type = GL_UNSIGNED_BYTE; - alignment = 1; - break; -#endif - - case DataFormat::R8G8B8_UNORM: - internalFormat = GL_RGB; - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - alignment = 1; - break; - - case DataFormat::B4G4R4A4_UNORM_PACK16: - internalFormat = GL_RGBA; - format = GL_RGBA; - type = GL_UNSIGNED_SHORT_4_4_4_4; - alignment = 2; - break; - - case DataFormat::B5G6R5_UNORM_PACK16: - internalFormat = GL_RGB; - format = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5; - alignment = 2; - break; - - case DataFormat::B5G5R5A1_UNORM_PACK16: - internalFormat = GL_RGBA; - format = GL_RGBA; - type = GL_UNSIGNED_SHORT_5_5_5_1; - alignment = 2; - break; - -#ifndef USING_GLES2 - case DataFormat::A4R4G4B4_UNORM_PACK16: - internalFormat = GL_RGBA; - format = GL_RGBA; - type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - alignment = 2; - break; - - case DataFormat::R5G6B5_UNORM_PACK16: - internalFormat = GL_RGB; - format = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5_REV; - alignment = 2; - break; - - case DataFormat::A1R5G5B5_UNORM_PACK16: - internalFormat = GL_RGBA; - format = GL_RGBA; - type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - alignment = 2; - break; -#endif - - default: - ELOG("Thin3d GL: Unsupported texture format %d", (int)fmt); - return false; - } - return true; -} - void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) { if (width != width_ || height != height_ || depth != depth_) { // When switching to texStorage we need to handle this correctly. @@ -835,18 +678,16 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int return; } - CHECK_GL_ERROR_IF_DEBUG(); - switch (target_) { - case GL_TEXTURE_2D: - glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width_, height_, 0, format, type, data); - break; - default: - ELOG("Thin3D GL: Targets other than GL_TEXTURE_2D not yet supported"); - break; - } - CHECK_GL_ERROR_IF_DEBUG(); -} + if (stride == 0) + stride = width; + // Make a copy of data with stride eliminated. + uint8_t *texData = new uint8_t[width * height * alignment]; + for (int y = 0; y < height; y++) { + memcpy(texData + y * width * alignment, data + y * stride * alignment, width * alignment); + } + render_->TextureImage(tex_, level, width, height, internalFormat, format, type, texData); +} #ifdef DEBUG_READ_PIXELS // TODO: Make more generic. @@ -886,65 +727,20 @@ static void LogReadPixelsError(GLenum error) { bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels, int pixelStride) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)src; - fbo_bind_fb_target(true, fb ? fb->handle : 0); - - // Reads from the "bound for read" framebuffer. - if (gl_extensions.GLES3 || !gl_extensions.IsGLES) - glReadBuffer(GL_COLOR_ATTACHMENT0); - - CHECK_GL_ERROR_IF_DEBUG(); - - GLuint internalFormat; - GLuint format; - GLuint type; - int alignment; - if (!Thin3DFormatToFormatAndType(dataFormat, internalFormat, format, type, alignment)) { - assert(false); - } - // Apply the correct alignment. - glPixelStorei(GL_PACK_ALIGNMENT, alignment); - if (!gl_extensions.IsGLES || gl_extensions.GLES3) { - // Even if not required, some drivers seem to require we specify this. See #8254. - glPixelStorei(GL_PACK_ROW_LENGTH, pixelStride); - } - - glReadPixels(x, y, w, h, format, type, pixels); -#ifdef DEBUG_READ_PIXELS - LogReadPixelsError(glGetError()); -#endif - - if (!gl_extensions.IsGLES || gl_extensions.GLES3) { - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - } - CHECK_GL_ERROR_IF_DEBUG(); + GLuint aspect = 0; + if (channelBits & FB_COLOR_BIT) + aspect |= GL_COLOR_BUFFER_BIT; + if (channelBits & FB_DEPTH_BIT) + aspect |= GL_DEPTH_BUFFER_BIT; + if (channelBits & FB_STENCIL_BIT) + aspect |= GL_STENCIL_BUFFER_BIT; + renderManager_.CopyFramebufferToMemorySync(fb ? fb->framebuffer : nullptr, aspect, x, y, w, h, dataFormat, (uint8_t *)pixels, pixelStride); return true; } Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) { - return new OpenGLTexture(desc); -} - -OpenGLInputLayout::~OpenGLInputLayout() { - if (id_) { - glDeleteVertexArrays(1, &id_); - } -} - -void OpenGLInputLayout::Compile() { - int semMask = 0; - for (int i = 0; i < (int)desc.attributes.size(); i++) { - semMask |= 1 << desc.attributes[i].location; - } - semanticsMask_ = semMask; - - if (gl_extensions.ARB_vertex_array_object && gl_extensions.IsCoreContext) { - glGenVertexArrays(1, &id_); - } else { - id_ = 0; - } - needsEnable_ = true; - lastBase_ = -1; + return new OpenGLTexture(&renderManager_, desc); } DepthStencilState *OpenGLContext::CreateDepthStencilState(const DepthStencilStateDesc &desc) { @@ -972,10 +768,6 @@ BlendState *OpenGLContext::CreateBlendState(const BlendStateDesc &desc) { bs->eqAlpha = blendEqToGL[(int)desc.eqAlpha]; bs->srcAlpha = blendFactorToGL[(int)desc.srcAlpha]; bs->dstAlpha = blendFactorToGL[(int)desc.dstAlpha]; -#ifndef USING_GLES2 - bs->logicEnabled = desc.logicEnabled; - bs->logicOp = logicOpToGL[(int)desc.logicOp]; -#endif bs->colorMask = desc.colorMask; return bs; } @@ -1025,28 +817,22 @@ RasterState *OpenGLContext::CreateRasterState(const RasterStateDesc &desc) { class OpenGLBuffer : public Buffer { public: - OpenGLBuffer(size_t size, uint32_t flags) { - glGenBuffers(1, &buffer_); + OpenGLBuffer(GLRenderManager *render, size_t size, uint32_t flags) : render_(render) { target_ = (flags & BufferUsageFlag::INDEXDATA) ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; usage_ = 0; if (flags & BufferUsageFlag::DYNAMIC) usage_ = GL_STREAM_DRAW; else usage_ = GL_STATIC_DRAW; + buffer_ = render->CreateBuffer(target_, size, usage_); totalSize_ = size; - glBindBuffer(target_, buffer_); - glBufferData(target_, size, NULL, usage_); } ~OpenGLBuffer() override { - glDeleteBuffers(1, &buffer_); + render_->DeleteBuffer(buffer_); } - void Bind(int offset) { - // TODO: Can't support offset using ES 2.0 - glBindBuffer(target_, buffer_); - } - - GLuint buffer_; + GLRenderManager *render_; + GLRBuffer *buffer_; GLuint target_; GLuint usage_; @@ -1054,26 +840,29 @@ public: }; Buffer *OpenGLContext::CreateBuffer(size_t size, uint32_t usageFlags) { - return new OpenGLBuffer(size, usageFlags); + return new OpenGLBuffer(&renderManager_, size, usageFlags); } void OpenGLContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) { OpenGLBuffer *buf = (OpenGLBuffer *)buffer; - buf->Bind(0); if (size + offset > buf->totalSize_) { Crash(); } + + uint8_t *dataCopy = new uint8_t[size]; + memcpy(dataCopy, data, size); // if (flags & UPDATE_DISCARD) we could try to orphan the buffer using glBufferData. - glBufferSubData(buf->target_, offset, size, data); + // But we're much better off using separate buffers per FrameData... + renderManager_.BufferSubdata(buf->buffer_, offset, size, dataCopy); } Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { ELOG("Pipeline requires at least one shader"); - return NULL; + return nullptr; } - OpenGLPipeline *pipeline = new OpenGLPipeline(); + OpenGLPipeline *pipeline = new OpenGLPipeline(&renderManager_); for (auto iter : desc.shaders) { iter->AddRef(); pipeline->shaders.push_back(static_cast(iter)); @@ -1103,16 +892,14 @@ void OpenGLContext::BindTextures(int start, int count, Texture **textures) { maxTextures_ = std::max(maxTextures_, start + count); for (int i = start; i < start + count; i++) { OpenGLTexture *glTex = static_cast(textures[i]); - glActiveTexture(GL_TEXTURE0 + i); if (!glTex) { boundTextures_[i] = 0; - glBindTexture(GL_TEXTURE_2D, 0); + renderManager_.BindTexture(i, nullptr); continue; } - glTex->Bind(); + glTex->Bind(i); boundTextures_[i] = glTex; } - glActiveTexture(GL_TEXTURE0); } void OpenGLContext::ApplySamplers() { @@ -1122,31 +909,25 @@ void OpenGLContext::ApplySamplers() { const OpenGLTexture *tex = boundTextures_[i]; if (!tex) continue; + GLenum wrapS; + GLenum wrapT; if (tex->CanWrap()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, samp->wrapU); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, samp->wrapV); -#ifndef USING_GLES2 - if (tex->GetType() == TextureType::LINEAR3D) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, samp->wrapW); -#endif + wrapS = samp->wrapU; + wrapT = samp->wrapV; } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, samp->magFilt); - if (tex->HasMips()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, samp->mipMinFilt); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, samp->minFilt); + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; } + GLenum magFilt = samp->magFilt; + GLenum minFilt = tex->HasMips() ? samp->mipMinFilt : samp->minFilt; + renderManager_.SetTextureSampler(i, wrapS, wrapT, magFilt, minFilt, 0.0f); } } } ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) { - OpenGLShaderModule *shader = new OpenGLShaderModule(stage); - if (shader->Compile(language, data, dataSize)) { + OpenGLShaderModule *shader = new OpenGLShaderModule(&renderManager_, stage); + if (shader->Compile(&renderManager_, language, data, dataSize)) { return shader; } else { shader->Release(); @@ -1155,76 +936,30 @@ ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, ShaderLanguag } bool OpenGLPipeline::LinkShaders() { - program_ = glCreateProgram(); + std::vector linkShaders; for (auto iter : shaders) { - glAttachShader(program_, iter->GetShader()); + linkShaders.push_back(iter->GetShader()); } - + std::vector semantics; // Bind all the common vertex data points. Mismatching ones will be ignored. - glBindAttribLocation(program_, SEM_POSITION, "Position"); - glBindAttribLocation(program_, SEM_COLOR0, "Color0"); - glBindAttribLocation(program_, SEM_TEXCOORD0, "TexCoord0"); - glBindAttribLocation(program_, SEM_NORMAL, "Normal"); - glBindAttribLocation(program_, SEM_TANGENT, "Tangent"); - glBindAttribLocation(program_, SEM_BINORMAL, "Binormal"); - glLinkProgram(program_); - - GLint linkStatus = GL_FALSE; - glGetProgramiv(program_, GL_LINK_STATUS, &linkStatus); - if (linkStatus != GL_TRUE) { - GLint bufLength = 0; - glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &bufLength); - if (bufLength) { - char* buf = new char[bufLength]; - glGetProgramInfoLog(program_, bufLength, NULL, buf); - ELOG("Could not link program:\n %s", buf); - // We've thrown out the source at this point. Might want to do something about that. -#ifdef _WIN32 - OutputDebugStringUTF8(buf); -#endif - delete[] buf; - } else { - ELOG("Could not link program with %d shaders for unknown reason:", (int)shaders.size()); - } - return false; - } - - // Auto-initialize samplers. - glUseProgram(program_); - for (int i = 0; i < 4; i++) { - char temp[256]; - sprintf(temp, "Sampler%i", i); - int samplerLoc = GetUniformLoc(temp); - if (samplerLoc != -1) { - glUniform1i(samplerLoc, i); - } - } - - // Here we could (using glGetAttribLocation) save a bitmask about which pieces of vertex data are used in the shader - // and then AND it with the vertex format bitmask later... + semantics.push_back({ SEM_POSITION, "Position" }); + semantics.push_back({ SEM_COLOR0, "Color0" }); + semantics.push_back({ SEM_TEXCOORD0, "TexCoord0" }); + semantics.push_back({ SEM_NORMAL, "Normal" }); + semantics.push_back({ SEM_TANGENT, "Tangent" }); + semantics.push_back({ SEM_BINORMAL, "Binormal" }); + std::vector queries; + std::vector initialize; + program_ = render_->CreateProgram(linkShaders, semantics, queries, initialize, false); return true; } -int OpenGLPipeline::GetUniformLoc(const char *name) { - auto iter = uniformCache_.find(name); - int loc = -1; - if (iter != uniformCache_.end()) { - loc = iter->second.loc_; - } else { - loc = glGetUniformLocation(program_, name); - UniformInfo info; - info.loc_ = loc; - uniformCache_[name] = info; - } - return loc; -} - void OpenGLContext::BindPipeline(Pipeline *pipeline) { curPipeline_ = (OpenGLPipeline *)pipeline; - curPipeline_->blend->Apply(); - curPipeline_->depthStencil->Apply(); - curPipeline_->raster->Apply(); - glUseProgram(curPipeline_->program_); + curPipeline_->blend->Apply(&renderManager_); + curPipeline_->depthStencil->Apply(&renderManager_); + curPipeline_->raster->Apply(&renderManager_); + renderManager_.BindProgram(curPipeline_->program_); } void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { @@ -1233,55 +968,47 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { } for (auto &uniform : curPipeline_->dynamicUniforms.uniforms) { - GLuint loc = curPipeline_->GetUniformLoc(uniform.name); - if (loc == -1) - Crash(); const float *data = (const float *)((uint8_t *)ub + uniform.offset); switch (uniform.type) { case UniformType::FLOAT4: - glUniform1fv(loc, 4, data); + renderManager_.SetUniformF(uniform.name, 4, data); break; case UniformType::MATRIX4X4: - glUniformMatrix4fv(loc, 1, false, data); + renderManager_.SetUniformM4x4(uniform.name, data); break; } } } void OpenGLContext::Draw(int vertexCount, int offset) { - curVBuffers_[0]->Bind(curVBufferOffsets_[0]); - curPipeline_->inputLayout->Apply(); + _dbg_assert_msg_(G3D, curVBuffers_[0], "Can't call Draw without a vertex buffer"); ApplySamplers(); - - glDrawArrays(curPipeline_->prim, offset, vertexCount); - - curPipeline_->inputLayout->Unapply(); - glBindBuffer(GL_ARRAY_BUFFER, 0); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); + renderManager_.Draw(curPipeline_->prim, offset, vertexCount); } void OpenGLContext::DrawIndexed(int vertexCount, int offset) { - curVBuffers_[0]->Bind(curVBufferOffsets_[0]); - curPipeline_->inputLayout->Apply(); + _dbg_assert_msg_(G3D, curVBuffers_[0], "Can't call DrawIndexed without a vertex buffer"); + _dbg_assert_msg_(G3D, curIBuffer_, "Can't call DrawIndexed without an index buffer"); ApplySamplers(); - // Note: ibuf binding is stored in the VAO, so call this after binding the fmt. - curIBuffer_->Bind(curIBufferOffset_); - - glDrawElements(curPipeline_->prim, vertexCount, GL_UNSIGNED_INT, (const void *)(size_t)offset); - - curPipeline_->inputLayout->Unapply(); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); + renderManager_.BindIndexBuffer(curIBuffer_->buffer_); + renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_INT, (void *)(intptr_t)curIBufferOffset_); } void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { - curPipeline_->inputLayout->Apply(vdata); + int stride = curPipeline_->inputLayout->stride; + size_t dataSize = stride * vertexCount; + + FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; + + GLRBuffer *buf; + size_t offset = frameData.push->Push(vdata, dataSize, &buf); + ApplySamplers(); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDrawArrays(curPipeline_->prim, 0, vertexCount); - - curPipeline_->inputLayout->Unapply(); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset); + renderManager_.Draw(curPipeline_->prim, 0, vertexCount); } void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) { @@ -1289,544 +1016,136 @@ void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stenc Uint8x4ToFloat4(col, colorval); GLuint glMask = 0; if (mask & FBChannel::FB_COLOR_BIT) { - glClearColor(col[0], col[1], col[2], col[3]); glMask |= GL_COLOR_BUFFER_BIT; } if (mask & FBChannel::FB_DEPTH_BIT) { -#if defined(USING_GLES2) - glClearDepthf(depthVal); -#else - glClearDepth(depthVal); -#endif glMask |= GL_DEPTH_BUFFER_BIT; } if (mask & FBChannel::FB_STENCIL_BIT) { - glClearStencil(stencilVal); glMask |= GL_STENCIL_BUFFER_BIT; } - glClear(glMask); + renderManager_.Clear(colorval, depthVal, stencilVal, glMask, 0xF, 0, 0, targetWidth_, targetHeight_); } DrawContext *T3DCreateGLContext() { return new OpenGLContext(); } -void OpenGLInputLayout::Apply(const void *base) { - if (id_ != 0) { - glBindVertexArray(id_); - } - - if (needsEnable_ || id_ == 0) { - for (int i = 0; i < SEM_MAX; i++) { - if (semanticsMask_ & (1 << i)) { - glEnableVertexAttribArray(i); - } - } - if (id_ != 0) { - needsEnable_ = false; - } - } - - intptr_t b = (intptr_t)base; - if (b != lastBase_) { - for (size_t i = 0; i < desc.attributes.size(); i++) { - GLsizei stride = (GLsizei)desc.bindings[desc.attributes[i].binding].stride; - switch (desc.attributes[i].format) { - case DataFormat::R32G32_FLOAT: - glVertexAttribPointer(desc.attributes[i].location, 2, GL_FLOAT, GL_FALSE, stride, (void *)(b + (intptr_t)desc.attributes[i].offset)); - break; - case DataFormat::R32G32B32_FLOAT: - glVertexAttribPointer(desc.attributes[i].location, 3, GL_FLOAT, GL_FALSE, stride, (void *)(b + (intptr_t)desc.attributes[i].offset)); - break; - case DataFormat::R32G32B32A32_FLOAT: - glVertexAttribPointer(desc.attributes[i].location, 4, GL_FLOAT, GL_FALSE, stride, (void *)(b + (intptr_t)desc.attributes[i].offset)); - break; - case DataFormat::R8G8B8A8_UNORM: - glVertexAttribPointer(desc.attributes[i].location, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void *)(b + (intptr_t)desc.attributes[i].offset)); - break; - case DataFormat::UNDEFINED: - default: - ELOG("Thin3DGLVertexFormat: Invalid or unknown component type applied."); - break; - } - } - if (id_ != 0) { - lastBase_ = b; - } - } +OpenGLInputLayout::~OpenGLInputLayout() { + render_->DeleteInputLayout(inputLayout_); } -void OpenGLInputLayout::Unapply() { - if (id_ == 0) { - for (int i = 0; i < (int)SEM_MAX; i++) { - if (semanticsMask_ & (1 << i)) { - glDisableVertexAttribArray(i); - } +void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) { + int semMask = 0; + + // TODO: This is only accurate if there's only one stream. But whatever, for now we + // never use multiple streams anyway. + stride = (GLsizei)desc.bindings[0].stride; + + std::vector entries; + for (auto &attr : desc.attributes) { + GLRInputLayout::Entry entry; + entry.location = attr.location; + entry.stride = (GLsizei)desc.bindings[attr.binding].stride; + entry.offset = attr.offset; + switch (attr.format) { + case DataFormat::R32G32_FLOAT: + entry.count = 2; + entry.type = GL_FLOAT; + entry.normalized = GL_FALSE; + break; + case DataFormat::R32G32B32_FLOAT: + entry.count = 3; + entry.type = GL_FLOAT; + entry.normalized = GL_FALSE; + break; + case DataFormat::R32G32B32A32_FLOAT: + entry.count = 4; + entry.type = GL_FLOAT; + entry.normalized = GL_FALSE; + break; + case DataFormat::R8G8B8A8_UNORM: + entry.count = 4; + entry.type = GL_UNSIGNED_BYTE; + entry.normalized = GL_TRUE; + break; + case DataFormat::UNDEFINED: + default: + ELOG("Thin3DGLVertexFormat: Invalid or unknown component type applied."); + break; } - } else { - glBindVertexArray(0); + + entries.push_back(entry); } + inputLayout_ = render_->CreateInputLayout(entries); } -// On PC, we always use GL_DEPTH24_STENCIL8. -// On Android, we try to use what's available. - -#ifndef USING_GLES2 -OpenGLFramebuffer *OpenGLContext::fbo_ext_create(const FramebufferDesc &desc) { - OpenGLFramebuffer *fbo = new OpenGLFramebuffer(); - fbo->width = desc.width; - fbo->height = desc.height; - fbo->colorDepth = desc.colorDepth; - - // Color texture is same everywhere - glGenFramebuffersEXT(1, &fbo->handle); - glGenTextures(1, &fbo->color_texture); - - // Create the surfaces. - glBindTexture(GL_TEXTURE_2D, fbo->color_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // TODO: We could opt to only create 16-bit render targets on slow devices. For later. - switch (fbo->colorDepth) { - case FBO_8888: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - break; - case FBO_4444: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL); - break; - case FBO_5551: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL); - break; - case FBO_565: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); - break; - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - fbo->stencil_buffer = 0; - fbo->z_buffer = 0; - // 24-bit Z, 8-bit stencil - glGenRenderbuffersEXT(1, &fbo->z_stencil_buffer); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, fbo->width, fbo->height); - //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height); - - // Bind it all together - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->color_texture, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); - - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: - // ILOG("Framebuffer verified complete."); - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); - break; - default: - FLOG("Other framebuffer error: %i", status); - break; - } - // Unbind state we don't need - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - glBindTexture(GL_TEXTURE_2D, 0); - - currentDrawHandle_ = fbo->handle; - currentReadHandle_ = fbo->handle; - return fbo; -} -#endif - Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) { CheckGLExtensions(); -#ifndef USING_GLES2 - if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) { - return fbo_ext_create(desc); - } else if (!gl_extensions.ARB_framebuffer_object) { - return nullptr; - } - // If GLES2, we have basic FBO support and can just proceed. -#endif - CHECK_GL_ERROR_IF_DEBUG(); - - OpenGLFramebuffer *fbo = new OpenGLFramebuffer(); - fbo->width = desc.width; - fbo->height = desc.height; - fbo->colorDepth = desc.colorDepth; - - // Color texture is same everywhere - glGenFramebuffers(1, &fbo->handle); - glGenTextures(1, &fbo->color_texture); - - // Create the surfaces. - glBindTexture(GL_TEXTURE_2D, fbo->color_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // TODO: We could opt to only create 16-bit render targets on slow devices. For later. - switch (fbo->colorDepth) { - case FBO_8888: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - break; - case FBO_4444: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL); - break; - case FBO_5551: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL); - break; - case FBO_565: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); - break; - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (gl_extensions.IsGLES) { - if (gl_extensions.OES_packed_depth_stencil) { - ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", fbo->width, fbo->height); - // Standard method - fbo->stencil_buffer = 0; - fbo->z_buffer = 0; - // 24-bit Z, 8-bit stencil combined - glGenRenderbuffers(1, &fbo->z_stencil_buffer); - glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, fbo->width, fbo->height); - - // Bind it all together - glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); - } else { - ILOG("Creating %i x %i FBO using separate stencil", fbo->width, fbo->height); - // TEGRA - fbo->z_stencil_buffer = 0; - // 16/24-bit Z, separate 8-bit stencil - glGenRenderbuffers(1, &fbo->z_buffer); - glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_buffer); - // Don't forget to make sure fbo_standard_z_depth() matches. - glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, fbo->width, fbo->height); - - // 8-bit stencil buffer - glGenRenderbuffers(1, &fbo->stencil_buffer); - glBindRenderbuffer(GL_RENDERBUFFER, fbo->stencil_buffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fbo->width, fbo->height); - - // Bind it all together - glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); - } - } else { - fbo->stencil_buffer = 0; - fbo->z_buffer = 0; - // 24-bit Z, 8-bit stencil - glGenRenderbuffers(1, &fbo->z_stencil_buffer); - glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fbo->width, fbo->height); - - // Bind it all together - glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE: - // ILOG("Framebuffer verified complete."); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); - break; - default: - FLOG("Other framebuffer error: %i", status); - break; - } - - // Unbind state we don't need - glBindRenderbuffer(GL_RENDERBUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - CHECK_GL_ERROR_IF_DEBUG(); - - currentDrawHandle_ = fbo->handle; - currentReadHandle_ = fbo->handle; + OpenGLFramebuffer *fbo = new OpenGLFramebuffer(&renderManager_); + fbo->framebuffer = renderManager_.CreateFramebuffer(desc.width, desc.height, desc.z_stencil); return fbo; } -GLenum OpenGLContext::fbo_get_fb_target(bool read, GLuint **cached) { - bool supportsBlit = gl_extensions.ARB_framebuffer_object; - if (gl_extensions.IsGLES) { - supportsBlit = (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit); - } - - // Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV. - if (supportsBlit) { - if (read) { - *cached = ¤tReadHandle_; - return GL_READ_FRAMEBUFFER; - } else { - *cached = ¤tDrawHandle_; - return GL_DRAW_FRAMEBUFFER; - } - } else { - *cached = ¤tDrawHandle_; - return GL_FRAMEBUFFER; - } -} - -void OpenGLContext::fbo_bind_fb_target(bool read, GLuint name) { - GLuint *cached; - GLenum target = fbo_get_fb_target(read, &cached); - if (*cached != name) { - if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { - glBindFramebuffer(target, name); - } else { -#ifndef USING_GLES2 - glBindFramebufferEXT(target, name); -#endif - } - *cached = name; - } -} - -void OpenGLContext::fbo_unbind() { -#ifndef USING_GLES2 - if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { - glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); - } else if (gl_extensions.EXT_framebuffer_object) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_defaultFBO); - } -#else - glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); -#endif - -#ifdef IOS - bindDefaultFBO(); -#endif - - currentDrawHandle_ = 0; - currentReadHandle_ = 0; -} - void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) { - CHECK_GL_ERROR_IF_DEBUG(); - curFB_ = (OpenGLFramebuffer *)fbo; - if (fbo) { - OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; - // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing - // in ES 2.0 that actually separate them anyway of course, so doesn't matter. - fbo_bind_fb_target(false, fb->handle); - // Always restore viewport after render target binding. Works around driver bugs. - glstate.viewport.restore(); - } else { - fbo_unbind(); - } - int clearFlags = 0; - if (rp.color == RPAction::CLEAR) { - float fc[4]{}; - if (rp.clearColor) { - Uint8x4ToFloat4(fc, rp.clearColor); - } - glClearColor(fc[0], fc[1], fc[2], fc[3]); - clearFlags |= GL_COLOR_BUFFER_BIT; - glstate.colorMask.force(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - if (rp.depth == RPAction::CLEAR) { -#ifdef USING_GLES2 - glClearDepthf(rp.clearDepth); -#else - glClearDepth(rp.clearDepth); -#endif - clearFlags |= GL_DEPTH_BUFFER_BIT; - glstate.depthWrite.force(GL_TRUE); - } - if (rp.stencil == RPAction::CLEAR) { - glClearStencil(rp.clearStencil); - clearFlags |= GL_STENCIL_BUFFER_BIT; - glstate.stencilFunc.force(GL_ALWAYS, 0, 0); - glstate.stencilMask.force(0xFF); - } - if (clearFlags) { - glstate.scissorTest.force(false); - glClear(clearFlags); - glstate.scissorTest.restore(); - } - if (rp.color == RPAction::CLEAR) { - glstate.colorMask.restore(); - } - if (rp.depth == RPAction::CLEAR) { - glstate.depthWrite.restore(); - } - if (rp.stencil == RPAction::CLEAR) { - glstate.stencilFunc.restore(); - glstate.stencilMask.restore(); - } - CHECK_GL_ERROR_IF_DEBUG(); + OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; + GLRRenderPassAction color = (GLRRenderPassAction)rp.color; + GLRRenderPassAction depth = (GLRRenderPassAction)rp.depth; + GLRRenderPassAction stencil = (GLRRenderPassAction)rp.stencil; + + renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil); } void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) { OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc; OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst; - GLuint srcTex = 0; - GLuint dstTex = 0; - GLuint target = GL_TEXTURE_2D; - switch (channelBits) { - case FB_COLOR_BIT: - srcTex = src->color_texture; - dstTex = dst->color_texture; - break; - case FB_DEPTH_BIT: - target = GL_RENDERBUFFER; - srcTex = src->z_buffer ? src->z_buffer : src->z_stencil_buffer; - dstTex = dst->z_buffer ? dst->z_buffer : dst->z_stencil_buffer; - break; + + int aspect = 0; + if (channelBits & FB_COLOR_BIT) { + aspect |= GL_COLOR_BUFFER_BIT; + } else if (channelBits & (FB_STENCIL_BIT | FB_DEPTH_BIT)) { + if (channelBits & FB_DEPTH_BIT) + aspect |= GL_DEPTH_BUFFER_BIT; + if (channelBits & FB_STENCIL_BIT) + aspect |= GL_STENCIL_BUFFER_BIT; } -#if defined(USING_GLES2) -#ifndef IOS - glCopyImageSubDataOES( - srcTex, target, srcLevel, srcX, srcY, srcZ, - dstTex, target, dstLevel, dstX, dstY, dstZ, - width, height, depth); -#endif -#else - if (gl_extensions.ARB_copy_image) { - glCopyImageSubData( - srcTex, target, srcLevel, srcX, srcY, srcZ, - dstTex, target, dstLevel, dstX, dstY, dstZ, - width, height, depth); - } else if (gl_extensions.NV_copy_image) { - // Older, pre GL 4.x NVIDIA cards. - glCopyImageSubDataNV( - srcTex, target, srcLevel, srcX, srcY, srcZ, - dstTex, target, dstLevel, dstX, dstY, dstZ, - width, height, depth); - } -#endif - CHECK_GL_ERROR_IF_DEBUG(); + renderManager_.CopyFramebuffer(src->framebuffer, GLRect2D{ srcX, srcY, width, height }, dst->framebuffer, GLOffset2D{ dstX, dstY }, aspect); } bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter) { OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc; OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst; - GLuint bits = 0; + GLuint aspect = 0; if (channels & FB_COLOR_BIT) - bits |= GL_COLOR_BUFFER_BIT; + aspect |= GL_COLOR_BUFFER_BIT; if (channels & FB_DEPTH_BIT) - bits |= GL_DEPTH_BUFFER_BIT; + aspect |= GL_DEPTH_BUFFER_BIT; if (channels & FB_STENCIL_BIT) - bits |= GL_STENCIL_BUFFER_BIT; - // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing - // in ES 2.0 that actually separate them anyway of course, so doesn't matter. - fbo_bind_fb_target(false, dst->handle); - fbo_bind_fb_target(true, src->handle); - if (gl_extensions.GLES3 || gl_extensions.ARB_framebuffer_object) { - glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST); - CHECK_GL_ERROR_IF_DEBUG(); -#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC. - return true; - } else if (gl_extensions.NV_framebuffer_blit) { - glBlitFramebufferNV(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST); - CHECK_GL_ERROR_IF_DEBUG(); -#endif // defined(USING_GLES2) && defined(__ANDROID__) - return true; - } else { - return false; - } -} + aspect |= GL_STENCIL_BUFFER_BIT; -uintptr_t OpenGLContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) { - OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; - switch (channelBits) { - case FB_COLOR_BIT: return (uintptr_t)fb->color_texture; - case FB_DEPTH_BIT: return (uintptr_t)(fb->z_buffer ? fb->z_buffer : fb->z_stencil_buffer); - default: - return 0; - } + renderManager_.BlitFramebuffer(src->framebuffer, GLRect2D{ srcX1, srcY1, srcX2 - srcX1, srcY2 - srcY1 }, dst->framebuffer, GLRect2D{ dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1 }, aspect, linearFilter == FB_BLIT_LINEAR); + return true; } void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; - if (!fb) - return; - if (binding != 0) - glActiveTexture(GL_TEXTURE0 + binding); - switch (channelBit) { - case FB_DEPTH_BIT: - glBindTexture(GL_TEXTURE_2D, fb->z_buffer ? fb->z_buffer : fb->z_stencil_buffer); - case FB_COLOR_BIT: - default: - glBindTexture(GL_TEXTURE_2D, fb->color_texture); - break; - } - glActiveTexture(GL_TEXTURE0); -} -OpenGLFramebuffer::~OpenGLFramebuffer() { - CHECK_GL_ERROR_IF_DEBUG(); - if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { - if (handle) { - glBindFramebuffer(GL_FRAMEBUFFER, handle); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); - glDeleteFramebuffers(1, &handle); - } - if (z_stencil_buffer) - glDeleteRenderbuffers(1, &z_stencil_buffer); - if (z_buffer) - glDeleteRenderbuffers(1, &z_buffer); - if (stencil_buffer) - glDeleteRenderbuffers(1, &stencil_buffer); - } else if (gl_extensions.EXT_framebuffer_object) { -#ifndef USING_GLES2 - if (handle) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, handle); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_defaultFBO); - glDeleteFramebuffersEXT(1, &handle); - } - if (z_stencil_buffer) - glDeleteRenderbuffers(1, &z_stencil_buffer); - if (z_buffer) - glDeleteRenderbuffers(1, &z_buffer); - if (stencil_buffer) - glDeleteRenderbuffers(1, &stencil_buffer); -#endif - } - - glDeleteTextures(1, &color_texture); + GLuint aspect = 0; + if (channelBit & FB_COLOR_BIT) + aspect |= GL_COLOR_BUFFER_BIT; + if (channelBit & FB_DEPTH_BIT) + aspect |= GL_DEPTH_BUFFER_BIT; + if (channelBit & FB_STENCIL_BIT) + aspect |= GL_STENCIL_BUFFER_BIT; + renderManager_.BindFramebufferAsTexture(fb->framebuffer, binding, aspect, color); } void OpenGLContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; if (fb) { - *w = fb->width; - *h = fb->height; + *w = fb->framebuffer->width; + *h = fb->framebuffer->height; } else { *w = targetWidth_; *h = targetHeight_; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index ce89f21498..0eef38ad14 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -301,10 +301,10 @@ struct DescriptorSetKey { class VKTexture : public Texture { public: - VKTexture(VulkanContext *vulkan, VkCommandBuffer cmd, const TextureDesc &desc, VulkanDeviceAllocator *alloc) + VKTexture(VulkanContext *vulkan, VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc) : vulkan_(vulkan), mipLevels_(desc.mipLevels), format_(desc.format) { - bool result = Create(cmd, desc, alloc); - assert(result); + bool result = Create(cmd, pushBuffer, desc, alloc); + _assert_(result); } ~VKTexture() { @@ -314,9 +314,7 @@ public: VkImageView GetImageView() { return vkTex_->GetImageView(); } private: - void SetImageData(VkCommandBuffer cmd, int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data); - - bool Create(VkCommandBuffer cmd, const TextureDesc &desc, VulkanDeviceAllocator *alloc); + bool Create(VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc); void Destroy() { if (vkTex_) { @@ -650,20 +648,48 @@ enum class TextureState { PENDING_DESTRUCTION, }; -bool VKTexture::Create(VkCommandBuffer cmd, const TextureDesc &desc, VulkanDeviceAllocator *alloc) { +bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const TextureDesc &desc, VulkanDeviceAllocator *alloc) { // Zero-sized textures not allowed. - assert(desc.width * desc.height * desc.depth > 0); + _assert_(desc.width * desc.height * desc.depth > 0); // remember to set depth to 1! + _assert_(push); format_ = desc.format; mipLevels_ = desc.mipLevels; width_ = desc.width; height_ = desc.height; depth_ = desc.depth; vkTex_ = new VulkanTexture(vulkan_, alloc); + VkFormat vulkanFormat = DataFormatToVulkan(format_); + int stride = desc.width * (int)DataFormatSizeInBytes(format_); + int bpp = GetBpp(vulkanFormat); + int bytesPerPixel = bpp / 8; + int usageBits = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + if (mipLevels_ > (int)desc.initData.size()) { + // Gonna have to generate some, which requires TRANSFER_SRC + usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + if (!vkTex_->CreateDirect(cmd, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) { + ELOG("Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_); + return false; + } if (desc.initData.size()) { - for (int i = 0; i < (int)desc.initData.size(); i++) { - this->SetImageData(cmd, 0, 0, 0, width_, height_, depth_, i, 0, desc.initData[i]); + int w = width_; + int h = height_; + int i; + for (i = 0; i < (int)desc.initData.size(); i++) { + uint32_t offset; + VkBuffer buf; + size_t size = w * h * bytesPerPixel; + offset = push->PushAligned((const void *)desc.initData[i], size, 16, &buf); + vkTex_->UploadMip(cmd, i, w, h, buf, offset, w); + w = (w + 1) / 2; + h = (h + 1) / 2; + } + // Generate the rest of the mips automatically. + for (; i < mipLevels_; i++) { + vkTex_->GenerateMip(cmd, i); } } + vkTex_->EndCreate(cmd, false); return true; } @@ -703,13 +729,13 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) dpTypes[1].descriptorCount = 200; dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - VkDescriptorPoolCreateInfo dp = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; dp.flags = 0; // Don't want to mess around with individually freeing these, let's go dynamic each frame. dp.maxSets = 200; // 200 textures per frame should be enough for the UI... dp.pPoolSizes = dpTypes; dp.poolSizeCount = ARRAY_SIZE(dpTypes); - VkCommandPoolCreateInfo p = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + VkCommandPoolCreateInfo p{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; p.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; p.queueFamilyIndex = vulkan->GetGraphicsQueueFamilyIndex(); @@ -747,7 +773,9 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) res = vkCreatePipelineLayout(device_, &pl, nullptr, &pipelineLayout_); assert(VK_SUCCESS == res); - pipelineCache_ = vulkan_->CreatePipelineCache(); + VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); + assert(VK_SUCCESS == res); renderManager_.SetSplitSubmit(splitSubmit); @@ -833,7 +861,11 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { VkDescriptorImageInfo imageDesc; imageDesc.imageView = boundTextures_[0]->GetImageView(); imageDesc.sampler = boundSamplers_[0]->GetSampler(); +#ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR + imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; +#else imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +#endif VkWriteDescriptorSet writes[2] = {}; writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -994,23 +1026,13 @@ InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) { } Texture *VKContext::CreateTexture(const TextureDesc &desc) { - return new VKTexture(vulkan_, renderManager_.GetInitCmd(), desc, allocator_); -} - -void VKTexture::SetImageData(VkCommandBuffer cmd, int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) { - VkFormat vulkanFormat = DataFormatToVulkan(format_); - if (stride == 0) { - stride = width * (int)DataFormatSizeInBytes(format_); + if (!push_) { + // Too early! Fail. + ELOG("Can't create textures before the first frame has started."); + return nullptr; } - int bpp = GetBpp(vulkanFormat); - int bytesPerPixel = bpp / 8; - vkTex_->Create(width, height, vulkanFormat); - int rowPitch; - uint8_t *dstData = vkTex_->Lock(0, &rowPitch); - for (int y = 0; y < height; y++) { - memcpy(dstData + rowPitch * y, data + stride * y, width * bytesPerPixel); - } - vkTex_->Unlock(cmd); + _assert_(renderManager_.GetInitCmd()); + return new VKTexture(vulkan_, renderManager_.GetInitCmd(), push_, desc, allocator_); } static inline void CopySide(VkStencilOpState &dest, const StencilSide &src) { @@ -1338,8 +1360,9 @@ void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPass VKFramebuffer *fb = (VKFramebuffer *)fbo; VKRRenderPassAction color = (VKRRenderPassAction)rp.color; VKRRenderPassAction depth = (VKRRenderPassAction)rp.depth; + VKRRenderPassAction stencil = (VKRRenderPassAction)rp.stencil; - renderManager_.BindFramebufferAsRenderTarget(fb ? fb->GetFB() : nullptr, color, depth, rp.clearColor, rp.clearDepth, rp.clearStencil); + renderManager_.BindFramebufferAsRenderTarget(fb ? fb->GetFB() : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil); curFramebuffer_ = fb; } diff --git a/ext/native/thread/prioritizedworkqueue.cpp b/ext/native/thread/prioritizedworkqueue.cpp index 1583738f40..35a1e94a62 100644 --- a/ext/native/thread/prioritizedworkqueue.cpp +++ b/ext/native/thread/prioritizedworkqueue.cpp @@ -112,7 +112,7 @@ PrioritizedWorkQueueItem *PrioritizedWorkQueue::Pop() { static std::thread *workThread; static void threadfunc(PrioritizedWorkQueue *wq) { - setCurrentThreadName("PrioritizedWorkQueue"); + setCurrentThreadName("PrioQueue"); while (true) { PrioritizedWorkQueueItem *item = wq->Pop(); if (!item) { @@ -126,7 +126,7 @@ static void threadfunc(PrioritizedWorkQueue *wq) { } void ProcessWorkQueueOnThreadWhile(PrioritizedWorkQueue *wq) { - workThread = new std::thread(std::bind(&threadfunc, wq)); + workThread = new std::thread([=](){threadfunc(wq);}); } void StopProcessingWorkQueue(PrioritizedWorkQueue *wq) { @@ -135,5 +135,5 @@ void StopProcessingWorkQueue(PrioritizedWorkQueue *wq) { workThread->join(); delete workThread; } - workThread = 0; + workThread = nullptr; } diff --git a/ext/native/thread/threadutil.cpp b/ext/native/thread/threadutil.cpp index fcd050e98f..403f8cadd9 100644 --- a/ext/native/thread/threadutil.cpp +++ b/ext/native/thread/threadutil.cpp @@ -12,7 +12,7 @@ #include "base/logging.h" #include "thread/threadutil.h" -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__APPLE__) || (defined(__GLIBC__) && defined(_GNU_SOURCE)) #include #endif @@ -96,10 +96,12 @@ void setCurrentThreadName(const char* threadName) { {} #else -#if defined(__ANDROID__) +#if defined(__ANDROID__) || (defined(__GLIBC__) && defined(_GNU_SOURCE)) pthread_setname_np(pthread_self(), threadName); +#elif defined(__APPLE__) + pthread_setname_np(threadName); // #else -// pthread_setname_np(thread_name); +// pthread_setname_np(threadName); #endif // Do nothing diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 671765a552..a148a0b60d 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -6,6 +6,8 @@ #include "gfx_es2/draw_buffer.h" #include "gfx_es2/draw_text.h" +#include "Common/Log.h" + UIContext::UIContext() { fontStyle_ = new UI::FontStyle(); bounds_ = Bounds(0, 0, dp_xres, dp_yres); @@ -28,13 +30,19 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi textDrawer_ = TextDrawer::Create(thin3d); // May return nullptr if no implementation is available for this platform. } -void UIContext::FrameSetup(Draw::Texture *uiTexture) { - uitexture_ = uiTexture; +void UIContext::BeginFrame() { + if (!uitexture_) { + uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM, false); + if (!uitexture_) { + PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); + FLOG("Failed to load ui_atlas.zim"); + } + } } void UIContext::Begin() { draw_->BindSamplerStates(0, 1, &sampler_); - draw_->BindTexture(0, uitexture_); + draw_->BindTexture(0, uitexture_->GetTexture()); ActivateTopScissor(); UIBegin(ui_pipeline_); } @@ -45,7 +53,7 @@ void UIContext::BeginNoTex() { } void UIContext::RebindTexture() const { - draw_->BindTexture(0, uitexture_); + draw_->BindTexture(0, uitexture_->GetTexture()); } void UIContext::Flush() { diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index 59468abde7..3b6c4d7e43 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -6,6 +6,7 @@ #include "math/geom2d.h" #include "math/lin/vec3.h" #include "gfx/texture_atlas.h" +#include "UI/TextureUtil.h" // Everything you need to draw a UI collected into a single unit that can be passed around. // Everything forward declared so this header is safe everywhere. @@ -46,7 +47,7 @@ public: void Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pipeline *uipipenotex, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop); - void FrameSetup(Draw::Texture *uiTexture); + void BeginFrame(); void Begin(); void BeginNoTex(); @@ -102,7 +103,7 @@ private: Draw::SamplerState *sampler_; Draw::Pipeline *ui_pipeline_ = nullptr; Draw::Pipeline *ui_pipeline_notex_ = nullptr; - Draw::Texture *uitexture_ = nullptr; + std::unique_ptr uitexture_; DrawBuffer *uidrawbuffer_ = nullptr; DrawBuffer *uidrawbufferTop_ = nullptr; diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 26e12b8b4f..092eacec1c 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -68,6 +68,7 @@ void UIScreen::preRender() { return; } draw->BeginFrame(); + screenManager()->getUIContext()->BeginFrame(); // Bind and clear the back buffer draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }); diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 0585b62d27..58427c8715 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -816,6 +816,10 @@ void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz } void TextView::Draw(UIContext &dc) { + uint32_t textColor = hasTextColor_ ? textColor_ : dc.theme->infoStyle.fgColor; + if (!(textColor & 0xFF000000)) + return; + bool clip = false; if (measuredWidth_ > bounds_.w || measuredHeight_ > bounds_.h) clip = true; @@ -839,7 +843,6 @@ void TextView::Draw(UIContext &dc) { uint32_t shadowColor = 0x80000000; dc.DrawTextRect(text_.c_str(), bounds_.Offset(1.0f, 1.0f), shadowColor, textAlign_); } - uint32_t textColor = hasTextColor_ ? textColor_ : dc.theme->infoStyle.fgColor; dc.DrawTextRect(text_.c_str(), bounds_, textColor, textAlign_); if (clip) { dc.PopScissor(); @@ -1071,6 +1074,26 @@ void ProgressBar::Draw(UIContext &dc) { dc.DrawTextRect(temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER); } +void Spinner::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + w = 48; + h = 48; +} + +void Spinner::Draw(UIContext &dc) { + if (!(color_ & 0xFF000000)) + return; + double t = time_now_d() * 1.3f; + double angle = fmod(t, M_PI * 2.0); + float r = bounds_.w * 0.5f; + double da = M_PI * 2.0 / numImages_; + for (int i = 0; i < numImages_; i++) { + double a = angle + i * da; + float x = (float)cos(a) * r; + float y = (float)sin(a) * r; + dc.Draw()->DrawImage(images_[i], bounds_.centerX() + x, bounds_.centerY() + y, 1.0f, color_, ALIGN_CENTER); + } +} + void TriggerButton::Touch(const TouchInput &input) { if (input.flags & TOUCH_DOWN) { if (bounds_.Contains(input.x, input.y)) { diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index af7fc2a1ce..06da7b98c6 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -882,6 +882,22 @@ private: float progress_; }; +class Spinner : public InertView { +public: + Spinner(const int *images, int numImages, LayoutParams *layoutParams = 0) + : InertView(layoutParams), images_(images), numImages_(numImages) { + } + + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + void Draw(UIContext &dc) override; + void SetColor(uint32_t color) { color_ = color; } + +private: + const int *images_; + int numImages_; + uint32_t color_ = 0xFFFFFFFF; +}; + void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measured); void EventTriggered(Event *e, EventParams params); diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index b6e9c08dcc..ab748a9772 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -461,7 +461,6 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v allowedWidth = horiz.size; } - float unit = (allowedWidth - weightZeroSum) / weightSum; float usedWidth = 0.0f; // Redistribute the stretchy ones! and remeasure the children! @@ -477,6 +476,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v MeasureSpec v = vert; if (v.type == UNSPECIFIED && measuredHeight_ != 0.0f) v = MeasureSpec(AT_MOST, measuredHeight_); + float unit = (allowedWidth - weightZeroSum) / weightSum; MeasureSpec h(AT_MOST, unit * linLayoutParams->weight - margins.horiz()); if (horiz.type == EXACTLY) { h.type = EXACTLY; @@ -502,7 +502,6 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v allowedHeight = vert.size; } - float unit = (allowedHeight - weightZeroSum) / weightSum; float usedHeight = 0.0f; // Redistribute the stretchy ones! and remeasure the children! @@ -518,6 +517,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v MeasureSpec h = horiz; if (h.type == UNSPECIFIED && measuredWidth_ != 0.0f) h = MeasureSpec(AT_MOST, measuredWidth_); + float unit = (allowedHeight - weightZeroSum) / weightSum; MeasureSpec v(AT_MOST, unit * linLayoutParams->weight - margins.vert()); if (vert.type == EXACTLY) { v.type = EXACTLY; diff --git a/ext/vulkan/icd-spv.h b/ext/vulkan/icd-spv.h deleted file mode 100644 index cc65284a19..0000000000 --- a/ext/vulkan/icd-spv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015-2016 Valve Corporation - * Copyright (c) 2015-2016 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Cody Northrop - */ - -#ifndef ICD_SPV_H -#define ICD_SPV_H - -#include - -#define ICD_SPV_MAGIC 0x07230203 -#define ICD_SPV_VERSION 99 - -struct icd_spv_header { - uint32_t magic; - uint32_t version; - uint32_t gen_magic; // Generator's magic number -}; - -#endif /* ICD_SPV_H */ diff --git a/ext/vulkan/spirv.h b/ext/vulkan/spirv.h index 89354c0696..2be35146df 100644 --- a/ext/vulkan/spirv.h +++ b/ext/vulkan/spirv.h @@ -51,11 +51,11 @@ typedef unsigned int SpvId; #define SPV_VERSION 0x10100 -#define SPV_REVISION 6 +#define SPV_REVISION 8 static const unsigned int SpvMagicNumber = 0x07230203; static const unsigned int SpvVersion = 0x00010100; -static const unsigned int SpvRevision = 6; +static const unsigned int SpvRevision = 8; static const unsigned int SpvOpCodeMask = 0xffff; static const unsigned int SpvWordCountShift = 16; @@ -65,6 +65,7 @@ typedef enum SpvSourceLanguage_ { SpvSourceLanguageGLSL = 2, SpvSourceLanguageOpenCL_C = 3, SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, SpvSourceLanguageMax = 0x7fffffff, } SpvSourceLanguage; @@ -129,6 +130,8 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeFinalizer = 34, SpvExecutionModeSubgroupSize = 35, SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -145,6 +148,7 @@ typedef enum SpvStorageClass_ { SpvStorageClassPushConstant = 9, SpvStorageClassAtomicCounter = 10, SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, SpvStorageClassMax = 0x7fffffff, } SpvStorageClass; @@ -383,6 +387,7 @@ typedef enum SpvDecoration_ { SpvDecorationInputAttachmentIndex = 43, SpvDecorationAlignment = 44, SpvDecorationMaxByteOffset = 45, + SpvDecorationExplicitInterpAMD = 4999, SpvDecorationOverrideCoverageNV = 5248, SpvDecorationPassthroughNV = 5250, SpvDecorationViewportRelativeNV = 5252, @@ -442,6 +447,14 @@ typedef enum SpvBuiltIn_ { SpvBuiltInDrawIndex = 4426, SpvBuiltInDeviceIndex = 4438, SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, SpvBuiltInViewportMaskNV = 5253, SpvBuiltInSecondaryPositionNV = 5257, SpvBuiltInSecondaryViewportMaskNV = 5258, @@ -632,18 +645,32 @@ typedef enum SpvCapability_ { SpvCapabilitySubgroupBallotKHR = 4423, SpvCapabilityDrawParameters = 4427, SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, SpvCapabilityStorageUniformBufferBlock16 = 4433, SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, SpvCapabilityStoragePushConstant16 = 4435, SpvCapabilityStorageInputOutput16 = 4436, SpvCapabilityDeviceGroup = 4437, SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, SpvCapabilitySampleMaskOverrideCoverageNV = 5249, SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, SpvCapabilityShaderViewportIndexLayerNV = 5254, SpvCapabilityShaderViewportMaskNV = 5255, SpvCapabilityShaderStereoViewNV = 5259, SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, SpvCapabilityMax = 0x7fffffff, } SpvCapability; @@ -958,6 +985,24 @@ typedef enum SpvOp_ { SpvOpSubgroupAnyKHR = 4429, SpvOpSubgroupAllEqualKHR = 4430, SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, SpvOpMax = 0x7fffffff, } SpvOp; diff --git a/ext/vulkan/spirv.hpp b/ext/vulkan/spirv.hpp index 1bac2c0277..b9ae21ecef 100644 --- a/ext/vulkan/spirv.hpp +++ b/ext/vulkan/spirv.hpp @@ -1,974 +1,1019 @@ -// Copyright (c) 2014-2017 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: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of 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. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// -// 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. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10100 -#define SPV_REVISION 6 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010100; -static const unsigned int Revision = 6; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum SourceLanguage { - SourceLanguageUnknown = 0, - SourceLanguageESSL = 1, - SourceLanguageGLSL = 2, - SourceLanguageOpenCL_C = 3, - SourceLanguageOpenCL_CPP = 4, - SourceLanguageMax = 0x7fffffff, -}; - -enum ExecutionModel { - ExecutionModelVertex = 0, - ExecutionModelTessellationControl = 1, - ExecutionModelTessellationEvaluation = 2, - ExecutionModelGeometry = 3, - ExecutionModelFragment = 4, - ExecutionModelGLCompute = 5, - ExecutionModelKernel = 6, - ExecutionModelMax = 0x7fffffff, -}; - -enum AddressingModel { - AddressingModelLogical = 0, - AddressingModelPhysical32 = 1, - AddressingModelPhysical64 = 2, - AddressingModelMax = 0x7fffffff, -}; - -enum MemoryModel { - MemoryModelSimple = 0, - MemoryModelGLSL450 = 1, - MemoryModelOpenCL = 2, - MemoryModelMax = 0x7fffffff, -}; - -enum ExecutionMode { - ExecutionModeInvocations = 0, - ExecutionModeSpacingEqual = 1, - ExecutionModeSpacingFractionalEven = 2, - ExecutionModeSpacingFractionalOdd = 3, - ExecutionModeVertexOrderCw = 4, - ExecutionModeVertexOrderCcw = 5, - ExecutionModePixelCenterInteger = 6, - ExecutionModeOriginUpperLeft = 7, - ExecutionModeOriginLowerLeft = 8, - ExecutionModeEarlyFragmentTests = 9, - ExecutionModePointMode = 10, - ExecutionModeXfb = 11, - ExecutionModeDepthReplacing = 12, - ExecutionModeDepthGreater = 14, - ExecutionModeDepthLess = 15, - ExecutionModeDepthUnchanged = 16, - ExecutionModeLocalSize = 17, - ExecutionModeLocalSizeHint = 18, - ExecutionModeInputPoints = 19, - ExecutionModeInputLines = 20, - ExecutionModeInputLinesAdjacency = 21, - ExecutionModeTriangles = 22, - ExecutionModeInputTrianglesAdjacency = 23, - ExecutionModeQuads = 24, - ExecutionModeIsolines = 25, - ExecutionModeOutputVertices = 26, - ExecutionModeOutputPoints = 27, - ExecutionModeOutputLineStrip = 28, - ExecutionModeOutputTriangleStrip = 29, - ExecutionModeVecTypeHint = 30, - ExecutionModeContractionOff = 31, - ExecutionModeInitializer = 33, - ExecutionModeFinalizer = 34, - ExecutionModeSubgroupSize = 35, - ExecutionModeSubgroupsPerWorkgroup = 36, - ExecutionModeMax = 0x7fffffff, -}; - -enum StorageClass { - StorageClassUniformConstant = 0, - StorageClassInput = 1, - StorageClassUniform = 2, - StorageClassOutput = 3, - StorageClassWorkgroup = 4, - StorageClassCrossWorkgroup = 5, - StorageClassPrivate = 6, - StorageClassFunction = 7, - StorageClassGeneric = 8, - StorageClassPushConstant = 9, - StorageClassAtomicCounter = 10, - StorageClassImage = 11, - StorageClassMax = 0x7fffffff, -}; - -enum Dim { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - DimCube = 3, - DimRect = 4, - DimBuffer = 5, - DimSubpassData = 6, - DimMax = 0x7fffffff, -}; - -enum SamplerAddressingMode { - SamplerAddressingModeNone = 0, - SamplerAddressingModeClampToEdge = 1, - SamplerAddressingModeClamp = 2, - SamplerAddressingModeRepeat = 3, - SamplerAddressingModeRepeatMirrored = 4, - SamplerAddressingModeMax = 0x7fffffff, -}; - -enum SamplerFilterMode { - SamplerFilterModeNearest = 0, - SamplerFilterModeLinear = 1, - SamplerFilterModeMax = 0x7fffffff, -}; - -enum ImageFormat { - ImageFormatUnknown = 0, - ImageFormatRgba32f = 1, - ImageFormatRgba16f = 2, - ImageFormatR32f = 3, - ImageFormatRgba8 = 4, - ImageFormatRgba8Snorm = 5, - ImageFormatRg32f = 6, - ImageFormatRg16f = 7, - ImageFormatR11fG11fB10f = 8, - ImageFormatR16f = 9, - ImageFormatRgba16 = 10, - ImageFormatRgb10A2 = 11, - ImageFormatRg16 = 12, - ImageFormatRg8 = 13, - ImageFormatR16 = 14, - ImageFormatR8 = 15, - ImageFormatRgba16Snorm = 16, - ImageFormatRg16Snorm = 17, - ImageFormatRg8Snorm = 18, - ImageFormatR16Snorm = 19, - ImageFormatR8Snorm = 20, - ImageFormatRgba32i = 21, - ImageFormatRgba16i = 22, - ImageFormatRgba8i = 23, - ImageFormatR32i = 24, - ImageFormatRg32i = 25, - ImageFormatRg16i = 26, - ImageFormatRg8i = 27, - ImageFormatR16i = 28, - ImageFormatR8i = 29, - ImageFormatRgba32ui = 30, - ImageFormatRgba16ui = 31, - ImageFormatRgba8ui = 32, - ImageFormatR32ui = 33, - ImageFormatRgb10a2ui = 34, - ImageFormatRg32ui = 35, - ImageFormatRg16ui = 36, - ImageFormatRg8ui = 37, - ImageFormatR16ui = 38, - ImageFormatR8ui = 39, - ImageFormatMax = 0x7fffffff, -}; - -enum ImageChannelOrder { - ImageChannelOrderR = 0, - ImageChannelOrderA = 1, - ImageChannelOrderRG = 2, - ImageChannelOrderRA = 3, - ImageChannelOrderRGB = 4, - ImageChannelOrderRGBA = 5, - ImageChannelOrderBGRA = 6, - ImageChannelOrderARGB = 7, - ImageChannelOrderIntensity = 8, - ImageChannelOrderLuminance = 9, - ImageChannelOrderRx = 10, - ImageChannelOrderRGx = 11, - ImageChannelOrderRGBx = 12, - ImageChannelOrderDepth = 13, - ImageChannelOrderDepthStencil = 14, - ImageChannelOrdersRGB = 15, - ImageChannelOrdersRGBx = 16, - ImageChannelOrdersRGBA = 17, - ImageChannelOrdersBGRA = 18, - ImageChannelOrderABGR = 19, - ImageChannelOrderMax = 0x7fffffff, -}; - -enum ImageChannelDataType { - ImageChannelDataTypeSnormInt8 = 0, - ImageChannelDataTypeSnormInt16 = 1, - ImageChannelDataTypeUnormInt8 = 2, - ImageChannelDataTypeUnormInt16 = 3, - ImageChannelDataTypeUnormShort565 = 4, - ImageChannelDataTypeUnormShort555 = 5, - ImageChannelDataTypeUnormInt101010 = 6, - ImageChannelDataTypeSignedInt8 = 7, - ImageChannelDataTypeSignedInt16 = 8, - ImageChannelDataTypeSignedInt32 = 9, - ImageChannelDataTypeUnsignedInt8 = 10, - ImageChannelDataTypeUnsignedInt16 = 11, - ImageChannelDataTypeUnsignedInt32 = 12, - ImageChannelDataTypeHalfFloat = 13, - ImageChannelDataTypeFloat = 14, - ImageChannelDataTypeUnormInt24 = 15, - ImageChannelDataTypeUnormInt101010_2 = 16, - ImageChannelDataTypeMax = 0x7fffffff, -}; - -enum ImageOperandsShift { - ImageOperandsBiasShift = 0, - ImageOperandsLodShift = 1, - ImageOperandsGradShift = 2, - ImageOperandsConstOffsetShift = 3, - ImageOperandsOffsetShift = 4, - ImageOperandsConstOffsetsShift = 5, - ImageOperandsSampleShift = 6, - ImageOperandsMinLodShift = 7, - ImageOperandsMax = 0x7fffffff, -}; - -enum ImageOperandsMask { - ImageOperandsMaskNone = 0, - ImageOperandsBiasMask = 0x00000001, - ImageOperandsLodMask = 0x00000002, - ImageOperandsGradMask = 0x00000004, - ImageOperandsConstOffsetMask = 0x00000008, - ImageOperandsOffsetMask = 0x00000010, - ImageOperandsConstOffsetsMask = 0x00000020, - ImageOperandsSampleMask = 0x00000040, - ImageOperandsMinLodMask = 0x00000080, -}; - -enum FPFastMathModeShift { - FPFastMathModeNotNaNShift = 0, - FPFastMathModeNotInfShift = 1, - FPFastMathModeNSZShift = 2, - FPFastMathModeAllowRecipShift = 3, - FPFastMathModeFastShift = 4, - FPFastMathModeMax = 0x7fffffff, -}; - -enum FPFastMathModeMask { - FPFastMathModeMaskNone = 0, - FPFastMathModeNotNaNMask = 0x00000001, - FPFastMathModeNotInfMask = 0x00000002, - FPFastMathModeNSZMask = 0x00000004, - FPFastMathModeAllowRecipMask = 0x00000008, - FPFastMathModeFastMask = 0x00000010, -}; - -enum FPRoundingMode { - FPRoundingModeRTE = 0, - FPRoundingModeRTZ = 1, - FPRoundingModeRTP = 2, - FPRoundingModeRTN = 3, - FPRoundingModeMax = 0x7fffffff, -}; - -enum LinkageType { - LinkageTypeExport = 0, - LinkageTypeImport = 1, - LinkageTypeMax = 0x7fffffff, -}; - -enum AccessQualifier { - AccessQualifierReadOnly = 0, - AccessQualifierWriteOnly = 1, - AccessQualifierReadWrite = 2, - AccessQualifierMax = 0x7fffffff, -}; - -enum FunctionParameterAttribute { - FunctionParameterAttributeZext = 0, - FunctionParameterAttributeSext = 1, - FunctionParameterAttributeByVal = 2, - FunctionParameterAttributeSret = 3, - FunctionParameterAttributeNoAlias = 4, - FunctionParameterAttributeNoCapture = 5, - FunctionParameterAttributeNoWrite = 6, - FunctionParameterAttributeNoReadWrite = 7, - FunctionParameterAttributeMax = 0x7fffffff, -}; - -enum Decoration { - DecorationRelaxedPrecision = 0, - DecorationSpecId = 1, - DecorationBlock = 2, - DecorationBufferBlock = 3, - DecorationRowMajor = 4, - DecorationColMajor = 5, - DecorationArrayStride = 6, - DecorationMatrixStride = 7, - DecorationGLSLShared = 8, - DecorationGLSLPacked = 9, - DecorationCPacked = 10, - DecorationBuiltIn = 11, - DecorationNoPerspective = 13, - DecorationFlat = 14, - DecorationPatch = 15, - DecorationCentroid = 16, - DecorationSample = 17, - DecorationInvariant = 18, - DecorationRestrict = 19, - DecorationAliased = 20, - DecorationVolatile = 21, - DecorationConstant = 22, - DecorationCoherent = 23, - DecorationNonWritable = 24, - DecorationNonReadable = 25, - DecorationUniform = 26, - DecorationSaturatedConversion = 28, - DecorationStream = 29, - DecorationLocation = 30, - DecorationComponent = 31, - DecorationIndex = 32, - DecorationBinding = 33, - DecorationDescriptorSet = 34, - DecorationOffset = 35, - DecorationXfbBuffer = 36, - DecorationXfbStride = 37, - DecorationFuncParamAttr = 38, - DecorationFPRoundingMode = 39, - DecorationFPFastMathMode = 40, - DecorationLinkageAttributes = 41, - DecorationNoContraction = 42, - DecorationInputAttachmentIndex = 43, - DecorationAlignment = 44, - DecorationMaxByteOffset = 45, - DecorationOverrideCoverageNV = 5248, - DecorationPassthroughNV = 5250, - DecorationViewportRelativeNV = 5252, - DecorationSecondaryViewportRelativeNV = 5256, - DecorationMax = 0x7fffffff, -}; - -enum BuiltIn { - BuiltInPosition = 0, - BuiltInPointSize = 1, - 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, - 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, - BuiltInSubgroupSize = 36, - BuiltInSubgroupMaxSize = 37, - BuiltInNumSubgroups = 38, - BuiltInNumEnqueuedSubgroups = 39, - BuiltInSubgroupId = 40, - BuiltInSubgroupLocalInvocationId = 41, - BuiltInVertexIndex = 42, - BuiltInInstanceIndex = 43, - BuiltInSubgroupEqMaskKHR = 4416, - BuiltInSubgroupGeMaskKHR = 4417, - BuiltInSubgroupGtMaskKHR = 4418, - BuiltInSubgroupLeMaskKHR = 4419, - BuiltInSubgroupLtMaskKHR = 4420, - BuiltInBaseVertex = 4424, - BuiltInBaseInstance = 4425, - BuiltInDrawIndex = 4426, - BuiltInDeviceIndex = 4438, - BuiltInViewIndex = 4440, - BuiltInViewportMaskNV = 5253, - BuiltInSecondaryPositionNV = 5257, - BuiltInSecondaryViewportMaskNV = 5258, - BuiltInPositionPerViewNV = 5261, - BuiltInViewportMaskPerViewNV = 5262, - BuiltInMax = 0x7fffffff, -}; - -enum SelectionControlShift { - SelectionControlFlattenShift = 0, - SelectionControlDontFlattenShift = 1, - SelectionControlMax = 0x7fffffff, -}; - -enum SelectionControlMask { - SelectionControlMaskNone = 0, - SelectionControlFlattenMask = 0x00000001, - SelectionControlDontFlattenMask = 0x00000002, -}; - -enum LoopControlShift { - LoopControlUnrollShift = 0, - LoopControlDontUnrollShift = 1, - LoopControlDependencyInfiniteShift = 2, - LoopControlDependencyLengthShift = 3, - LoopControlMax = 0x7fffffff, -}; - -enum LoopControlMask { - LoopControlMaskNone = 0, - LoopControlUnrollMask = 0x00000001, - LoopControlDontUnrollMask = 0x00000002, - LoopControlDependencyInfiniteMask = 0x00000004, - LoopControlDependencyLengthMask = 0x00000008, -}; - -enum FunctionControlShift { - FunctionControlInlineShift = 0, - FunctionControlDontInlineShift = 1, - FunctionControlPureShift = 2, - FunctionControlConstShift = 3, - FunctionControlMax = 0x7fffffff, -}; - -enum FunctionControlMask { - FunctionControlMaskNone = 0, - FunctionControlInlineMask = 0x00000001, - FunctionControlDontInlineMask = 0x00000002, - FunctionControlPureMask = 0x00000004, - FunctionControlConstMask = 0x00000008, -}; - -enum MemorySemanticsShift { - MemorySemanticsAcquireShift = 1, - MemorySemanticsReleaseShift = 2, - MemorySemanticsAcquireReleaseShift = 3, - MemorySemanticsSequentiallyConsistentShift = 4, - MemorySemanticsUniformMemoryShift = 6, - MemorySemanticsSubgroupMemoryShift = 7, - MemorySemanticsWorkgroupMemoryShift = 8, - MemorySemanticsCrossWorkgroupMemoryShift = 9, - MemorySemanticsAtomicCounterMemoryShift = 10, - MemorySemanticsImageMemoryShift = 11, - MemorySemanticsMax = 0x7fffffff, -}; - -enum MemorySemanticsMask { - MemorySemanticsMaskNone = 0, - MemorySemanticsAcquireMask = 0x00000002, - MemorySemanticsReleaseMask = 0x00000004, - MemorySemanticsAcquireReleaseMask = 0x00000008, - MemorySemanticsSequentiallyConsistentMask = 0x00000010, - MemorySemanticsUniformMemoryMask = 0x00000040, - MemorySemanticsSubgroupMemoryMask = 0x00000080, - MemorySemanticsWorkgroupMemoryMask = 0x00000100, - MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - MemorySemanticsAtomicCounterMemoryMask = 0x00000400, - MemorySemanticsImageMemoryMask = 0x00000800, -}; - -enum MemoryAccessShift { - MemoryAccessVolatileShift = 0, - MemoryAccessAlignedShift = 1, - MemoryAccessNontemporalShift = 2, - MemoryAccessMax = 0x7fffffff, -}; - -enum MemoryAccessMask { - MemoryAccessMaskNone = 0, - MemoryAccessVolatileMask = 0x00000001, - MemoryAccessAlignedMask = 0x00000002, - MemoryAccessNontemporalMask = 0x00000004, -}; - -enum Scope { - ScopeCrossDevice = 0, - ScopeDevice = 1, - ScopeWorkgroup = 2, - ScopeSubgroup = 3, - ScopeInvocation = 4, - ScopeMax = 0x7fffffff, -}; - -enum GroupOperation { - GroupOperationReduce = 0, - GroupOperationInclusiveScan = 1, - GroupOperationExclusiveScan = 2, - GroupOperationMax = 0x7fffffff, -}; - -enum KernelEnqueueFlags { - KernelEnqueueFlagsNoWait = 0, - KernelEnqueueFlagsWaitKernel = 1, - KernelEnqueueFlagsWaitWorkGroup = 2, - KernelEnqueueFlagsMax = 0x7fffffff, -}; - -enum KernelProfilingInfoShift { - KernelProfilingInfoCmdExecTimeShift = 0, - KernelProfilingInfoMax = 0x7fffffff, -}; - -enum KernelProfilingInfoMask { - KernelProfilingInfoMaskNone = 0, - KernelProfilingInfoCmdExecTimeMask = 0x00000001, -}; - -enum Capability { - CapabilityMatrix = 0, - CapabilityShader = 1, - CapabilityGeometry = 2, - CapabilityTessellation = 3, - CapabilityAddresses = 4, - CapabilityLinkage = 5, - CapabilityKernel = 6, - CapabilityVector16 = 7, - CapabilityFloat16Buffer = 8, - CapabilityFloat16 = 9, - CapabilityFloat64 = 10, - CapabilityInt64 = 11, - CapabilityInt64Atomics = 12, - CapabilityImageBasic = 13, - CapabilityImageReadWrite = 14, - CapabilityImageMipmap = 15, - CapabilityPipes = 17, - CapabilityGroups = 18, - CapabilityDeviceEnqueue = 19, - CapabilityLiteralSampler = 20, - CapabilityAtomicStorage = 21, - CapabilityInt16 = 22, - CapabilityTessellationPointSize = 23, - CapabilityGeometryPointSize = 24, - CapabilityImageGatherExtended = 25, - CapabilityStorageImageMultisample = 27, - CapabilityUniformBufferArrayDynamicIndexing = 28, - CapabilitySampledImageArrayDynamicIndexing = 29, - CapabilityStorageBufferArrayDynamicIndexing = 30, - CapabilityStorageImageArrayDynamicIndexing = 31, - CapabilityClipDistance = 32, - CapabilityCullDistance = 33, - CapabilityImageCubeArray = 34, - CapabilitySampleRateShading = 35, - CapabilityImageRect = 36, - CapabilitySampledRect = 37, - CapabilityGenericPointer = 38, - CapabilityInt8 = 39, - CapabilityInputAttachment = 40, - CapabilitySparseResidency = 41, - CapabilityMinLod = 42, - CapabilitySampled1D = 43, - CapabilityImage1D = 44, - CapabilitySampledCubeArray = 45, - CapabilitySampledBuffer = 46, - CapabilityImageBuffer = 47, - CapabilityImageMSArray = 48, - CapabilityStorageImageExtendedFormats = 49, - CapabilityImageQuery = 50, - CapabilityDerivativeControl = 51, - CapabilityInterpolationFunction = 52, - CapabilityTransformFeedback = 53, - CapabilityGeometryStreams = 54, - CapabilityStorageImageReadWithoutFormat = 55, - CapabilityStorageImageWriteWithoutFormat = 56, - CapabilityMultiViewport = 57, - CapabilitySubgroupDispatch = 58, - CapabilityNamedBarrier = 59, - CapabilityPipeStorage = 60, - CapabilitySubgroupBallotKHR = 4423, - CapabilityDrawParameters = 4427, - CapabilitySubgroupVoteKHR = 4431, - CapabilityStorageUniformBufferBlock16 = 4433, - CapabilityStorageUniform16 = 4434, - CapabilityStoragePushConstant16 = 4435, - CapabilityStorageInputOutput16 = 4436, - CapabilityDeviceGroup = 4437, - CapabilityMultiView = 4439, - CapabilitySampleMaskOverrideCoverageNV = 5249, - CapabilityGeometryShaderPassthroughNV = 5251, - CapabilityShaderViewportIndexLayerNV = 5254, - CapabilityShaderViewportMaskNV = 5255, - CapabilityShaderStereoViewNV = 5259, - CapabilityPerViewAttributesNV = 5260, - CapabilityMax = 0x7fffffff, -}; - -enum Op { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - OpMax = 0x7fffffff, -}; - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP - +// Copyright (c) 2014-2017 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of 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. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// 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. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + 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, + 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, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/ext/vulkan/spirv.hpp11 b/ext/vulkan/spirv.hpp11 index b99396378c..c345f6da98 100644 --- a/ext/vulkan/spirv.hpp11 +++ b/ext/vulkan/spirv.hpp11 @@ -1,974 +1,1019 @@ -// Copyright (c) 2014-2017 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: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of 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. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// -// 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. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10100 -#define SPV_REVISION 6 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010100; -static const unsigned int Revision = 6; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum class SourceLanguage : unsigned { - Unknown = 0, - ESSL = 1, - GLSL = 2, - OpenCL_C = 3, - OpenCL_CPP = 4, - Max = 0x7fffffff, -}; - -enum class ExecutionModel : unsigned { - Vertex = 0, - TessellationControl = 1, - TessellationEvaluation = 2, - Geometry = 3, - Fragment = 4, - GLCompute = 5, - Kernel = 6, - Max = 0x7fffffff, -}; - -enum class AddressingModel : unsigned { - Logical = 0, - Physical32 = 1, - Physical64 = 2, - Max = 0x7fffffff, -}; - -enum class MemoryModel : unsigned { - Simple = 0, - GLSL450 = 1, - OpenCL = 2, - Max = 0x7fffffff, -}; - -enum class ExecutionMode : unsigned { - Invocations = 0, - SpacingEqual = 1, - SpacingFractionalEven = 2, - SpacingFractionalOdd = 3, - VertexOrderCw = 4, - VertexOrderCcw = 5, - PixelCenterInteger = 6, - OriginUpperLeft = 7, - OriginLowerLeft = 8, - EarlyFragmentTests = 9, - PointMode = 10, - Xfb = 11, - DepthReplacing = 12, - DepthGreater = 14, - DepthLess = 15, - DepthUnchanged = 16, - LocalSize = 17, - LocalSizeHint = 18, - InputPoints = 19, - InputLines = 20, - InputLinesAdjacency = 21, - Triangles = 22, - InputTrianglesAdjacency = 23, - Quads = 24, - Isolines = 25, - OutputVertices = 26, - OutputPoints = 27, - OutputLineStrip = 28, - OutputTriangleStrip = 29, - VecTypeHint = 30, - ContractionOff = 31, - Initializer = 33, - Finalizer = 34, - SubgroupSize = 35, - SubgroupsPerWorkgroup = 36, - Max = 0x7fffffff, -}; - -enum class StorageClass : unsigned { - UniformConstant = 0, - Input = 1, - Uniform = 2, - Output = 3, - Workgroup = 4, - CrossWorkgroup = 5, - Private = 6, - Function = 7, - Generic = 8, - PushConstant = 9, - AtomicCounter = 10, - Image = 11, - Max = 0x7fffffff, -}; - -enum class Dim : unsigned { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - Cube = 3, - Rect = 4, - Buffer = 5, - SubpassData = 6, - Max = 0x7fffffff, -}; - -enum class SamplerAddressingMode : unsigned { - None = 0, - ClampToEdge = 1, - Clamp = 2, - Repeat = 3, - RepeatMirrored = 4, - Max = 0x7fffffff, -}; - -enum class SamplerFilterMode : unsigned { - Nearest = 0, - Linear = 1, - Max = 0x7fffffff, -}; - -enum class ImageFormat : unsigned { - Unknown = 0, - Rgba32f = 1, - Rgba16f = 2, - R32f = 3, - Rgba8 = 4, - Rgba8Snorm = 5, - Rg32f = 6, - Rg16f = 7, - R11fG11fB10f = 8, - R16f = 9, - Rgba16 = 10, - Rgb10A2 = 11, - Rg16 = 12, - Rg8 = 13, - R16 = 14, - R8 = 15, - Rgba16Snorm = 16, - Rg16Snorm = 17, - Rg8Snorm = 18, - R16Snorm = 19, - R8Snorm = 20, - Rgba32i = 21, - Rgba16i = 22, - Rgba8i = 23, - R32i = 24, - Rg32i = 25, - Rg16i = 26, - Rg8i = 27, - R16i = 28, - R8i = 29, - Rgba32ui = 30, - Rgba16ui = 31, - Rgba8ui = 32, - R32ui = 33, - Rgb10a2ui = 34, - Rg32ui = 35, - Rg16ui = 36, - Rg8ui = 37, - R16ui = 38, - R8ui = 39, - Max = 0x7fffffff, -}; - -enum class ImageChannelOrder : unsigned { - R = 0, - A = 1, - RG = 2, - RA = 3, - RGB = 4, - RGBA = 5, - BGRA = 6, - ARGB = 7, - Intensity = 8, - Luminance = 9, - Rx = 10, - RGx = 11, - RGBx = 12, - Depth = 13, - DepthStencil = 14, - sRGB = 15, - sRGBx = 16, - sRGBA = 17, - sBGRA = 18, - ABGR = 19, - Max = 0x7fffffff, -}; - -enum class ImageChannelDataType : unsigned { - SnormInt8 = 0, - SnormInt16 = 1, - UnormInt8 = 2, - UnormInt16 = 3, - UnormShort565 = 4, - UnormShort555 = 5, - UnormInt101010 = 6, - SignedInt8 = 7, - SignedInt16 = 8, - SignedInt32 = 9, - UnsignedInt8 = 10, - UnsignedInt16 = 11, - UnsignedInt32 = 12, - HalfFloat = 13, - Float = 14, - UnormInt24 = 15, - UnormInt101010_2 = 16, - Max = 0x7fffffff, -}; - -enum class ImageOperandsShift : unsigned { - Bias = 0, - Lod = 1, - Grad = 2, - ConstOffset = 3, - Offset = 4, - ConstOffsets = 5, - Sample = 6, - MinLod = 7, - Max = 0x7fffffff, -}; - -enum class ImageOperandsMask : unsigned { - MaskNone = 0, - Bias = 0x00000001, - Lod = 0x00000002, - Grad = 0x00000004, - ConstOffset = 0x00000008, - Offset = 0x00000010, - ConstOffsets = 0x00000020, - Sample = 0x00000040, - MinLod = 0x00000080, -}; - -enum class FPFastMathModeShift : unsigned { - NotNaN = 0, - NotInf = 1, - NSZ = 2, - AllowRecip = 3, - Fast = 4, - Max = 0x7fffffff, -}; - -enum class FPFastMathModeMask : unsigned { - MaskNone = 0, - NotNaN = 0x00000001, - NotInf = 0x00000002, - NSZ = 0x00000004, - AllowRecip = 0x00000008, - Fast = 0x00000010, -}; - -enum class FPRoundingMode : unsigned { - RTE = 0, - RTZ = 1, - RTP = 2, - RTN = 3, - Max = 0x7fffffff, -}; - -enum class LinkageType : unsigned { - Export = 0, - Import = 1, - Max = 0x7fffffff, -}; - -enum class AccessQualifier : unsigned { - ReadOnly = 0, - WriteOnly = 1, - ReadWrite = 2, - Max = 0x7fffffff, -}; - -enum class FunctionParameterAttribute : unsigned { - Zext = 0, - Sext = 1, - ByVal = 2, - Sret = 3, - NoAlias = 4, - NoCapture = 5, - NoWrite = 6, - NoReadWrite = 7, - Max = 0x7fffffff, -}; - -enum class Decoration : unsigned { - RelaxedPrecision = 0, - SpecId = 1, - Block = 2, - BufferBlock = 3, - RowMajor = 4, - ColMajor = 5, - ArrayStride = 6, - MatrixStride = 7, - GLSLShared = 8, - GLSLPacked = 9, - CPacked = 10, - BuiltIn = 11, - NoPerspective = 13, - Flat = 14, - Patch = 15, - Centroid = 16, - Sample = 17, - Invariant = 18, - Restrict = 19, - Aliased = 20, - Volatile = 21, - Constant = 22, - Coherent = 23, - NonWritable = 24, - NonReadable = 25, - Uniform = 26, - SaturatedConversion = 28, - Stream = 29, - Location = 30, - Component = 31, - Index = 32, - Binding = 33, - DescriptorSet = 34, - Offset = 35, - XfbBuffer = 36, - XfbStride = 37, - FuncParamAttr = 38, - FPRoundingMode = 39, - FPFastMathMode = 40, - LinkageAttributes = 41, - NoContraction = 42, - InputAttachmentIndex = 43, - Alignment = 44, - MaxByteOffset = 45, - OverrideCoverageNV = 5248, - PassthroughNV = 5250, - ViewportRelativeNV = 5252, - SecondaryViewportRelativeNV = 5256, - Max = 0x7fffffff, -}; - -enum class BuiltIn : unsigned { - Position = 0, - PointSize = 1, - ClipDistance = 3, - CullDistance = 4, - VertexId = 5, - InstanceId = 6, - PrimitiveId = 7, - InvocationId = 8, - Layer = 9, - ViewportIndex = 10, - TessLevelOuter = 11, - TessLevelInner = 12, - TessCoord = 13, - PatchVertices = 14, - FragCoord = 15, - PointCoord = 16, - FrontFacing = 17, - SampleId = 18, - SamplePosition = 19, - SampleMask = 20, - FragDepth = 22, - HelperInvocation = 23, - NumWorkgroups = 24, - WorkgroupSize = 25, - WorkgroupId = 26, - LocalInvocationId = 27, - GlobalInvocationId = 28, - LocalInvocationIndex = 29, - WorkDim = 30, - GlobalSize = 31, - EnqueuedWorkgroupSize = 32, - GlobalOffset = 33, - GlobalLinearId = 34, - SubgroupSize = 36, - SubgroupMaxSize = 37, - NumSubgroups = 38, - NumEnqueuedSubgroups = 39, - SubgroupId = 40, - SubgroupLocalInvocationId = 41, - VertexIndex = 42, - InstanceIndex = 43, - SubgroupEqMaskKHR = 4416, - SubgroupGeMaskKHR = 4417, - SubgroupGtMaskKHR = 4418, - SubgroupLeMaskKHR = 4419, - SubgroupLtMaskKHR = 4420, - BaseVertex = 4424, - BaseInstance = 4425, - DrawIndex = 4426, - DeviceIndex = 4438, - ViewIndex = 4440, - ViewportMaskNV = 5253, - SecondaryPositionNV = 5257, - SecondaryViewportMaskNV = 5258, - PositionPerViewNV = 5261, - ViewportMaskPerViewNV = 5262, - Max = 0x7fffffff, -}; - -enum class SelectionControlShift : unsigned { - Flatten = 0, - DontFlatten = 1, - Max = 0x7fffffff, -}; - -enum class SelectionControlMask : unsigned { - MaskNone = 0, - Flatten = 0x00000001, - DontFlatten = 0x00000002, -}; - -enum class LoopControlShift : unsigned { - Unroll = 0, - DontUnroll = 1, - DependencyInfinite = 2, - DependencyLength = 3, - Max = 0x7fffffff, -}; - -enum class LoopControlMask : unsigned { - MaskNone = 0, - Unroll = 0x00000001, - DontUnroll = 0x00000002, - DependencyInfinite = 0x00000004, - DependencyLength = 0x00000008, -}; - -enum class FunctionControlShift : unsigned { - Inline = 0, - DontInline = 1, - Pure = 2, - Const = 3, - Max = 0x7fffffff, -}; - -enum class FunctionControlMask : unsigned { - MaskNone = 0, - Inline = 0x00000001, - DontInline = 0x00000002, - Pure = 0x00000004, - Const = 0x00000008, -}; - -enum class MemorySemanticsShift : unsigned { - Acquire = 1, - Release = 2, - AcquireRelease = 3, - SequentiallyConsistent = 4, - UniformMemory = 6, - SubgroupMemory = 7, - WorkgroupMemory = 8, - CrossWorkgroupMemory = 9, - AtomicCounterMemory = 10, - ImageMemory = 11, - Max = 0x7fffffff, -}; - -enum class MemorySemanticsMask : unsigned { - MaskNone = 0, - Acquire = 0x00000002, - Release = 0x00000004, - AcquireRelease = 0x00000008, - SequentiallyConsistent = 0x00000010, - UniformMemory = 0x00000040, - SubgroupMemory = 0x00000080, - WorkgroupMemory = 0x00000100, - CrossWorkgroupMemory = 0x00000200, - AtomicCounterMemory = 0x00000400, - ImageMemory = 0x00000800, -}; - -enum class MemoryAccessShift : unsigned { - Volatile = 0, - Aligned = 1, - Nontemporal = 2, - Max = 0x7fffffff, -}; - -enum class MemoryAccessMask : unsigned { - MaskNone = 0, - Volatile = 0x00000001, - Aligned = 0x00000002, - Nontemporal = 0x00000004, -}; - -enum class Scope : unsigned { - CrossDevice = 0, - Device = 1, - Workgroup = 2, - Subgroup = 3, - Invocation = 4, - Max = 0x7fffffff, -}; - -enum class GroupOperation : unsigned { - Reduce = 0, - InclusiveScan = 1, - ExclusiveScan = 2, - Max = 0x7fffffff, -}; - -enum class KernelEnqueueFlags : unsigned { - NoWait = 0, - WaitKernel = 1, - WaitWorkGroup = 2, - Max = 0x7fffffff, -}; - -enum class KernelProfilingInfoShift : unsigned { - CmdExecTime = 0, - Max = 0x7fffffff, -}; - -enum class KernelProfilingInfoMask : unsigned { - MaskNone = 0, - CmdExecTime = 0x00000001, -}; - -enum class Capability : unsigned { - Matrix = 0, - Shader = 1, - Geometry = 2, - Tessellation = 3, - Addresses = 4, - Linkage = 5, - Kernel = 6, - Vector16 = 7, - Float16Buffer = 8, - Float16 = 9, - Float64 = 10, - Int64 = 11, - Int64Atomics = 12, - ImageBasic = 13, - ImageReadWrite = 14, - ImageMipmap = 15, - Pipes = 17, - Groups = 18, - DeviceEnqueue = 19, - LiteralSampler = 20, - AtomicStorage = 21, - Int16 = 22, - TessellationPointSize = 23, - GeometryPointSize = 24, - ImageGatherExtended = 25, - StorageImageMultisample = 27, - UniformBufferArrayDynamicIndexing = 28, - SampledImageArrayDynamicIndexing = 29, - StorageBufferArrayDynamicIndexing = 30, - StorageImageArrayDynamicIndexing = 31, - ClipDistance = 32, - CullDistance = 33, - ImageCubeArray = 34, - SampleRateShading = 35, - ImageRect = 36, - SampledRect = 37, - GenericPointer = 38, - Int8 = 39, - InputAttachment = 40, - SparseResidency = 41, - MinLod = 42, - Sampled1D = 43, - Image1D = 44, - SampledCubeArray = 45, - SampledBuffer = 46, - ImageBuffer = 47, - ImageMSArray = 48, - StorageImageExtendedFormats = 49, - ImageQuery = 50, - DerivativeControl = 51, - InterpolationFunction = 52, - TransformFeedback = 53, - GeometryStreams = 54, - StorageImageReadWithoutFormat = 55, - StorageImageWriteWithoutFormat = 56, - MultiViewport = 57, - SubgroupDispatch = 58, - NamedBarrier = 59, - PipeStorage = 60, - SubgroupBallotKHR = 4423, - DrawParameters = 4427, - SubgroupVoteKHR = 4431, - StorageUniformBufferBlock16 = 4433, - StorageUniform16 = 4434, - StoragePushConstant16 = 4435, - StorageInputOutput16 = 4436, - DeviceGroup = 4437, - MultiView = 4439, - SampleMaskOverrideCoverageNV = 5249, - GeometryShaderPassthroughNV = 5251, - ShaderViewportIndexLayerNV = 5254, - ShaderViewportMaskNV = 5255, - ShaderStereoViewNV = 5259, - PerViewAttributesNV = 5260, - Max = 0x7fffffff, -}; - -enum class Op : unsigned { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - Max = 0x7fffffff, -}; - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP - +// Copyright (c) 2014-2017 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of 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. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// 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. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/ext/vulkan/spirv.json b/ext/vulkan/spirv.json index a966cfbc10..988d7bf3ad 100644 --- a/ext/vulkan/spirv.json +++ b/ext/vulkan/spirv.json @@ -1,990 +1,1035 @@ -{ - "spv": - { - "meta": - { - "Comment": - [ - [ - "Copyright (c) 2014-2017 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:", - "", - "The above copyright notice and this permission notice shall be included in", - "all copies or substantial portions of 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." - ], - [ - "This header is automatically generated by the same tool that creates", - "the Binary Section of the SPIR-V specification." - ], - [ - "Enumeration tokens for SPIR-V, in various styles:", - " C, C++, C++11, JSON, Lua, Python", - "", - "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", - "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", - "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", - "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", - "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", - "", - "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." - ] - ], - "MagicNumber": 119734787, - "Version": 65792, - "Revision": 6, - "OpCodeMask": 65535, - "WordCountShift": 16 - }, - "enum": - [ - { - "Name": "SourceLanguage", - "Type": "Value", - "Values": - { - "Unknown": 0, - "ESSL": 1, - "GLSL": 2, - "OpenCL_C": 3, - "OpenCL_CPP": 4 - } - }, - { - "Name": "ExecutionModel", - "Type": "Value", - "Values": - { - "Vertex": 0, - "TessellationControl": 1, - "TessellationEvaluation": 2, - "Geometry": 3, - "Fragment": 4, - "GLCompute": 5, - "Kernel": 6 - } - }, - { - "Name": "AddressingModel", - "Type": "Value", - "Values": - { - "Logical": 0, - "Physical32": 1, - "Physical64": 2 - } - }, - { - "Name": "MemoryModel", - "Type": "Value", - "Values": - { - "Simple": 0, - "GLSL450": 1, - "OpenCL": 2 - } - }, - { - "Name": "ExecutionMode", - "Type": "Value", - "Values": - { - "Invocations": 0, - "SpacingEqual": 1, - "SpacingFractionalEven": 2, - "SpacingFractionalOdd": 3, - "VertexOrderCw": 4, - "VertexOrderCcw": 5, - "PixelCenterInteger": 6, - "OriginUpperLeft": 7, - "OriginLowerLeft": 8, - "EarlyFragmentTests": 9, - "PointMode": 10, - "Xfb": 11, - "DepthReplacing": 12, - "DepthGreater": 14, - "DepthLess": 15, - "DepthUnchanged": 16, - "LocalSize": 17, - "LocalSizeHint": 18, - "InputPoints": 19, - "InputLines": 20, - "InputLinesAdjacency": 21, - "Triangles": 22, - "InputTrianglesAdjacency": 23, - "Quads": 24, - "Isolines": 25, - "OutputVertices": 26, - "OutputPoints": 27, - "OutputLineStrip": 28, - "OutputTriangleStrip": 29, - "VecTypeHint": 30, - "ContractionOff": 31, - "Initializer": 33, - "Finalizer": 34, - "SubgroupSize": 35, - "SubgroupsPerWorkgroup": 36 - } - }, - { - "Name": "StorageClass", - "Type": "Value", - "Values": - { - "UniformConstant": 0, - "Input": 1, - "Uniform": 2, - "Output": 3, - "Workgroup": 4, - "CrossWorkgroup": 5, - "Private": 6, - "Function": 7, - "Generic": 8, - "PushConstant": 9, - "AtomicCounter": 10, - "Image": 11 - } - }, - { - "Name": "Dim", - "Type": "Value", - "Values": - { - "Dim1D": 0, - "Dim2D": 1, - "Dim3D": 2, - "Cube": 3, - "Rect": 4, - "Buffer": 5, - "SubpassData": 6 - } - }, - { - "Name": "SamplerAddressingMode", - "Type": "Value", - "Values": - { - "None": 0, - "ClampToEdge": 1, - "Clamp": 2, - "Repeat": 3, - "RepeatMirrored": 4 - } - }, - { - "Name": "SamplerFilterMode", - "Type": "Value", - "Values": - { - "Nearest": 0, - "Linear": 1 - } - }, - { - "Name": "ImageFormat", - "Type": "Value", - "Values": - { - "Unknown": 0, - "Rgba32f": 1, - "Rgba16f": 2, - "R32f": 3, - "Rgba8": 4, - "Rgba8Snorm": 5, - "Rg32f": 6, - "Rg16f": 7, - "R11fG11fB10f": 8, - "R16f": 9, - "Rgba16": 10, - "Rgb10A2": 11, - "Rg16": 12, - "Rg8": 13, - "R16": 14, - "R8": 15, - "Rgba16Snorm": 16, - "Rg16Snorm": 17, - "Rg8Snorm": 18, - "R16Snorm": 19, - "R8Snorm": 20, - "Rgba32i": 21, - "Rgba16i": 22, - "Rgba8i": 23, - "R32i": 24, - "Rg32i": 25, - "Rg16i": 26, - "Rg8i": 27, - "R16i": 28, - "R8i": 29, - "Rgba32ui": 30, - "Rgba16ui": 31, - "Rgba8ui": 32, - "R32ui": 33, - "Rgb10a2ui": 34, - "Rg32ui": 35, - "Rg16ui": 36, - "Rg8ui": 37, - "R16ui": 38, - "R8ui": 39 - } - }, - { - "Name": "ImageChannelOrder", - "Type": "Value", - "Values": - { - "R": 0, - "A": 1, - "RG": 2, - "RA": 3, - "RGB": 4, - "RGBA": 5, - "BGRA": 6, - "ARGB": 7, - "Intensity": 8, - "Luminance": 9, - "Rx": 10, - "RGx": 11, - "RGBx": 12, - "Depth": 13, - "DepthStencil": 14, - "sRGB": 15, - "sRGBx": 16, - "sRGBA": 17, - "sBGRA": 18, - "ABGR": 19 - } - }, - { - "Name": "ImageChannelDataType", - "Type": "Value", - "Values": - { - "SnormInt8": 0, - "SnormInt16": 1, - "UnormInt8": 2, - "UnormInt16": 3, - "UnormShort565": 4, - "UnormShort555": 5, - "UnormInt101010": 6, - "SignedInt8": 7, - "SignedInt16": 8, - "SignedInt32": 9, - "UnsignedInt8": 10, - "UnsignedInt16": 11, - "UnsignedInt32": 12, - "HalfFloat": 13, - "Float": 14, - "UnormInt24": 15, - "UnormInt101010_2": 16 - } - }, - { - "Name": "ImageOperands", - "Type": "Bit", - "Values": - { - "Bias": 0, - "Lod": 1, - "Grad": 2, - "ConstOffset": 3, - "Offset": 4, - "ConstOffsets": 5, - "Sample": 6, - "MinLod": 7 - } - }, - { - "Name": "FPFastMathMode", - "Type": "Bit", - "Values": - { - "NotNaN": 0, - "NotInf": 1, - "NSZ": 2, - "AllowRecip": 3, - "Fast": 4 - } - }, - { - "Name": "FPRoundingMode", - "Type": "Value", - "Values": - { - "RTE": 0, - "RTZ": 1, - "RTP": 2, - "RTN": 3 - } - }, - { - "Name": "LinkageType", - "Type": "Value", - "Values": - { - "Export": 0, - "Import": 1 - } - }, - { - "Name": "AccessQualifier", - "Type": "Value", - "Values": - { - "ReadOnly": 0, - "WriteOnly": 1, - "ReadWrite": 2 - } - }, - { - "Name": "FunctionParameterAttribute", - "Type": "Value", - "Values": - { - "Zext": 0, - "Sext": 1, - "ByVal": 2, - "Sret": 3, - "NoAlias": 4, - "NoCapture": 5, - "NoWrite": 6, - "NoReadWrite": 7 - } - }, - { - "Name": "Decoration", - "Type": "Value", - "Values": - { - "RelaxedPrecision": 0, - "SpecId": 1, - "Block": 2, - "BufferBlock": 3, - "RowMajor": 4, - "ColMajor": 5, - "ArrayStride": 6, - "MatrixStride": 7, - "GLSLShared": 8, - "GLSLPacked": 9, - "CPacked": 10, - "BuiltIn": 11, - "NoPerspective": 13, - "Flat": 14, - "Patch": 15, - "Centroid": 16, - "Sample": 17, - "Invariant": 18, - "Restrict": 19, - "Aliased": 20, - "Volatile": 21, - "Constant": 22, - "Coherent": 23, - "NonWritable": 24, - "NonReadable": 25, - "Uniform": 26, - "SaturatedConversion": 28, - "Stream": 29, - "Location": 30, - "Component": 31, - "Index": 32, - "Binding": 33, - "DescriptorSet": 34, - "Offset": 35, - "XfbBuffer": 36, - "XfbStride": 37, - "FuncParamAttr": 38, - "FPRoundingMode": 39, - "FPFastMathMode": 40, - "LinkageAttributes": 41, - "NoContraction": 42, - "InputAttachmentIndex": 43, - "Alignment": 44, - "MaxByteOffset": 45, - "OverrideCoverageNV": 5248, - "PassthroughNV": 5250, - "ViewportRelativeNV": 5252, - "SecondaryViewportRelativeNV": 5256 - } - }, - { - "Name": "BuiltIn", - "Type": "Value", - "Values": - { - "Position": 0, - "PointSize": 1, - "ClipDistance": 3, - "CullDistance": 4, - "VertexId": 5, - "InstanceId": 6, - "PrimitiveId": 7, - "InvocationId": 8, - "Layer": 9, - "ViewportIndex": 10, - "TessLevelOuter": 11, - "TessLevelInner": 12, - "TessCoord": 13, - "PatchVertices": 14, - "FragCoord": 15, - "PointCoord": 16, - "FrontFacing": 17, - "SampleId": 18, - "SamplePosition": 19, - "SampleMask": 20, - "FragDepth": 22, - "HelperInvocation": 23, - "NumWorkgroups": 24, - "WorkgroupSize": 25, - "WorkgroupId": 26, - "LocalInvocationId": 27, - "GlobalInvocationId": 28, - "LocalInvocationIndex": 29, - "WorkDim": 30, - "GlobalSize": 31, - "EnqueuedWorkgroupSize": 32, - "GlobalOffset": 33, - "GlobalLinearId": 34, - "SubgroupSize": 36, - "SubgroupMaxSize": 37, - "NumSubgroups": 38, - "NumEnqueuedSubgroups": 39, - "SubgroupId": 40, - "SubgroupLocalInvocationId": 41, - "VertexIndex": 42, - "InstanceIndex": 43, - "SubgroupEqMaskKHR": 4416, - "SubgroupGeMaskKHR": 4417, - "SubgroupGtMaskKHR": 4418, - "SubgroupLeMaskKHR": 4419, - "SubgroupLtMaskKHR": 4420, - "BaseVertex": 4424, - "BaseInstance": 4425, - "DrawIndex": 4426, - "DeviceIndex": 4438, - "ViewIndex": 4440, - "ViewportMaskNV": 5253, - "SecondaryPositionNV": 5257, - "SecondaryViewportMaskNV": 5258, - "PositionPerViewNV": 5261, - "ViewportMaskPerViewNV": 5262 - } - }, - { - "Name": "SelectionControl", - "Type": "Bit", - "Values": - { - "Flatten": 0, - "DontFlatten": 1 - } - }, - { - "Name": "LoopControl", - "Type": "Bit", - "Values": - { - "Unroll": 0, - "DontUnroll": 1, - "DependencyInfinite": 2, - "DependencyLength": 3 - } - }, - { - "Name": "FunctionControl", - "Type": "Bit", - "Values": - { - "Inline": 0, - "DontInline": 1, - "Pure": 2, - "Const": 3 - } - }, - { - "Name": "MemorySemantics", - "Type": "Bit", - "Values": - { - "Acquire": 1, - "Release": 2, - "AcquireRelease": 3, - "SequentiallyConsistent": 4, - "UniformMemory": 6, - "SubgroupMemory": 7, - "WorkgroupMemory": 8, - "CrossWorkgroupMemory": 9, - "AtomicCounterMemory": 10, - "ImageMemory": 11 - } - }, - { - "Name": "MemoryAccess", - "Type": "Bit", - "Values": - { - "Volatile": 0, - "Aligned": 1, - "Nontemporal": 2 - } - }, - { - "Name": "Scope", - "Type": "Value", - "Values": - { - "CrossDevice": 0, - "Device": 1, - "Workgroup": 2, - "Subgroup": 3, - "Invocation": 4 - } - }, - { - "Name": "GroupOperation", - "Type": "Value", - "Values": - { - "Reduce": 0, - "InclusiveScan": 1, - "ExclusiveScan": 2 - } - }, - { - "Name": "KernelEnqueueFlags", - "Type": "Value", - "Values": - { - "NoWait": 0, - "WaitKernel": 1, - "WaitWorkGroup": 2 - } - }, - { - "Name": "KernelProfilingInfo", - "Type": "Bit", - "Values": - { - "CmdExecTime": 0 - } - }, - { - "Name": "Capability", - "Type": "Value", - "Values": - { - "Matrix": 0, - "Shader": 1, - "Geometry": 2, - "Tessellation": 3, - "Addresses": 4, - "Linkage": 5, - "Kernel": 6, - "Vector16": 7, - "Float16Buffer": 8, - "Float16": 9, - "Float64": 10, - "Int64": 11, - "Int64Atomics": 12, - "ImageBasic": 13, - "ImageReadWrite": 14, - "ImageMipmap": 15, - "Pipes": 17, - "Groups": 18, - "DeviceEnqueue": 19, - "LiteralSampler": 20, - "AtomicStorage": 21, - "Int16": 22, - "TessellationPointSize": 23, - "GeometryPointSize": 24, - "ImageGatherExtended": 25, - "StorageImageMultisample": 27, - "UniformBufferArrayDynamicIndexing": 28, - "SampledImageArrayDynamicIndexing": 29, - "StorageBufferArrayDynamicIndexing": 30, - "StorageImageArrayDynamicIndexing": 31, - "ClipDistance": 32, - "CullDistance": 33, - "ImageCubeArray": 34, - "SampleRateShading": 35, - "ImageRect": 36, - "SampledRect": 37, - "GenericPointer": 38, - "Int8": 39, - "InputAttachment": 40, - "SparseResidency": 41, - "MinLod": 42, - "Sampled1D": 43, - "Image1D": 44, - "SampledCubeArray": 45, - "SampledBuffer": 46, - "ImageBuffer": 47, - "ImageMSArray": 48, - "StorageImageExtendedFormats": 49, - "ImageQuery": 50, - "DerivativeControl": 51, - "InterpolationFunction": 52, - "TransformFeedback": 53, - "GeometryStreams": 54, - "StorageImageReadWithoutFormat": 55, - "StorageImageWriteWithoutFormat": 56, - "MultiViewport": 57, - "SubgroupDispatch": 58, - "NamedBarrier": 59, - "PipeStorage": 60, - "SubgroupBallotKHR": 4423, - "DrawParameters": 4427, - "SubgroupVoteKHR": 4431, - "StorageUniformBufferBlock16": 4433, - "StorageUniform16": 4434, - "StoragePushConstant16": 4435, - "StorageInputOutput16": 4436, - "DeviceGroup": 4437, - "MultiView": 4439, - "SampleMaskOverrideCoverageNV": 5249, - "GeometryShaderPassthroughNV": 5251, - "ShaderViewportIndexLayerNV": 5254, - "ShaderViewportMaskNV": 5255, - "ShaderStereoViewNV": 5259, - "PerViewAttributesNV": 5260 - } - }, - { - "Name": "Op", - "Type": "Value", - "Values": - { - "OpNop": 0, - "OpUndef": 1, - "OpSourceContinued": 2, - "OpSource": 3, - "OpSourceExtension": 4, - "OpName": 5, - "OpMemberName": 6, - "OpString": 7, - "OpLine": 8, - "OpExtension": 10, - "OpExtInstImport": 11, - "OpExtInst": 12, - "OpMemoryModel": 14, - "OpEntryPoint": 15, - "OpExecutionMode": 16, - "OpCapability": 17, - "OpTypeVoid": 19, - "OpTypeBool": 20, - "OpTypeInt": 21, - "OpTypeFloat": 22, - "OpTypeVector": 23, - "OpTypeMatrix": 24, - "OpTypeImage": 25, - "OpTypeSampler": 26, - "OpTypeSampledImage": 27, - "OpTypeArray": 28, - "OpTypeRuntimeArray": 29, - "OpTypeStruct": 30, - "OpTypeOpaque": 31, - "OpTypePointer": 32, - "OpTypeFunction": 33, - "OpTypeEvent": 34, - "OpTypeDeviceEvent": 35, - "OpTypeReserveId": 36, - "OpTypeQueue": 37, - "OpTypePipe": 38, - "OpTypeForwardPointer": 39, - "OpConstantTrue": 41, - "OpConstantFalse": 42, - "OpConstant": 43, - "OpConstantComposite": 44, - "OpConstantSampler": 45, - "OpConstantNull": 46, - "OpSpecConstantTrue": 48, - "OpSpecConstantFalse": 49, - "OpSpecConstant": 50, - "OpSpecConstantComposite": 51, - "OpSpecConstantOp": 52, - "OpFunction": 54, - "OpFunctionParameter": 55, - "OpFunctionEnd": 56, - "OpFunctionCall": 57, - "OpVariable": 59, - "OpImageTexelPointer": 60, - "OpLoad": 61, - "OpStore": 62, - "OpCopyMemory": 63, - "OpCopyMemorySized": 64, - "OpAccessChain": 65, - "OpInBoundsAccessChain": 66, - "OpPtrAccessChain": 67, - "OpArrayLength": 68, - "OpGenericPtrMemSemantics": 69, - "OpInBoundsPtrAccessChain": 70, - "OpDecorate": 71, - "OpMemberDecorate": 72, - "OpDecorationGroup": 73, - "OpGroupDecorate": 74, - "OpGroupMemberDecorate": 75, - "OpVectorExtractDynamic": 77, - "OpVectorInsertDynamic": 78, - "OpVectorShuffle": 79, - "OpCompositeConstruct": 80, - "OpCompositeExtract": 81, - "OpCompositeInsert": 82, - "OpCopyObject": 83, - "OpTranspose": 84, - "OpSampledImage": 86, - "OpImageSampleImplicitLod": 87, - "OpImageSampleExplicitLod": 88, - "OpImageSampleDrefImplicitLod": 89, - "OpImageSampleDrefExplicitLod": 90, - "OpImageSampleProjImplicitLod": 91, - "OpImageSampleProjExplicitLod": 92, - "OpImageSampleProjDrefImplicitLod": 93, - "OpImageSampleProjDrefExplicitLod": 94, - "OpImageFetch": 95, - "OpImageGather": 96, - "OpImageDrefGather": 97, - "OpImageRead": 98, - "OpImageWrite": 99, - "OpImage": 100, - "OpImageQueryFormat": 101, - "OpImageQueryOrder": 102, - "OpImageQuerySizeLod": 103, - "OpImageQuerySize": 104, - "OpImageQueryLod": 105, - "OpImageQueryLevels": 106, - "OpImageQuerySamples": 107, - "OpConvertFToU": 109, - "OpConvertFToS": 110, - "OpConvertSToF": 111, - "OpConvertUToF": 112, - "OpUConvert": 113, - "OpSConvert": 114, - "OpFConvert": 115, - "OpQuantizeToF16": 116, - "OpConvertPtrToU": 117, - "OpSatConvertSToU": 118, - "OpSatConvertUToS": 119, - "OpConvertUToPtr": 120, - "OpPtrCastToGeneric": 121, - "OpGenericCastToPtr": 122, - "OpGenericCastToPtrExplicit": 123, - "OpBitcast": 124, - "OpSNegate": 126, - "OpFNegate": 127, - "OpIAdd": 128, - "OpFAdd": 129, - "OpISub": 130, - "OpFSub": 131, - "OpIMul": 132, - "OpFMul": 133, - "OpUDiv": 134, - "OpSDiv": 135, - "OpFDiv": 136, - "OpUMod": 137, - "OpSRem": 138, - "OpSMod": 139, - "OpFRem": 140, - "OpFMod": 141, - "OpVectorTimesScalar": 142, - "OpMatrixTimesScalar": 143, - "OpVectorTimesMatrix": 144, - "OpMatrixTimesVector": 145, - "OpMatrixTimesMatrix": 146, - "OpOuterProduct": 147, - "OpDot": 148, - "OpIAddCarry": 149, - "OpISubBorrow": 150, - "OpUMulExtended": 151, - "OpSMulExtended": 152, - "OpAny": 154, - "OpAll": 155, - "OpIsNan": 156, - "OpIsInf": 157, - "OpIsFinite": 158, - "OpIsNormal": 159, - "OpSignBitSet": 160, - "OpLessOrGreater": 161, - "OpOrdered": 162, - "OpUnordered": 163, - "OpLogicalEqual": 164, - "OpLogicalNotEqual": 165, - "OpLogicalOr": 166, - "OpLogicalAnd": 167, - "OpLogicalNot": 168, - "OpSelect": 169, - "OpIEqual": 170, - "OpINotEqual": 171, - "OpUGreaterThan": 172, - "OpSGreaterThan": 173, - "OpUGreaterThanEqual": 174, - "OpSGreaterThanEqual": 175, - "OpULessThan": 176, - "OpSLessThan": 177, - "OpULessThanEqual": 178, - "OpSLessThanEqual": 179, - "OpFOrdEqual": 180, - "OpFUnordEqual": 181, - "OpFOrdNotEqual": 182, - "OpFUnordNotEqual": 183, - "OpFOrdLessThan": 184, - "OpFUnordLessThan": 185, - "OpFOrdGreaterThan": 186, - "OpFUnordGreaterThan": 187, - "OpFOrdLessThanEqual": 188, - "OpFUnordLessThanEqual": 189, - "OpFOrdGreaterThanEqual": 190, - "OpFUnordGreaterThanEqual": 191, - "OpShiftRightLogical": 194, - "OpShiftRightArithmetic": 195, - "OpShiftLeftLogical": 196, - "OpBitwiseOr": 197, - "OpBitwiseXor": 198, - "OpBitwiseAnd": 199, - "OpNot": 200, - "OpBitFieldInsert": 201, - "OpBitFieldSExtract": 202, - "OpBitFieldUExtract": 203, - "OpBitReverse": 204, - "OpBitCount": 205, - "OpDPdx": 207, - "OpDPdy": 208, - "OpFwidth": 209, - "OpDPdxFine": 210, - "OpDPdyFine": 211, - "OpFwidthFine": 212, - "OpDPdxCoarse": 213, - "OpDPdyCoarse": 214, - "OpFwidthCoarse": 215, - "OpEmitVertex": 218, - "OpEndPrimitive": 219, - "OpEmitStreamVertex": 220, - "OpEndStreamPrimitive": 221, - "OpControlBarrier": 224, - "OpMemoryBarrier": 225, - "OpAtomicLoad": 227, - "OpAtomicStore": 228, - "OpAtomicExchange": 229, - "OpAtomicCompareExchange": 230, - "OpAtomicCompareExchangeWeak": 231, - "OpAtomicIIncrement": 232, - "OpAtomicIDecrement": 233, - "OpAtomicIAdd": 234, - "OpAtomicISub": 235, - "OpAtomicSMin": 236, - "OpAtomicUMin": 237, - "OpAtomicSMax": 238, - "OpAtomicUMax": 239, - "OpAtomicAnd": 240, - "OpAtomicOr": 241, - "OpAtomicXor": 242, - "OpPhi": 245, - "OpLoopMerge": 246, - "OpSelectionMerge": 247, - "OpLabel": 248, - "OpBranch": 249, - "OpBranchConditional": 250, - "OpSwitch": 251, - "OpKill": 252, - "OpReturn": 253, - "OpReturnValue": 254, - "OpUnreachable": 255, - "OpLifetimeStart": 256, - "OpLifetimeStop": 257, - "OpGroupAsyncCopy": 259, - "OpGroupWaitEvents": 260, - "OpGroupAll": 261, - "OpGroupAny": 262, - "OpGroupBroadcast": 263, - "OpGroupIAdd": 264, - "OpGroupFAdd": 265, - "OpGroupFMin": 266, - "OpGroupUMin": 267, - "OpGroupSMin": 268, - "OpGroupFMax": 269, - "OpGroupUMax": 270, - "OpGroupSMax": 271, - "OpReadPipe": 274, - "OpWritePipe": 275, - "OpReservedReadPipe": 276, - "OpReservedWritePipe": 277, - "OpReserveReadPipePackets": 278, - "OpReserveWritePipePackets": 279, - "OpCommitReadPipe": 280, - "OpCommitWritePipe": 281, - "OpIsValidReserveId": 282, - "OpGetNumPipePackets": 283, - "OpGetMaxPipePackets": 284, - "OpGroupReserveReadPipePackets": 285, - "OpGroupReserveWritePipePackets": 286, - "OpGroupCommitReadPipe": 287, - "OpGroupCommitWritePipe": 288, - "OpEnqueueMarker": 291, - "OpEnqueueKernel": 292, - "OpGetKernelNDrangeSubGroupCount": 293, - "OpGetKernelNDrangeMaxSubGroupSize": 294, - "OpGetKernelWorkGroupSize": 295, - "OpGetKernelPreferredWorkGroupSizeMultiple": 296, - "OpRetainEvent": 297, - "OpReleaseEvent": 298, - "OpCreateUserEvent": 299, - "OpIsValidEvent": 300, - "OpSetUserEventStatus": 301, - "OpCaptureEventProfilingInfo": 302, - "OpGetDefaultQueue": 303, - "OpBuildNDRange": 304, - "OpImageSparseSampleImplicitLod": 305, - "OpImageSparseSampleExplicitLod": 306, - "OpImageSparseSampleDrefImplicitLod": 307, - "OpImageSparseSampleDrefExplicitLod": 308, - "OpImageSparseSampleProjImplicitLod": 309, - "OpImageSparseSampleProjExplicitLod": 310, - "OpImageSparseSampleProjDrefImplicitLod": 311, - "OpImageSparseSampleProjDrefExplicitLod": 312, - "OpImageSparseFetch": 313, - "OpImageSparseGather": 314, - "OpImageSparseDrefGather": 315, - "OpImageSparseTexelsResident": 316, - "OpNoLine": 317, - "OpAtomicFlagTestAndSet": 318, - "OpAtomicFlagClear": 319, - "OpImageSparseRead": 320, - "OpSizeOf": 321, - "OpTypePipeStorage": 322, - "OpConstantPipeStorage": 323, - "OpCreatePipeFromPipeStorage": 324, - "OpGetKernelLocalSizeForSubgroupCount": 325, - "OpGetKernelMaxNumSubgroups": 326, - "OpTypeNamedBarrier": 327, - "OpNamedBarrierInitialize": 328, - "OpMemoryNamedBarrier": 329, - "OpModuleProcessed": 330, - "OpSubgroupBallotKHR": 4421, - "OpSubgroupFirstInvocationKHR": 4422, - "OpSubgroupAllKHR": 4428, - "OpSubgroupAnyKHR": 4429, - "OpSubgroupAllEqualKHR": 4430, - "OpSubgroupReadInvocationKHR": 4432 - } - } - ] - } -} - +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2017 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:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of 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." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "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." + ] + ], + "MagicNumber": 119734787, + "Version": 65792, + "Revision": 8, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578 + } + } + ] + } +} + diff --git a/ext/vulkan/spirv.lua b/ext/vulkan/spirv.lua index 421c1f45bb..44688596cd 100644 --- a/ext/vulkan/spirv.lua +++ b/ext/vulkan/spirv.lua @@ -1,921 +1,966 @@ --- Copyright (c) 2014-2017 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: --- --- The above copyright notice and this permission notice shall be included in --- all copies or substantial portions of 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. - --- This header is automatically generated by the same tool that creates --- the Binary Section of the SPIR-V specification. - --- Enumeration tokens for SPIR-V, in various styles: --- C, C++, C++11, JSON, Lua, Python --- --- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL --- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL --- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL --- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL --- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] --- --- 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. - -spv = { - MagicNumber = 0x07230203, - Version = 0x00010100, - Revision = 6, - OpCodeMask = 0xffff, - WordCountShift = 16, - - SourceLanguage = { - Unknown = 0, - ESSL = 1, - GLSL = 2, - OpenCL_C = 3, - OpenCL_CPP = 4, - }, - - ExecutionModel = { - Vertex = 0, - TessellationControl = 1, - TessellationEvaluation = 2, - Geometry = 3, - Fragment = 4, - GLCompute = 5, - Kernel = 6, - }, - - AddressingModel = { - Logical = 0, - Physical32 = 1, - Physical64 = 2, - }, - - MemoryModel = { - Simple = 0, - GLSL450 = 1, - OpenCL = 2, - }, - - ExecutionMode = { - Invocations = 0, - SpacingEqual = 1, - SpacingFractionalEven = 2, - SpacingFractionalOdd = 3, - VertexOrderCw = 4, - VertexOrderCcw = 5, - PixelCenterInteger = 6, - OriginUpperLeft = 7, - OriginLowerLeft = 8, - EarlyFragmentTests = 9, - PointMode = 10, - Xfb = 11, - DepthReplacing = 12, - DepthGreater = 14, - DepthLess = 15, - DepthUnchanged = 16, - LocalSize = 17, - LocalSizeHint = 18, - InputPoints = 19, - InputLines = 20, - InputLinesAdjacency = 21, - Triangles = 22, - InputTrianglesAdjacency = 23, - Quads = 24, - Isolines = 25, - OutputVertices = 26, - OutputPoints = 27, - OutputLineStrip = 28, - OutputTriangleStrip = 29, - VecTypeHint = 30, - ContractionOff = 31, - Initializer = 33, - Finalizer = 34, - SubgroupSize = 35, - SubgroupsPerWorkgroup = 36, - }, - - StorageClass = { - UniformConstant = 0, - Input = 1, - Uniform = 2, - Output = 3, - Workgroup = 4, - CrossWorkgroup = 5, - Private = 6, - Function = 7, - Generic = 8, - PushConstant = 9, - AtomicCounter = 10, - Image = 11, - }, - - Dim = { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - Cube = 3, - Rect = 4, - Buffer = 5, - SubpassData = 6, - }, - - SamplerAddressingMode = { - None = 0, - ClampToEdge = 1, - Clamp = 2, - Repeat = 3, - RepeatMirrored = 4, - }, - - SamplerFilterMode = { - Nearest = 0, - Linear = 1, - }, - - ImageFormat = { - Unknown = 0, - Rgba32f = 1, - Rgba16f = 2, - R32f = 3, - Rgba8 = 4, - Rgba8Snorm = 5, - Rg32f = 6, - Rg16f = 7, - R11fG11fB10f = 8, - R16f = 9, - Rgba16 = 10, - Rgb10A2 = 11, - Rg16 = 12, - Rg8 = 13, - R16 = 14, - R8 = 15, - Rgba16Snorm = 16, - Rg16Snorm = 17, - Rg8Snorm = 18, - R16Snorm = 19, - R8Snorm = 20, - Rgba32i = 21, - Rgba16i = 22, - Rgba8i = 23, - R32i = 24, - Rg32i = 25, - Rg16i = 26, - Rg8i = 27, - R16i = 28, - R8i = 29, - Rgba32ui = 30, - Rgba16ui = 31, - Rgba8ui = 32, - R32ui = 33, - Rgb10a2ui = 34, - Rg32ui = 35, - Rg16ui = 36, - Rg8ui = 37, - R16ui = 38, - R8ui = 39, - }, - - ImageChannelOrder = { - R = 0, - A = 1, - RG = 2, - RA = 3, - RGB = 4, - RGBA = 5, - BGRA = 6, - ARGB = 7, - Intensity = 8, - Luminance = 9, - Rx = 10, - RGx = 11, - RGBx = 12, - Depth = 13, - DepthStencil = 14, - sRGB = 15, - sRGBx = 16, - sRGBA = 17, - sBGRA = 18, - ABGR = 19, - }, - - ImageChannelDataType = { - SnormInt8 = 0, - SnormInt16 = 1, - UnormInt8 = 2, - UnormInt16 = 3, - UnormShort565 = 4, - UnormShort555 = 5, - UnormInt101010 = 6, - SignedInt8 = 7, - SignedInt16 = 8, - SignedInt32 = 9, - UnsignedInt8 = 10, - UnsignedInt16 = 11, - UnsignedInt32 = 12, - HalfFloat = 13, - Float = 14, - UnormInt24 = 15, - UnormInt101010_2 = 16, - }, - - ImageOperandsShift = { - Bias = 0, - Lod = 1, - Grad = 2, - ConstOffset = 3, - Offset = 4, - ConstOffsets = 5, - Sample = 6, - MinLod = 7, - }, - - ImageOperandsMask = { - MaskNone = 0, - Bias = 0x00000001, - Lod = 0x00000002, - Grad = 0x00000004, - ConstOffset = 0x00000008, - Offset = 0x00000010, - ConstOffsets = 0x00000020, - Sample = 0x00000040, - MinLod = 0x00000080, - }, - - FPFastMathModeShift = { - NotNaN = 0, - NotInf = 1, - NSZ = 2, - AllowRecip = 3, - Fast = 4, - }, - - FPFastMathModeMask = { - MaskNone = 0, - NotNaN = 0x00000001, - NotInf = 0x00000002, - NSZ = 0x00000004, - AllowRecip = 0x00000008, - Fast = 0x00000010, - }, - - FPRoundingMode = { - RTE = 0, - RTZ = 1, - RTP = 2, - RTN = 3, - }, - - LinkageType = { - Export = 0, - Import = 1, - }, - - AccessQualifier = { - ReadOnly = 0, - WriteOnly = 1, - ReadWrite = 2, - }, - - FunctionParameterAttribute = { - Zext = 0, - Sext = 1, - ByVal = 2, - Sret = 3, - NoAlias = 4, - NoCapture = 5, - NoWrite = 6, - NoReadWrite = 7, - }, - - Decoration = { - RelaxedPrecision = 0, - SpecId = 1, - Block = 2, - BufferBlock = 3, - RowMajor = 4, - ColMajor = 5, - ArrayStride = 6, - MatrixStride = 7, - GLSLShared = 8, - GLSLPacked = 9, - CPacked = 10, - BuiltIn = 11, - NoPerspective = 13, - Flat = 14, - Patch = 15, - Centroid = 16, - Sample = 17, - Invariant = 18, - Restrict = 19, - Aliased = 20, - Volatile = 21, - Constant = 22, - Coherent = 23, - NonWritable = 24, - NonReadable = 25, - Uniform = 26, - SaturatedConversion = 28, - Stream = 29, - Location = 30, - Component = 31, - Index = 32, - Binding = 33, - DescriptorSet = 34, - Offset = 35, - XfbBuffer = 36, - XfbStride = 37, - FuncParamAttr = 38, - FPRoundingMode = 39, - FPFastMathMode = 40, - LinkageAttributes = 41, - NoContraction = 42, - InputAttachmentIndex = 43, - Alignment = 44, - MaxByteOffset = 45, - OverrideCoverageNV = 5248, - PassthroughNV = 5250, - ViewportRelativeNV = 5252, - SecondaryViewportRelativeNV = 5256, - }, - - BuiltIn = { - Position = 0, - PointSize = 1, - ClipDistance = 3, - CullDistance = 4, - VertexId = 5, - InstanceId = 6, - PrimitiveId = 7, - InvocationId = 8, - Layer = 9, - ViewportIndex = 10, - TessLevelOuter = 11, - TessLevelInner = 12, - TessCoord = 13, - PatchVertices = 14, - FragCoord = 15, - PointCoord = 16, - FrontFacing = 17, - SampleId = 18, - SamplePosition = 19, - SampleMask = 20, - FragDepth = 22, - HelperInvocation = 23, - NumWorkgroups = 24, - WorkgroupSize = 25, - WorkgroupId = 26, - LocalInvocationId = 27, - GlobalInvocationId = 28, - LocalInvocationIndex = 29, - WorkDim = 30, - GlobalSize = 31, - EnqueuedWorkgroupSize = 32, - GlobalOffset = 33, - GlobalLinearId = 34, - SubgroupSize = 36, - SubgroupMaxSize = 37, - NumSubgroups = 38, - NumEnqueuedSubgroups = 39, - SubgroupId = 40, - SubgroupLocalInvocationId = 41, - VertexIndex = 42, - InstanceIndex = 43, - SubgroupEqMaskKHR = 4416, - SubgroupGeMaskKHR = 4417, - SubgroupGtMaskKHR = 4418, - SubgroupLeMaskKHR = 4419, - SubgroupLtMaskKHR = 4420, - BaseVertex = 4424, - BaseInstance = 4425, - DrawIndex = 4426, - DeviceIndex = 4438, - ViewIndex = 4440, - ViewportMaskNV = 5253, - SecondaryPositionNV = 5257, - SecondaryViewportMaskNV = 5258, - PositionPerViewNV = 5261, - ViewportMaskPerViewNV = 5262, - }, - - SelectionControlShift = { - Flatten = 0, - DontFlatten = 1, - }, - - SelectionControlMask = { - MaskNone = 0, - Flatten = 0x00000001, - DontFlatten = 0x00000002, - }, - - LoopControlShift = { - Unroll = 0, - DontUnroll = 1, - DependencyInfinite = 2, - DependencyLength = 3, - }, - - LoopControlMask = { - MaskNone = 0, - Unroll = 0x00000001, - DontUnroll = 0x00000002, - DependencyInfinite = 0x00000004, - DependencyLength = 0x00000008, - }, - - FunctionControlShift = { - Inline = 0, - DontInline = 1, - Pure = 2, - Const = 3, - }, - - FunctionControlMask = { - MaskNone = 0, - Inline = 0x00000001, - DontInline = 0x00000002, - Pure = 0x00000004, - Const = 0x00000008, - }, - - MemorySemanticsShift = { - Acquire = 1, - Release = 2, - AcquireRelease = 3, - SequentiallyConsistent = 4, - UniformMemory = 6, - SubgroupMemory = 7, - WorkgroupMemory = 8, - CrossWorkgroupMemory = 9, - AtomicCounterMemory = 10, - ImageMemory = 11, - }, - - MemorySemanticsMask = { - MaskNone = 0, - Acquire = 0x00000002, - Release = 0x00000004, - AcquireRelease = 0x00000008, - SequentiallyConsistent = 0x00000010, - UniformMemory = 0x00000040, - SubgroupMemory = 0x00000080, - WorkgroupMemory = 0x00000100, - CrossWorkgroupMemory = 0x00000200, - AtomicCounterMemory = 0x00000400, - ImageMemory = 0x00000800, - }, - - MemoryAccessShift = { - Volatile = 0, - Aligned = 1, - Nontemporal = 2, - }, - - MemoryAccessMask = { - MaskNone = 0, - Volatile = 0x00000001, - Aligned = 0x00000002, - Nontemporal = 0x00000004, - }, - - Scope = { - CrossDevice = 0, - Device = 1, - Workgroup = 2, - Subgroup = 3, - Invocation = 4, - }, - - GroupOperation = { - Reduce = 0, - InclusiveScan = 1, - ExclusiveScan = 2, - }, - - KernelEnqueueFlags = { - NoWait = 0, - WaitKernel = 1, - WaitWorkGroup = 2, - }, - - KernelProfilingInfoShift = { - CmdExecTime = 0, - }, - - KernelProfilingInfoMask = { - MaskNone = 0, - CmdExecTime = 0x00000001, - }, - - Capability = { - Matrix = 0, - Shader = 1, - Geometry = 2, - Tessellation = 3, - Addresses = 4, - Linkage = 5, - Kernel = 6, - Vector16 = 7, - Float16Buffer = 8, - Float16 = 9, - Float64 = 10, - Int64 = 11, - Int64Atomics = 12, - ImageBasic = 13, - ImageReadWrite = 14, - ImageMipmap = 15, - Pipes = 17, - Groups = 18, - DeviceEnqueue = 19, - LiteralSampler = 20, - AtomicStorage = 21, - Int16 = 22, - TessellationPointSize = 23, - GeometryPointSize = 24, - ImageGatherExtended = 25, - StorageImageMultisample = 27, - UniformBufferArrayDynamicIndexing = 28, - SampledImageArrayDynamicIndexing = 29, - StorageBufferArrayDynamicIndexing = 30, - StorageImageArrayDynamicIndexing = 31, - ClipDistance = 32, - CullDistance = 33, - ImageCubeArray = 34, - SampleRateShading = 35, - ImageRect = 36, - SampledRect = 37, - GenericPointer = 38, - Int8 = 39, - InputAttachment = 40, - SparseResidency = 41, - MinLod = 42, - Sampled1D = 43, - Image1D = 44, - SampledCubeArray = 45, - SampledBuffer = 46, - ImageBuffer = 47, - ImageMSArray = 48, - StorageImageExtendedFormats = 49, - ImageQuery = 50, - DerivativeControl = 51, - InterpolationFunction = 52, - TransformFeedback = 53, - GeometryStreams = 54, - StorageImageReadWithoutFormat = 55, - StorageImageWriteWithoutFormat = 56, - MultiViewport = 57, - SubgroupDispatch = 58, - NamedBarrier = 59, - PipeStorage = 60, - SubgroupBallotKHR = 4423, - DrawParameters = 4427, - SubgroupVoteKHR = 4431, - StorageUniformBufferBlock16 = 4433, - StorageUniform16 = 4434, - StoragePushConstant16 = 4435, - StorageInputOutput16 = 4436, - DeviceGroup = 4437, - MultiView = 4439, - SampleMaskOverrideCoverageNV = 5249, - GeometryShaderPassthroughNV = 5251, - ShaderViewportIndexLayerNV = 5254, - ShaderViewportMaskNV = 5255, - ShaderStereoViewNV = 5259, - PerViewAttributesNV = 5260, - }, - - Op = { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - }, - -} - +-- Copyright (c) 2014-2017 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: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of 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. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- 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. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010100, + Revision = 8, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + }, + +} + diff --git a/ext/vulkan/spirv.py b/ext/vulkan/spirv.py index d0bce4d169..d7d900cb1d 100644 --- a/ext/vulkan/spirv.py +++ b/ext/vulkan/spirv.py @@ -1,921 +1,966 @@ -# Copyright (c) 2014-2017 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: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of 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. - -# This header is automatically generated by the same tool that creates -# the Binary Section of the SPIR-V specification. - -# Enumeration tokens for SPIR-V, in various styles: -# C, C++, C++11, JSON, Lua, Python -# -# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -# -# 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. - -spv = { - 'MagicNumber' : 0x07230203, - 'Version' : 0x00010100, - 'Revision' : 6, - 'OpCodeMask' : 0xffff, - 'WordCountShift' : 16, - - 'SourceLanguage' : { - 'Unknown' : 0, - 'ESSL' : 1, - 'GLSL' : 2, - 'OpenCL_C' : 3, - 'OpenCL_CPP' : 4, - }, - - 'ExecutionModel' : { - 'Vertex' : 0, - 'TessellationControl' : 1, - 'TessellationEvaluation' : 2, - 'Geometry' : 3, - 'Fragment' : 4, - 'GLCompute' : 5, - 'Kernel' : 6, - }, - - 'AddressingModel' : { - 'Logical' : 0, - 'Physical32' : 1, - 'Physical64' : 2, - }, - - 'MemoryModel' : { - 'Simple' : 0, - 'GLSL450' : 1, - 'OpenCL' : 2, - }, - - 'ExecutionMode' : { - 'Invocations' : 0, - 'SpacingEqual' : 1, - 'SpacingFractionalEven' : 2, - 'SpacingFractionalOdd' : 3, - 'VertexOrderCw' : 4, - 'VertexOrderCcw' : 5, - 'PixelCenterInteger' : 6, - 'OriginUpperLeft' : 7, - 'OriginLowerLeft' : 8, - 'EarlyFragmentTests' : 9, - 'PointMode' : 10, - 'Xfb' : 11, - 'DepthReplacing' : 12, - 'DepthGreater' : 14, - 'DepthLess' : 15, - 'DepthUnchanged' : 16, - 'LocalSize' : 17, - 'LocalSizeHint' : 18, - 'InputPoints' : 19, - 'InputLines' : 20, - 'InputLinesAdjacency' : 21, - 'Triangles' : 22, - 'InputTrianglesAdjacency' : 23, - 'Quads' : 24, - 'Isolines' : 25, - 'OutputVertices' : 26, - 'OutputPoints' : 27, - 'OutputLineStrip' : 28, - 'OutputTriangleStrip' : 29, - 'VecTypeHint' : 30, - 'ContractionOff' : 31, - 'Initializer' : 33, - 'Finalizer' : 34, - 'SubgroupSize' : 35, - 'SubgroupsPerWorkgroup' : 36, - }, - - 'StorageClass' : { - 'UniformConstant' : 0, - 'Input' : 1, - 'Uniform' : 2, - 'Output' : 3, - 'Workgroup' : 4, - 'CrossWorkgroup' : 5, - 'Private' : 6, - 'Function' : 7, - 'Generic' : 8, - 'PushConstant' : 9, - 'AtomicCounter' : 10, - 'Image' : 11, - }, - - 'Dim' : { - 'Dim1D' : 0, - 'Dim2D' : 1, - 'Dim3D' : 2, - 'Cube' : 3, - 'Rect' : 4, - 'Buffer' : 5, - 'SubpassData' : 6, - }, - - 'SamplerAddressingMode' : { - 'None' : 0, - 'ClampToEdge' : 1, - 'Clamp' : 2, - 'Repeat' : 3, - 'RepeatMirrored' : 4, - }, - - 'SamplerFilterMode' : { - 'Nearest' : 0, - 'Linear' : 1, - }, - - 'ImageFormat' : { - 'Unknown' : 0, - 'Rgba32f' : 1, - 'Rgba16f' : 2, - 'R32f' : 3, - 'Rgba8' : 4, - 'Rgba8Snorm' : 5, - 'Rg32f' : 6, - 'Rg16f' : 7, - 'R11fG11fB10f' : 8, - 'R16f' : 9, - 'Rgba16' : 10, - 'Rgb10A2' : 11, - 'Rg16' : 12, - 'Rg8' : 13, - 'R16' : 14, - 'R8' : 15, - 'Rgba16Snorm' : 16, - 'Rg16Snorm' : 17, - 'Rg8Snorm' : 18, - 'R16Snorm' : 19, - 'R8Snorm' : 20, - 'Rgba32i' : 21, - 'Rgba16i' : 22, - 'Rgba8i' : 23, - 'R32i' : 24, - 'Rg32i' : 25, - 'Rg16i' : 26, - 'Rg8i' : 27, - 'R16i' : 28, - 'R8i' : 29, - 'Rgba32ui' : 30, - 'Rgba16ui' : 31, - 'Rgba8ui' : 32, - 'R32ui' : 33, - 'Rgb10a2ui' : 34, - 'Rg32ui' : 35, - 'Rg16ui' : 36, - 'Rg8ui' : 37, - 'R16ui' : 38, - 'R8ui' : 39, - }, - - 'ImageChannelOrder' : { - 'R' : 0, - 'A' : 1, - 'RG' : 2, - 'RA' : 3, - 'RGB' : 4, - 'RGBA' : 5, - 'BGRA' : 6, - 'ARGB' : 7, - 'Intensity' : 8, - 'Luminance' : 9, - 'Rx' : 10, - 'RGx' : 11, - 'RGBx' : 12, - 'Depth' : 13, - 'DepthStencil' : 14, - 'sRGB' : 15, - 'sRGBx' : 16, - 'sRGBA' : 17, - 'sBGRA' : 18, - 'ABGR' : 19, - }, - - 'ImageChannelDataType' : { - 'SnormInt8' : 0, - 'SnormInt16' : 1, - 'UnormInt8' : 2, - 'UnormInt16' : 3, - 'UnormShort565' : 4, - 'UnormShort555' : 5, - 'UnormInt101010' : 6, - 'SignedInt8' : 7, - 'SignedInt16' : 8, - 'SignedInt32' : 9, - 'UnsignedInt8' : 10, - 'UnsignedInt16' : 11, - 'UnsignedInt32' : 12, - 'HalfFloat' : 13, - 'Float' : 14, - 'UnormInt24' : 15, - 'UnormInt101010_2' : 16, - }, - - 'ImageOperandsShift' : { - 'Bias' : 0, - 'Lod' : 1, - 'Grad' : 2, - 'ConstOffset' : 3, - 'Offset' : 4, - 'ConstOffsets' : 5, - 'Sample' : 6, - 'MinLod' : 7, - }, - - 'ImageOperandsMask' : { - 'MaskNone' : 0, - 'Bias' : 0x00000001, - 'Lod' : 0x00000002, - 'Grad' : 0x00000004, - 'ConstOffset' : 0x00000008, - 'Offset' : 0x00000010, - 'ConstOffsets' : 0x00000020, - 'Sample' : 0x00000040, - 'MinLod' : 0x00000080, - }, - - 'FPFastMathModeShift' : { - 'NotNaN' : 0, - 'NotInf' : 1, - 'NSZ' : 2, - 'AllowRecip' : 3, - 'Fast' : 4, - }, - - 'FPFastMathModeMask' : { - 'MaskNone' : 0, - 'NotNaN' : 0x00000001, - 'NotInf' : 0x00000002, - 'NSZ' : 0x00000004, - 'AllowRecip' : 0x00000008, - 'Fast' : 0x00000010, - }, - - 'FPRoundingMode' : { - 'RTE' : 0, - 'RTZ' : 1, - 'RTP' : 2, - 'RTN' : 3, - }, - - 'LinkageType' : { - 'Export' : 0, - 'Import' : 1, - }, - - 'AccessQualifier' : { - 'ReadOnly' : 0, - 'WriteOnly' : 1, - 'ReadWrite' : 2, - }, - - 'FunctionParameterAttribute' : { - 'Zext' : 0, - 'Sext' : 1, - 'ByVal' : 2, - 'Sret' : 3, - 'NoAlias' : 4, - 'NoCapture' : 5, - 'NoWrite' : 6, - 'NoReadWrite' : 7, - }, - - 'Decoration' : { - 'RelaxedPrecision' : 0, - 'SpecId' : 1, - 'Block' : 2, - 'BufferBlock' : 3, - 'RowMajor' : 4, - 'ColMajor' : 5, - 'ArrayStride' : 6, - 'MatrixStride' : 7, - 'GLSLShared' : 8, - 'GLSLPacked' : 9, - 'CPacked' : 10, - 'BuiltIn' : 11, - 'NoPerspective' : 13, - 'Flat' : 14, - 'Patch' : 15, - 'Centroid' : 16, - 'Sample' : 17, - 'Invariant' : 18, - 'Restrict' : 19, - 'Aliased' : 20, - 'Volatile' : 21, - 'Constant' : 22, - 'Coherent' : 23, - 'NonWritable' : 24, - 'NonReadable' : 25, - 'Uniform' : 26, - 'SaturatedConversion' : 28, - 'Stream' : 29, - 'Location' : 30, - 'Component' : 31, - 'Index' : 32, - 'Binding' : 33, - 'DescriptorSet' : 34, - 'Offset' : 35, - 'XfbBuffer' : 36, - 'XfbStride' : 37, - 'FuncParamAttr' : 38, - 'FPRoundingMode' : 39, - 'FPFastMathMode' : 40, - 'LinkageAttributes' : 41, - 'NoContraction' : 42, - 'InputAttachmentIndex' : 43, - 'Alignment' : 44, - 'MaxByteOffset' : 45, - 'OverrideCoverageNV' : 5248, - 'PassthroughNV' : 5250, - 'ViewportRelativeNV' : 5252, - 'SecondaryViewportRelativeNV' : 5256, - }, - - 'BuiltIn' : { - 'Position' : 0, - 'PointSize' : 1, - 'ClipDistance' : 3, - 'CullDistance' : 4, - 'VertexId' : 5, - 'InstanceId' : 6, - 'PrimitiveId' : 7, - 'InvocationId' : 8, - 'Layer' : 9, - 'ViewportIndex' : 10, - 'TessLevelOuter' : 11, - 'TessLevelInner' : 12, - 'TessCoord' : 13, - 'PatchVertices' : 14, - 'FragCoord' : 15, - 'PointCoord' : 16, - 'FrontFacing' : 17, - 'SampleId' : 18, - 'SamplePosition' : 19, - 'SampleMask' : 20, - 'FragDepth' : 22, - 'HelperInvocation' : 23, - 'NumWorkgroups' : 24, - 'WorkgroupSize' : 25, - 'WorkgroupId' : 26, - 'LocalInvocationId' : 27, - 'GlobalInvocationId' : 28, - 'LocalInvocationIndex' : 29, - 'WorkDim' : 30, - 'GlobalSize' : 31, - 'EnqueuedWorkgroupSize' : 32, - 'GlobalOffset' : 33, - 'GlobalLinearId' : 34, - 'SubgroupSize' : 36, - 'SubgroupMaxSize' : 37, - 'NumSubgroups' : 38, - 'NumEnqueuedSubgroups' : 39, - 'SubgroupId' : 40, - 'SubgroupLocalInvocationId' : 41, - 'VertexIndex' : 42, - 'InstanceIndex' : 43, - 'SubgroupEqMaskKHR' : 4416, - 'SubgroupGeMaskKHR' : 4417, - 'SubgroupGtMaskKHR' : 4418, - 'SubgroupLeMaskKHR' : 4419, - 'SubgroupLtMaskKHR' : 4420, - 'BaseVertex' : 4424, - 'BaseInstance' : 4425, - 'DrawIndex' : 4426, - 'DeviceIndex' : 4438, - 'ViewIndex' : 4440, - 'ViewportMaskNV' : 5253, - 'SecondaryPositionNV' : 5257, - 'SecondaryViewportMaskNV' : 5258, - 'PositionPerViewNV' : 5261, - 'ViewportMaskPerViewNV' : 5262, - }, - - 'SelectionControlShift' : { - 'Flatten' : 0, - 'DontFlatten' : 1, - }, - - 'SelectionControlMask' : { - 'MaskNone' : 0, - 'Flatten' : 0x00000001, - 'DontFlatten' : 0x00000002, - }, - - 'LoopControlShift' : { - 'Unroll' : 0, - 'DontUnroll' : 1, - 'DependencyInfinite' : 2, - 'DependencyLength' : 3, - }, - - 'LoopControlMask' : { - 'MaskNone' : 0, - 'Unroll' : 0x00000001, - 'DontUnroll' : 0x00000002, - 'DependencyInfinite' : 0x00000004, - 'DependencyLength' : 0x00000008, - }, - - 'FunctionControlShift' : { - 'Inline' : 0, - 'DontInline' : 1, - 'Pure' : 2, - 'Const' : 3, - }, - - 'FunctionControlMask' : { - 'MaskNone' : 0, - 'Inline' : 0x00000001, - 'DontInline' : 0x00000002, - 'Pure' : 0x00000004, - 'Const' : 0x00000008, - }, - - 'MemorySemanticsShift' : { - 'Acquire' : 1, - 'Release' : 2, - 'AcquireRelease' : 3, - 'SequentiallyConsistent' : 4, - 'UniformMemory' : 6, - 'SubgroupMemory' : 7, - 'WorkgroupMemory' : 8, - 'CrossWorkgroupMemory' : 9, - 'AtomicCounterMemory' : 10, - 'ImageMemory' : 11, - }, - - 'MemorySemanticsMask' : { - 'MaskNone' : 0, - 'Acquire' : 0x00000002, - 'Release' : 0x00000004, - 'AcquireRelease' : 0x00000008, - 'SequentiallyConsistent' : 0x00000010, - 'UniformMemory' : 0x00000040, - 'SubgroupMemory' : 0x00000080, - 'WorkgroupMemory' : 0x00000100, - 'CrossWorkgroupMemory' : 0x00000200, - 'AtomicCounterMemory' : 0x00000400, - 'ImageMemory' : 0x00000800, - }, - - 'MemoryAccessShift' : { - 'Volatile' : 0, - 'Aligned' : 1, - 'Nontemporal' : 2, - }, - - 'MemoryAccessMask' : { - 'MaskNone' : 0, - 'Volatile' : 0x00000001, - 'Aligned' : 0x00000002, - 'Nontemporal' : 0x00000004, - }, - - 'Scope' : { - 'CrossDevice' : 0, - 'Device' : 1, - 'Workgroup' : 2, - 'Subgroup' : 3, - 'Invocation' : 4, - }, - - 'GroupOperation' : { - 'Reduce' : 0, - 'InclusiveScan' : 1, - 'ExclusiveScan' : 2, - }, - - 'KernelEnqueueFlags' : { - 'NoWait' : 0, - 'WaitKernel' : 1, - 'WaitWorkGroup' : 2, - }, - - 'KernelProfilingInfoShift' : { - 'CmdExecTime' : 0, - }, - - 'KernelProfilingInfoMask' : { - 'MaskNone' : 0, - 'CmdExecTime' : 0x00000001, - }, - - 'Capability' : { - 'Matrix' : 0, - 'Shader' : 1, - 'Geometry' : 2, - 'Tessellation' : 3, - 'Addresses' : 4, - 'Linkage' : 5, - 'Kernel' : 6, - 'Vector16' : 7, - 'Float16Buffer' : 8, - 'Float16' : 9, - 'Float64' : 10, - 'Int64' : 11, - 'Int64Atomics' : 12, - 'ImageBasic' : 13, - 'ImageReadWrite' : 14, - 'ImageMipmap' : 15, - 'Pipes' : 17, - 'Groups' : 18, - 'DeviceEnqueue' : 19, - 'LiteralSampler' : 20, - 'AtomicStorage' : 21, - 'Int16' : 22, - 'TessellationPointSize' : 23, - 'GeometryPointSize' : 24, - 'ImageGatherExtended' : 25, - 'StorageImageMultisample' : 27, - 'UniformBufferArrayDynamicIndexing' : 28, - 'SampledImageArrayDynamicIndexing' : 29, - 'StorageBufferArrayDynamicIndexing' : 30, - 'StorageImageArrayDynamicIndexing' : 31, - 'ClipDistance' : 32, - 'CullDistance' : 33, - 'ImageCubeArray' : 34, - 'SampleRateShading' : 35, - 'ImageRect' : 36, - 'SampledRect' : 37, - 'GenericPointer' : 38, - 'Int8' : 39, - 'InputAttachment' : 40, - 'SparseResidency' : 41, - 'MinLod' : 42, - 'Sampled1D' : 43, - 'Image1D' : 44, - 'SampledCubeArray' : 45, - 'SampledBuffer' : 46, - 'ImageBuffer' : 47, - 'ImageMSArray' : 48, - 'StorageImageExtendedFormats' : 49, - 'ImageQuery' : 50, - 'DerivativeControl' : 51, - 'InterpolationFunction' : 52, - 'TransformFeedback' : 53, - 'GeometryStreams' : 54, - 'StorageImageReadWithoutFormat' : 55, - 'StorageImageWriteWithoutFormat' : 56, - 'MultiViewport' : 57, - 'SubgroupDispatch' : 58, - 'NamedBarrier' : 59, - 'PipeStorage' : 60, - 'SubgroupBallotKHR' : 4423, - 'DrawParameters' : 4427, - 'SubgroupVoteKHR' : 4431, - 'StorageUniformBufferBlock16' : 4433, - 'StorageUniform16' : 4434, - 'StoragePushConstant16' : 4435, - 'StorageInputOutput16' : 4436, - 'DeviceGroup' : 4437, - 'MultiView' : 4439, - 'SampleMaskOverrideCoverageNV' : 5249, - 'GeometryShaderPassthroughNV' : 5251, - 'ShaderViewportIndexLayerNV' : 5254, - 'ShaderViewportMaskNV' : 5255, - 'ShaderStereoViewNV' : 5259, - 'PerViewAttributesNV' : 5260, - }, - - 'Op' : { - 'OpNop' : 0, - 'OpUndef' : 1, - 'OpSourceContinued' : 2, - 'OpSource' : 3, - 'OpSourceExtension' : 4, - 'OpName' : 5, - 'OpMemberName' : 6, - 'OpString' : 7, - 'OpLine' : 8, - 'OpExtension' : 10, - 'OpExtInstImport' : 11, - 'OpExtInst' : 12, - 'OpMemoryModel' : 14, - 'OpEntryPoint' : 15, - 'OpExecutionMode' : 16, - 'OpCapability' : 17, - 'OpTypeVoid' : 19, - 'OpTypeBool' : 20, - 'OpTypeInt' : 21, - 'OpTypeFloat' : 22, - 'OpTypeVector' : 23, - 'OpTypeMatrix' : 24, - 'OpTypeImage' : 25, - 'OpTypeSampler' : 26, - 'OpTypeSampledImage' : 27, - 'OpTypeArray' : 28, - 'OpTypeRuntimeArray' : 29, - 'OpTypeStruct' : 30, - 'OpTypeOpaque' : 31, - 'OpTypePointer' : 32, - 'OpTypeFunction' : 33, - 'OpTypeEvent' : 34, - 'OpTypeDeviceEvent' : 35, - 'OpTypeReserveId' : 36, - 'OpTypeQueue' : 37, - 'OpTypePipe' : 38, - 'OpTypeForwardPointer' : 39, - 'OpConstantTrue' : 41, - 'OpConstantFalse' : 42, - 'OpConstant' : 43, - 'OpConstantComposite' : 44, - 'OpConstantSampler' : 45, - 'OpConstantNull' : 46, - 'OpSpecConstantTrue' : 48, - 'OpSpecConstantFalse' : 49, - 'OpSpecConstant' : 50, - 'OpSpecConstantComposite' : 51, - 'OpSpecConstantOp' : 52, - 'OpFunction' : 54, - 'OpFunctionParameter' : 55, - 'OpFunctionEnd' : 56, - 'OpFunctionCall' : 57, - 'OpVariable' : 59, - 'OpImageTexelPointer' : 60, - 'OpLoad' : 61, - 'OpStore' : 62, - 'OpCopyMemory' : 63, - 'OpCopyMemorySized' : 64, - 'OpAccessChain' : 65, - 'OpInBoundsAccessChain' : 66, - 'OpPtrAccessChain' : 67, - 'OpArrayLength' : 68, - 'OpGenericPtrMemSemantics' : 69, - 'OpInBoundsPtrAccessChain' : 70, - 'OpDecorate' : 71, - 'OpMemberDecorate' : 72, - 'OpDecorationGroup' : 73, - 'OpGroupDecorate' : 74, - 'OpGroupMemberDecorate' : 75, - 'OpVectorExtractDynamic' : 77, - 'OpVectorInsertDynamic' : 78, - 'OpVectorShuffle' : 79, - 'OpCompositeConstruct' : 80, - 'OpCompositeExtract' : 81, - 'OpCompositeInsert' : 82, - 'OpCopyObject' : 83, - 'OpTranspose' : 84, - 'OpSampledImage' : 86, - 'OpImageSampleImplicitLod' : 87, - 'OpImageSampleExplicitLod' : 88, - 'OpImageSampleDrefImplicitLod' : 89, - 'OpImageSampleDrefExplicitLod' : 90, - 'OpImageSampleProjImplicitLod' : 91, - 'OpImageSampleProjExplicitLod' : 92, - 'OpImageSampleProjDrefImplicitLod' : 93, - 'OpImageSampleProjDrefExplicitLod' : 94, - 'OpImageFetch' : 95, - 'OpImageGather' : 96, - 'OpImageDrefGather' : 97, - 'OpImageRead' : 98, - 'OpImageWrite' : 99, - 'OpImage' : 100, - 'OpImageQueryFormat' : 101, - 'OpImageQueryOrder' : 102, - 'OpImageQuerySizeLod' : 103, - 'OpImageQuerySize' : 104, - 'OpImageQueryLod' : 105, - 'OpImageQueryLevels' : 106, - 'OpImageQuerySamples' : 107, - 'OpConvertFToU' : 109, - 'OpConvertFToS' : 110, - 'OpConvertSToF' : 111, - 'OpConvertUToF' : 112, - 'OpUConvert' : 113, - 'OpSConvert' : 114, - 'OpFConvert' : 115, - 'OpQuantizeToF16' : 116, - 'OpConvertPtrToU' : 117, - 'OpSatConvertSToU' : 118, - 'OpSatConvertUToS' : 119, - 'OpConvertUToPtr' : 120, - 'OpPtrCastToGeneric' : 121, - 'OpGenericCastToPtr' : 122, - 'OpGenericCastToPtrExplicit' : 123, - 'OpBitcast' : 124, - 'OpSNegate' : 126, - 'OpFNegate' : 127, - 'OpIAdd' : 128, - 'OpFAdd' : 129, - 'OpISub' : 130, - 'OpFSub' : 131, - 'OpIMul' : 132, - 'OpFMul' : 133, - 'OpUDiv' : 134, - 'OpSDiv' : 135, - 'OpFDiv' : 136, - 'OpUMod' : 137, - 'OpSRem' : 138, - 'OpSMod' : 139, - 'OpFRem' : 140, - 'OpFMod' : 141, - 'OpVectorTimesScalar' : 142, - 'OpMatrixTimesScalar' : 143, - 'OpVectorTimesMatrix' : 144, - 'OpMatrixTimesVector' : 145, - 'OpMatrixTimesMatrix' : 146, - 'OpOuterProduct' : 147, - 'OpDot' : 148, - 'OpIAddCarry' : 149, - 'OpISubBorrow' : 150, - 'OpUMulExtended' : 151, - 'OpSMulExtended' : 152, - 'OpAny' : 154, - 'OpAll' : 155, - 'OpIsNan' : 156, - 'OpIsInf' : 157, - 'OpIsFinite' : 158, - 'OpIsNormal' : 159, - 'OpSignBitSet' : 160, - 'OpLessOrGreater' : 161, - 'OpOrdered' : 162, - 'OpUnordered' : 163, - 'OpLogicalEqual' : 164, - 'OpLogicalNotEqual' : 165, - 'OpLogicalOr' : 166, - 'OpLogicalAnd' : 167, - 'OpLogicalNot' : 168, - 'OpSelect' : 169, - 'OpIEqual' : 170, - 'OpINotEqual' : 171, - 'OpUGreaterThan' : 172, - 'OpSGreaterThan' : 173, - 'OpUGreaterThanEqual' : 174, - 'OpSGreaterThanEqual' : 175, - 'OpULessThan' : 176, - 'OpSLessThan' : 177, - 'OpULessThanEqual' : 178, - 'OpSLessThanEqual' : 179, - 'OpFOrdEqual' : 180, - 'OpFUnordEqual' : 181, - 'OpFOrdNotEqual' : 182, - 'OpFUnordNotEqual' : 183, - 'OpFOrdLessThan' : 184, - 'OpFUnordLessThan' : 185, - 'OpFOrdGreaterThan' : 186, - 'OpFUnordGreaterThan' : 187, - 'OpFOrdLessThanEqual' : 188, - 'OpFUnordLessThanEqual' : 189, - 'OpFOrdGreaterThanEqual' : 190, - 'OpFUnordGreaterThanEqual' : 191, - 'OpShiftRightLogical' : 194, - 'OpShiftRightArithmetic' : 195, - 'OpShiftLeftLogical' : 196, - 'OpBitwiseOr' : 197, - 'OpBitwiseXor' : 198, - 'OpBitwiseAnd' : 199, - 'OpNot' : 200, - 'OpBitFieldInsert' : 201, - 'OpBitFieldSExtract' : 202, - 'OpBitFieldUExtract' : 203, - 'OpBitReverse' : 204, - 'OpBitCount' : 205, - 'OpDPdx' : 207, - 'OpDPdy' : 208, - 'OpFwidth' : 209, - 'OpDPdxFine' : 210, - 'OpDPdyFine' : 211, - 'OpFwidthFine' : 212, - 'OpDPdxCoarse' : 213, - 'OpDPdyCoarse' : 214, - 'OpFwidthCoarse' : 215, - 'OpEmitVertex' : 218, - 'OpEndPrimitive' : 219, - 'OpEmitStreamVertex' : 220, - 'OpEndStreamPrimitive' : 221, - 'OpControlBarrier' : 224, - 'OpMemoryBarrier' : 225, - 'OpAtomicLoad' : 227, - 'OpAtomicStore' : 228, - 'OpAtomicExchange' : 229, - 'OpAtomicCompareExchange' : 230, - 'OpAtomicCompareExchangeWeak' : 231, - 'OpAtomicIIncrement' : 232, - 'OpAtomicIDecrement' : 233, - 'OpAtomicIAdd' : 234, - 'OpAtomicISub' : 235, - 'OpAtomicSMin' : 236, - 'OpAtomicUMin' : 237, - 'OpAtomicSMax' : 238, - 'OpAtomicUMax' : 239, - 'OpAtomicAnd' : 240, - 'OpAtomicOr' : 241, - 'OpAtomicXor' : 242, - 'OpPhi' : 245, - 'OpLoopMerge' : 246, - 'OpSelectionMerge' : 247, - 'OpLabel' : 248, - 'OpBranch' : 249, - 'OpBranchConditional' : 250, - 'OpSwitch' : 251, - 'OpKill' : 252, - 'OpReturn' : 253, - 'OpReturnValue' : 254, - 'OpUnreachable' : 255, - 'OpLifetimeStart' : 256, - 'OpLifetimeStop' : 257, - 'OpGroupAsyncCopy' : 259, - 'OpGroupWaitEvents' : 260, - 'OpGroupAll' : 261, - 'OpGroupAny' : 262, - 'OpGroupBroadcast' : 263, - 'OpGroupIAdd' : 264, - 'OpGroupFAdd' : 265, - 'OpGroupFMin' : 266, - 'OpGroupUMin' : 267, - 'OpGroupSMin' : 268, - 'OpGroupFMax' : 269, - 'OpGroupUMax' : 270, - 'OpGroupSMax' : 271, - 'OpReadPipe' : 274, - 'OpWritePipe' : 275, - 'OpReservedReadPipe' : 276, - 'OpReservedWritePipe' : 277, - 'OpReserveReadPipePackets' : 278, - 'OpReserveWritePipePackets' : 279, - 'OpCommitReadPipe' : 280, - 'OpCommitWritePipe' : 281, - 'OpIsValidReserveId' : 282, - 'OpGetNumPipePackets' : 283, - 'OpGetMaxPipePackets' : 284, - 'OpGroupReserveReadPipePackets' : 285, - 'OpGroupReserveWritePipePackets' : 286, - 'OpGroupCommitReadPipe' : 287, - 'OpGroupCommitWritePipe' : 288, - 'OpEnqueueMarker' : 291, - 'OpEnqueueKernel' : 292, - 'OpGetKernelNDrangeSubGroupCount' : 293, - 'OpGetKernelNDrangeMaxSubGroupSize' : 294, - 'OpGetKernelWorkGroupSize' : 295, - 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, - 'OpRetainEvent' : 297, - 'OpReleaseEvent' : 298, - 'OpCreateUserEvent' : 299, - 'OpIsValidEvent' : 300, - 'OpSetUserEventStatus' : 301, - 'OpCaptureEventProfilingInfo' : 302, - 'OpGetDefaultQueue' : 303, - 'OpBuildNDRange' : 304, - 'OpImageSparseSampleImplicitLod' : 305, - 'OpImageSparseSampleExplicitLod' : 306, - 'OpImageSparseSampleDrefImplicitLod' : 307, - 'OpImageSparseSampleDrefExplicitLod' : 308, - 'OpImageSparseSampleProjImplicitLod' : 309, - 'OpImageSparseSampleProjExplicitLod' : 310, - 'OpImageSparseSampleProjDrefImplicitLod' : 311, - 'OpImageSparseSampleProjDrefExplicitLod' : 312, - 'OpImageSparseFetch' : 313, - 'OpImageSparseGather' : 314, - 'OpImageSparseDrefGather' : 315, - 'OpImageSparseTexelsResident' : 316, - 'OpNoLine' : 317, - 'OpAtomicFlagTestAndSet' : 318, - 'OpAtomicFlagClear' : 319, - 'OpImageSparseRead' : 320, - 'OpSizeOf' : 321, - 'OpTypePipeStorage' : 322, - 'OpConstantPipeStorage' : 323, - 'OpCreatePipeFromPipeStorage' : 324, - 'OpGetKernelLocalSizeForSubgroupCount' : 325, - 'OpGetKernelMaxNumSubgroups' : 326, - 'OpTypeNamedBarrier' : 327, - 'OpNamedBarrierInitialize' : 328, - 'OpMemoryNamedBarrier' : 329, - 'OpModuleProcessed' : 330, - 'OpSubgroupBallotKHR' : 4421, - 'OpSubgroupFirstInvocationKHR' : 4422, - 'OpSubgroupAllKHR' : 4428, - 'OpSubgroupAnyKHR' : 4429, - 'OpSubgroupAllEqualKHR' : 4430, - 'OpSubgroupReadInvocationKHR' : 4432, - }, - -} - +# Copyright (c) 2014-2017 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: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of 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. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# 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. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010100, + 'Revision' : 8, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + }, + +} + diff --git a/ext/vulkan/vk_icd.h b/ext/vulkan/vk_icd.h index 668a4d183c..b8c7efcb6b 100644 --- a/ext/vulkan/vk_icd.h +++ b/ext/vulkan/vk_icd.h @@ -35,13 +35,19 @@ // Version 3 - Add ICD creation/destruction of KHR_surface objects. // Version 4 - Add unknown physical device extension qyering via // vk_icdGetPhysicalDeviceProcAddr. -#define CURRENT_LOADER_ICD_INTERFACE_VERSION 4 +// Version 5 - Tells ICDs that the loader is now paying attention to the +// application version of Vulkan passed into the ApplicationInfo +// structure during vkCreateInstance. This will tell the ICD +// that if the loader is older, it should automatically fail a +// call for any API version > 1.0. Otherwise, the loader will +// manually determine if it can support the expected version. +#define CURRENT_LOADER_ICD_INTERFACE_VERSION 5 #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 #define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this -// flie directly, it won't be found. +// file directly, it won't be found. #ifndef PFN_GetPhysicalDeviceProcAddr typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); #endif diff --git a/ext/vulkan/vk_layer.h b/ext/vulkan/vk_layer.h index 4a502a33bc..e8300c37d4 100644 --- a/ext/vulkan/vk_layer.h +++ b/ext/vulkan/vk_layer.h @@ -48,6 +48,8 @@ #define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2 #define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1 +#define VK_CURRENT_CHAIN_VERSION 1 + // Version negotiation values typedef enum VkNegotiateLayerStructType { LAYER_NEGOTIATE_UNINTIALIZED = 0, @@ -68,7 +70,7 @@ typedef struct VkNegotiateLayerInterface { typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct); // Function prototype for unknown physical device extension command -typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device, ...); +typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device); // ------------------------------------------------------------------------------------------------ // CreateInstance and CreateDevice support structures @@ -132,3 +134,62 @@ typedef struct { } u; } VkLayerDeviceCreateInfo; +#ifdef __cplusplus +extern "C" { +#endif + +VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct); + +typedef enum VkChainType { + VK_CHAIN_TYPE_UNKNOWN = 0, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2, + VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3, +} VkChainType; + +typedef struct VkChainHeader { + VkChainType type; + uint32_t version; + uint32_t size; +} VkChainHeader; + +typedef struct VkEnumerateInstanceExtensionPropertiesChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *, + VkExtensionProperties *); + const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const { + return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties); + } +#endif +} VkEnumerateInstanceExtensionPropertiesChain; + +typedef struct VkEnumerateInstanceLayerPropertiesChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *); + const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const { + return pfnNextLayer(pNextLink, pPropertyCount, pProperties); + } +#endif +} VkEnumerateInstanceLayerPropertiesChain; + +typedef struct VkEnumerateInstanceVersionChain { + VkChainHeader header; + VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *); + const struct VkEnumerateInstanceVersionChain *pNextLink; + +#if defined(__cplusplus) + inline VkResult CallDown(uint32_t *pApiVersion) const { + return pfnNextLayer(pNextLink, pApiVersion); + } +#endif +} VkEnumerateInstanceVersionChain; + +#ifdef __cplusplus +} +#endif diff --git a/ext/vulkan/vk_layer_dispatch_table.h b/ext/vulkan/vk_layer_dispatch_table.h index d6b3f11a27..572982dfd3 100644 --- a/ext/vulkan/vk_layer_dispatch_table.h +++ b/ext/vulkan/vk_layer_dispatch_table.h @@ -49,6 +49,20 @@ typedef struct VkLayerInstanceDispatchTable_ { PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; + // ---- Core 1_1 commands + PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; + PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; + PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2; + PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysicalDeviceSparseImageFormatProperties2; + PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties; + PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties; + PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties; + // ---- VK_KHR_surface extension commands PFN_vkDestroySurfaceKHR DestroySurfaceKHR; PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR; @@ -56,6 +70,9 @@ typedef struct VkLayerInstanceDispatchTable_ { PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR; PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR; + // ---- VK_KHR_swapchain extension commands + PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR; + // ---- VK_KHR_display extension commands PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR; PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR; @@ -119,6 +136,22 @@ typedef struct VkLayerInstanceDispatchTable_ { PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR; PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysicalDeviceSparseImageFormatProperties2KHR; + // ---- VK_KHR_device_group_creation extension commands + PFN_vkEnumeratePhysicalDeviceGroupsKHR EnumeratePhysicalDeviceGroupsKHR; + + // ---- VK_KHR_external_memory_capabilities extension commands + PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR; + + // ---- VK_KHR_external_semaphore_capabilities extension commands + PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR; + + // ---- VK_KHR_external_fence_capabilities extension commands + PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR; + + // ---- VK_KHR_get_surface_capabilities2 extension commands + PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR; + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR; + // ---- VK_EXT_debug_report extension commands PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; @@ -127,23 +160,11 @@ typedef struct VkLayerInstanceDispatchTable_ { // ---- VK_NV_external_memory_capabilities extension commands PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV; - // ---- VK_KHX_device_group extension commands - PFN_vkGetPhysicalDevicePresentRectanglesKHX GetPhysicalDevicePresentRectanglesKHX; - // ---- VK_NN_vi_surface extension commands #ifdef VK_USE_PLATFORM_VI_NN PFN_vkCreateViSurfaceNN CreateViSurfaceNN; #endif // VK_USE_PLATFORM_VI_NN - // ---- VK_KHX_device_group_creation extension commands - PFN_vkEnumeratePhysicalDeviceGroupsKHX EnumeratePhysicalDeviceGroupsKHX; - - // ---- VK_KHX_external_memory_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHX GetPhysicalDeviceExternalBufferPropertiesKHX; - - // ---- VK_KHX_external_semaphore_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHX GetPhysicalDeviceExternalSemaphorePropertiesKHX; - // ---- VK_NVX_device_generated_commands extension commands PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX GetPhysicalDeviceGeneratedCommandsPropertiesNVX; @@ -170,6 +191,14 @@ typedef struct VkLayerInstanceDispatchTable_ { #ifdef VK_USE_PLATFORM_MACOS_MVK PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK; #endif // VK_USE_PLATFORM_MACOS_MVK + + // ---- VK_EXT_debug_utils extension commands + PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; + PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT; + PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT; + + // ---- VK_EXT_sample_locations extension commands + PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT; } VkLayerInstanceDispatchTable; // Device function pointer dispatch table @@ -298,27 +327,108 @@ typedef struct VkLayerDispatchTable_ { PFN_vkCmdEndRenderPass CmdEndRenderPass; PFN_vkCmdExecuteCommands CmdExecuteCommands; + // ---- Core 1_1 commands + PFN_vkBindBufferMemory2 BindBufferMemory2; + PFN_vkBindImageMemory2 BindImageMemory2; + PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures; + PFN_vkCmdSetDeviceMask CmdSetDeviceMask; + PFN_vkCmdDispatchBase CmdDispatchBase; + PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2; + PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2; + PFN_vkGetImageSparseMemoryRequirements2 GetImageSparseMemoryRequirements2; + PFN_vkTrimCommandPool TrimCommandPool; + PFN_vkGetDeviceQueue2 GetDeviceQueue2; + PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion; + PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion; + PFN_vkCreateDescriptorUpdateTemplate CreateDescriptorUpdateTemplate; + PFN_vkDestroyDescriptorUpdateTemplate DestroyDescriptorUpdateTemplate; + PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate; + PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport; + // ---- VK_KHR_swapchain extension commands PFN_vkCreateSwapchainKHR CreateSwapchainKHR; PFN_vkDestroySwapchainKHR DestroySwapchainKHR; PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR; PFN_vkAcquireNextImageKHR AcquireNextImageKHR; PFN_vkQueuePresentKHR QueuePresentKHR; + PFN_vkGetDeviceGroupPresentCapabilitiesKHR GetDeviceGroupPresentCapabilitiesKHR; + PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR; + PFN_vkAcquireNextImage2KHR AcquireNextImage2KHR; // ---- VK_KHR_display_swapchain extension commands PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR; + // ---- VK_KHR_device_group extension commands + PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR GetDeviceGroupPeerMemoryFeaturesKHR; + PFN_vkCmdSetDeviceMaskKHR CmdSetDeviceMaskKHR; + PFN_vkCmdDispatchBaseKHR CmdDispatchBaseKHR; + // ---- VK_KHR_maintenance1 extension commands PFN_vkTrimCommandPoolKHR TrimCommandPoolKHR; + // ---- VK_KHR_external_memory_win32 extension commands +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkGetMemoryWin32HandleKHR GetMemoryWin32HandleKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkGetMemoryWin32HandlePropertiesKHR GetMemoryWin32HandlePropertiesKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR + + // ---- VK_KHR_external_memory_fd extension commands + PFN_vkGetMemoryFdKHR GetMemoryFdKHR; + PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR; + + // ---- VK_KHR_external_semaphore_win32 extension commands +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkImportSemaphoreWin32HandleKHR ImportSemaphoreWin32HandleKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR + + // ---- VK_KHR_external_semaphore_fd extension commands + PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR; + PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR; + // ---- VK_KHR_push_descriptor extension commands PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSetKHR; + PFN_vkCmdPushDescriptorSetWithTemplateKHR CmdPushDescriptorSetWithTemplateKHR; // ---- VK_KHR_descriptor_update_template extension commands PFN_vkCreateDescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR; PFN_vkDestroyDescriptorUpdateTemplateKHR DestroyDescriptorUpdateTemplateKHR; PFN_vkUpdateDescriptorSetWithTemplateKHR UpdateDescriptorSetWithTemplateKHR; - PFN_vkCmdPushDescriptorSetWithTemplateKHR CmdPushDescriptorSetWithTemplateKHR; + + // ---- VK_KHR_shared_presentable_image extension commands + PFN_vkGetSwapchainStatusKHR GetSwapchainStatusKHR; + + // ---- VK_KHR_external_fence_win32 extension commands +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkImportFenceWin32HandleKHR ImportFenceWin32HandleKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkGetFenceWin32HandleKHR GetFenceWin32HandleKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR + + // ---- VK_KHR_external_fence_fd extension commands + PFN_vkImportFenceFdKHR ImportFenceFdKHR; + PFN_vkGetFenceFdKHR GetFenceFdKHR; + + // ---- VK_KHR_get_memory_requirements2 extension commands + PFN_vkGetImageMemoryRequirements2KHR GetImageMemoryRequirements2KHR; + PFN_vkGetBufferMemoryRequirements2KHR GetBufferMemoryRequirements2KHR; + PFN_vkGetImageSparseMemoryRequirements2KHR GetImageSparseMemoryRequirements2KHR; + + // ---- VK_KHR_sampler_ycbcr_conversion extension commands + PFN_vkCreateSamplerYcbcrConversionKHR CreateSamplerYcbcrConversionKHR; + PFN_vkDestroySamplerYcbcrConversionKHR DestroySamplerYcbcrConversionKHR; + + // ---- VK_KHR_bind_memory2 extension commands + PFN_vkBindBufferMemory2KHR BindBufferMemory2KHR; + PFN_vkBindImageMemory2KHR BindImageMemory2KHR; + + // ---- VK_KHR_maintenance3 extension commands + PFN_vkGetDescriptorSetLayoutSupportKHR GetDescriptorSetLayoutSupportKHR; // ---- VK_EXT_debug_marker extension commands PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; @@ -331,45 +441,14 @@ typedef struct VkLayerDispatchTable_ { PFN_vkCmdDrawIndirectCountAMD CmdDrawIndirectCountAMD; PFN_vkCmdDrawIndexedIndirectCountAMD CmdDrawIndexedIndirectCountAMD; + // ---- VK_AMD_shader_info extension commands + PFN_vkGetShaderInfoAMD GetShaderInfoAMD; + // ---- VK_NV_external_memory_win32 extension commands #ifdef VK_USE_PLATFORM_WIN32_KHR PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV; #endif // VK_USE_PLATFORM_WIN32_KHR - // ---- VK_KHX_device_group extension commands - PFN_vkGetDeviceGroupPeerMemoryFeaturesKHX GetDeviceGroupPeerMemoryFeaturesKHX; - PFN_vkBindBufferMemory2KHX BindBufferMemory2KHX; - PFN_vkBindImageMemory2KHX BindImageMemory2KHX; - PFN_vkCmdSetDeviceMaskKHX CmdSetDeviceMaskKHX; - PFN_vkGetDeviceGroupPresentCapabilitiesKHX GetDeviceGroupPresentCapabilitiesKHX; - PFN_vkGetDeviceGroupSurfacePresentModesKHX GetDeviceGroupSurfacePresentModesKHX; - PFN_vkAcquireNextImage2KHX AcquireNextImage2KHX; - PFN_vkCmdDispatchBaseKHX CmdDispatchBaseKHX; - - // ---- VK_KHX_external_memory_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHX - PFN_vkGetMemoryWin32HandleKHX GetMemoryWin32HandleKHX; -#endif // VK_USE_PLATFORM_WIN32_KHX -#ifdef VK_USE_PLATFORM_WIN32_KHX - PFN_vkGetMemoryWin32HandlePropertiesKHX GetMemoryWin32HandlePropertiesKHX; -#endif // VK_USE_PLATFORM_WIN32_KHX - - // ---- VK_KHX_external_memory_fd extension commands - PFN_vkGetMemoryFdKHX GetMemoryFdKHX; - PFN_vkGetMemoryFdPropertiesKHX GetMemoryFdPropertiesKHX; - - // ---- VK_KHX_external_semaphore_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHX - PFN_vkImportSemaphoreWin32HandleKHX ImportSemaphoreWin32HandleKHX; -#endif // VK_USE_PLATFORM_WIN32_KHX -#ifdef VK_USE_PLATFORM_WIN32_KHX - PFN_vkGetSemaphoreWin32HandleKHX GetSemaphoreWin32HandleKHX; -#endif // VK_USE_PLATFORM_WIN32_KHX - - // ---- VK_KHX_external_semaphore_fd extension commands - PFN_vkImportSemaphoreFdKHX ImportSemaphoreFdKHX; - PFN_vkGetSemaphoreFdKHX GetSemaphoreFdKHX; - // ---- VK_NVX_device_generated_commands extension commands PFN_vkCmdProcessCommandsNVX CmdProcessCommandsNVX; PFN_vkCmdReserveSpaceForCommandsNVX CmdReserveSpaceForCommandsNVX; @@ -398,6 +477,31 @@ typedef struct VkLayerDispatchTable_ { // ---- VK_EXT_hdr_metadata extension commands PFN_vkSetHdrMetadataEXT SetHdrMetadataEXT; + + // ---- VK_EXT_debug_utils extension commands + PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; + PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT; + PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT; + PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT; + PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT; + PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; + PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; + PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; + + // ---- VK_EXT_sample_locations extension commands + PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT; + + // ---- VK_EXT_validation_cache extension commands + PFN_vkCreateValidationCacheEXT CreateValidationCacheEXT; + PFN_vkDestroyValidationCacheEXT DestroyValidationCacheEXT; + PFN_vkMergeValidationCachesEXT MergeValidationCachesEXT; + PFN_vkGetValidationCacheDataEXT GetValidationCacheDataEXT; + + // ---- VK_EXT_external_memory_host extension commands + PFN_vkGetMemoryHostPointerPropertiesEXT GetMemoryHostPointerPropertiesEXT; + + // ---- VK_AMD_buffer_marker extension commands + PFN_vkCmdWriteBufferMarkerAMD CmdWriteBufferMarkerAMD; } VkLayerDispatchTable; diff --git a/ext/vulkan/vk_platform.h b/ext/vulkan/vk_platform.h index 72f80493ca..7289299240 100644 --- a/ext/vulkan/vk_platform.h +++ b/ext/vulkan/vk_platform.h @@ -89,32 +89,4 @@ extern "C" } // extern "C" #endif // __cplusplus -// Platform-specific headers required by platform window system extensions. -// These are enabled prior to #including "vulkan.h". The same enable then -// controls inclusion of the extension interfaces in vulkan.h. - -#ifdef VK_USE_PLATFORM_ANDROID_KHR -#include -#endif - -#ifdef VK_USE_PLATFORM_MIR_KHR -#include -#endif - -#ifdef VK_USE_PLATFORM_WAYLAND_KHR -#include -#endif - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#include -#endif - -#ifdef VK_USE_PLATFORM_XLIB_KHR -#include -#endif - -#ifdef VK_USE_PLATFORM_XCB_KHR -#include -#endif - #endif diff --git a/ext/vulkan/vk_sdk_platform.h b/ext/vulkan/vk_sdk_platform.h index ef9a000fb2..96d8676949 100644 --- a/ext/vulkan/vk_sdk_platform.h +++ b/ext/vulkan/vk_sdk_platform.h @@ -43,4 +43,27 @@ #endif // _WIN32 -#endif // VK_SDK_PLATFORM_H +// Check for noexcept support using clang, with fallback to Windows or GCC version numbers +#ifndef NOEXCEPT +#if defined(__clang__) +#if __has_feature(cxx_noexcept) +#define HAS_NOEXCEPT +#endif +#else +#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 +#define HAS_NOEXCEPT +#else +#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS +#define HAS_NOEXCEPT +#endif +#endif +#endif + +#ifdef HAS_NOEXCEPT +#define NOEXCEPT noexcept +#else +#define NOEXCEPT +#endif +#endif + +#endif // VK_SDK_PLATFORM_H diff --git a/ext/vulkan/vulkan.h b/ext/vulkan/vulkan.h index b19c1efff9..d05c8490a5 100644 --- a/ext/vulkan/vulkan.h +++ b/ext/vulkan/vulkan.h @@ -1,12 +1,8 @@ #ifndef VULKAN_H_ #define VULKAN_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2017 The Khronos Group Inc. +** Copyright (c) 2015-2018 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -21,6840 +17,63 @@ extern "C" { ** limitations under the License. */ -/* -** This header is generated from the Khronos Vulkan XML API Registry. -** -*/ - - -#define VK_VERSION_1_0 1 #include "vk_platform.h" - -#define VK_MAKE_VERSION(major, minor, patch) \ - (((major) << 22) | ((minor) << 12) | (patch)) - -// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. -//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 - -// Vulkan 1.0 version number -#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)// Patch version should always be set to 0 - -#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) -#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) -#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) -// Version of this file -#define VK_HEADER_VERSION 61 - - -#define VK_NULL_HANDLE 0 - - - -#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; - - -#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE) -#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; -#else - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; -#endif -#endif - - - -typedef uint32_t VkFlags; -typedef uint32_t VkBool32; -typedef uint64_t VkDeviceSize; -typedef uint32_t VkSampleMask; - -VK_DEFINE_HANDLE(VkInstance) -VK_DEFINE_HANDLE(VkPhysicalDevice) -VK_DEFINE_HANDLE(VkDevice) -VK_DEFINE_HANDLE(VkQueue) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) -VK_DEFINE_HANDLE(VkCommandBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) - -#define VK_LOD_CLAMP_NONE 1000.0f -#define VK_REMAINING_MIP_LEVELS (~0U) -#define VK_REMAINING_ARRAY_LAYERS (~0U) -#define VK_WHOLE_SIZE (~0ULL) -#define VK_ATTACHMENT_UNUSED (~0U) -#define VK_TRUE 1 -#define VK_FALSE 0 -#define VK_QUEUE_FAMILY_IGNORED (~0U) -#define VK_SUBPASS_EXTERNAL (~0U) -#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 -#define VK_UUID_SIZE 16 -#define VK_MAX_MEMORY_TYPES 32 -#define VK_MAX_MEMORY_HEAPS 16 -#define VK_MAX_EXTENSION_NAME_SIZE 256 -#define VK_MAX_DESCRIPTION_SIZE 256 - - -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1), - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; - -typedef enum VkResult { - VK_SUCCESS = 0, - VK_NOT_READY = 1, - VK_TIMEOUT = 2, - VK_EVENT_SET = 3, - VK_EVENT_RESET = 4, - VK_INCOMPLETE = 5, - VK_ERROR_OUT_OF_HOST_MEMORY = -1, - VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, - VK_ERROR_INITIALIZATION_FAILED = -3, - VK_ERROR_DEVICE_LOST = -4, - VK_ERROR_MEMORY_MAP_FAILED = -5, - VK_ERROR_LAYER_NOT_PRESENT = -6, - VK_ERROR_EXTENSION_NOT_PRESENT = -7, - VK_ERROR_FEATURE_NOT_PRESENT = -8, - VK_ERROR_INCOMPATIBLE_DRIVER = -9, - VK_ERROR_TOO_MANY_OBJECTS = -10, - VK_ERROR_FORMAT_NOT_SUPPORTED = -11, - VK_ERROR_FRAGMENTED_POOL = -12, - VK_ERROR_SURFACE_LOST_KHR = -1000000000, - VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, - VK_SUBOPTIMAL_KHR = 1000001003, - VK_ERROR_OUT_OF_DATE_KHR = -1000001004, - VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, - VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, - VK_ERROR_INVALID_SHADER_NV = -1000012000, - VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000, - VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = -1000072003, - VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL, - VK_RESULT_END_RANGE = VK_INCOMPLETE, - VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1), - VK_RESULT_MAX_ENUM = 0x7FFFFFFF -} VkResult; - -typedef enum VkStructureType { - VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, - VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, - VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, - VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, - VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, - VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, - VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, - VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, - VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, - VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, - VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, - VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, - VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, - VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, - VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, - VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, - VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, - VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000, - VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, - VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, - VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, - VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000, - VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, - VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, - VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, - VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, - VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, - VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX = 1000053000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX = 1000053001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX = 1000053002, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, - VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = 1000059000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = 1000059001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = 1000059002, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = 1000059004, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000059005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = 1000059006, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = 1000059008, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHX = 1000060000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHX = 1000060003, - VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHX = 1000060004, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHX = 1000060005, - VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHX = 1000060006, - VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHX = 1000060010, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHX = 1000060013, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHX = 1000060014, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHX = 1000060007, - VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHX = 1000060008, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHX = 1000060009, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHX = 1000060011, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHX = 1000060012, - VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, - VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX = 1000070000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHX = 1000070001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = 1000071000, - VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = 1000071001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = 1000071002, - VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = 1000071003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = 1000071004, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = 1000072000, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = 1000072001, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = 1000072002, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, - VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, - VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000, - VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001, - VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002, - VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = 1000076000, - VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = 1000076001, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = 1000077000, - VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, - VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, - VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, - VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, - VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = 1000083000, - VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, - VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = 1000085000, - VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000, - VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001, - VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002, - VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, - VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, - VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001, - VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002, - VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, - VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, - VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, - VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, - VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = 1000112000, - VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = 1000112001, - VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = 1000113000, - VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, - VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, - VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, - VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, - VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = 1000117000, - VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = 1000117001, - VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = 1000117002, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = 1000117003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, - VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000, - VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, - VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = 1000127000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = 1000127001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, - VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, - VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, - VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, - VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146000, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146001, - VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146002, - VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = 1000146003, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = 1000146004, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, - VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, - VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = 1000156000, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = 1000156001, - VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = 1000156002, - VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = 1000156003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = 1000156004, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = 1000156005, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = 1000157000, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = 1000157001, - VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, - VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, - VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, - VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, - VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), - VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkStructureType; - -typedef enum VkSystemAllocationScope { - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, - VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, - VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE, - VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), - VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF -} VkSystemAllocationScope; - -typedef enum VkInternalAllocationType { - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), - VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkInternalAllocationType; - -typedef enum VkFormat { - VK_FORMAT_UNDEFINED = 0, - VK_FORMAT_R4G4_UNORM_PACK8 = 1, - VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, - VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, - VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, - VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, - VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, - VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, - VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, - VK_FORMAT_R8_UNORM = 9, - VK_FORMAT_R8_SNORM = 10, - VK_FORMAT_R8_USCALED = 11, - VK_FORMAT_R8_SSCALED = 12, - VK_FORMAT_R8_UINT = 13, - VK_FORMAT_R8_SINT = 14, - VK_FORMAT_R8_SRGB = 15, - VK_FORMAT_R8G8_UNORM = 16, - VK_FORMAT_R8G8_SNORM = 17, - VK_FORMAT_R8G8_USCALED = 18, - VK_FORMAT_R8G8_SSCALED = 19, - VK_FORMAT_R8G8_UINT = 20, - VK_FORMAT_R8G8_SINT = 21, - VK_FORMAT_R8G8_SRGB = 22, - VK_FORMAT_R8G8B8_UNORM = 23, - VK_FORMAT_R8G8B8_SNORM = 24, - VK_FORMAT_R8G8B8_USCALED = 25, - VK_FORMAT_R8G8B8_SSCALED = 26, - VK_FORMAT_R8G8B8_UINT = 27, - VK_FORMAT_R8G8B8_SINT = 28, - VK_FORMAT_R8G8B8_SRGB = 29, - VK_FORMAT_B8G8R8_UNORM = 30, - VK_FORMAT_B8G8R8_SNORM = 31, - VK_FORMAT_B8G8R8_USCALED = 32, - VK_FORMAT_B8G8R8_SSCALED = 33, - VK_FORMAT_B8G8R8_UINT = 34, - VK_FORMAT_B8G8R8_SINT = 35, - VK_FORMAT_B8G8R8_SRGB = 36, - VK_FORMAT_R8G8B8A8_UNORM = 37, - VK_FORMAT_R8G8B8A8_SNORM = 38, - VK_FORMAT_R8G8B8A8_USCALED = 39, - VK_FORMAT_R8G8B8A8_SSCALED = 40, - VK_FORMAT_R8G8B8A8_UINT = 41, - VK_FORMAT_R8G8B8A8_SINT = 42, - VK_FORMAT_R8G8B8A8_SRGB = 43, - VK_FORMAT_B8G8R8A8_UNORM = 44, - VK_FORMAT_B8G8R8A8_SNORM = 45, - VK_FORMAT_B8G8R8A8_USCALED = 46, - VK_FORMAT_B8G8R8A8_SSCALED = 47, - VK_FORMAT_B8G8R8A8_UINT = 48, - VK_FORMAT_B8G8R8A8_SINT = 49, - VK_FORMAT_B8G8R8A8_SRGB = 50, - VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, - VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, - VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, - VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, - VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, - VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, - VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, - VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, - VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, - VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, - VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, - VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, - VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, - VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, - VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, - VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, - VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, - VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, - VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, - VK_FORMAT_R16_UNORM = 70, - VK_FORMAT_R16_SNORM = 71, - VK_FORMAT_R16_USCALED = 72, - VK_FORMAT_R16_SSCALED = 73, - VK_FORMAT_R16_UINT = 74, - VK_FORMAT_R16_SINT = 75, - VK_FORMAT_R16_SFLOAT = 76, - VK_FORMAT_R16G16_UNORM = 77, - VK_FORMAT_R16G16_SNORM = 78, - VK_FORMAT_R16G16_USCALED = 79, - VK_FORMAT_R16G16_SSCALED = 80, - VK_FORMAT_R16G16_UINT = 81, - VK_FORMAT_R16G16_SINT = 82, - VK_FORMAT_R16G16_SFLOAT = 83, - VK_FORMAT_R16G16B16_UNORM = 84, - VK_FORMAT_R16G16B16_SNORM = 85, - VK_FORMAT_R16G16B16_USCALED = 86, - VK_FORMAT_R16G16B16_SSCALED = 87, - VK_FORMAT_R16G16B16_UINT = 88, - VK_FORMAT_R16G16B16_SINT = 89, - VK_FORMAT_R16G16B16_SFLOAT = 90, - VK_FORMAT_R16G16B16A16_UNORM = 91, - VK_FORMAT_R16G16B16A16_SNORM = 92, - VK_FORMAT_R16G16B16A16_USCALED = 93, - VK_FORMAT_R16G16B16A16_SSCALED = 94, - VK_FORMAT_R16G16B16A16_UINT = 95, - VK_FORMAT_R16G16B16A16_SINT = 96, - VK_FORMAT_R16G16B16A16_SFLOAT = 97, - VK_FORMAT_R32_UINT = 98, - VK_FORMAT_R32_SINT = 99, - VK_FORMAT_R32_SFLOAT = 100, - VK_FORMAT_R32G32_UINT = 101, - VK_FORMAT_R32G32_SINT = 102, - VK_FORMAT_R32G32_SFLOAT = 103, - VK_FORMAT_R32G32B32_UINT = 104, - VK_FORMAT_R32G32B32_SINT = 105, - VK_FORMAT_R32G32B32_SFLOAT = 106, - VK_FORMAT_R32G32B32A32_UINT = 107, - VK_FORMAT_R32G32B32A32_SINT = 108, - VK_FORMAT_R32G32B32A32_SFLOAT = 109, - VK_FORMAT_R64_UINT = 110, - VK_FORMAT_R64_SINT = 111, - VK_FORMAT_R64_SFLOAT = 112, - VK_FORMAT_R64G64_UINT = 113, - VK_FORMAT_R64G64_SINT = 114, - VK_FORMAT_R64G64_SFLOAT = 115, - VK_FORMAT_R64G64B64_UINT = 116, - VK_FORMAT_R64G64B64_SINT = 117, - VK_FORMAT_R64G64B64_SFLOAT = 118, - VK_FORMAT_R64G64B64A64_UINT = 119, - VK_FORMAT_R64G64B64A64_SINT = 120, - VK_FORMAT_R64G64B64A64_SFLOAT = 121, - VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, - VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, - VK_FORMAT_D16_UNORM = 124, - VK_FORMAT_X8_D24_UNORM_PACK32 = 125, - VK_FORMAT_D32_SFLOAT = 126, - VK_FORMAT_S8_UINT = 127, - VK_FORMAT_D16_UNORM_S8_UINT = 128, - VK_FORMAT_D24_UNORM_S8_UINT = 129, - VK_FORMAT_D32_SFLOAT_S8_UINT = 130, - VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, - VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, - VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, - VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, - VK_FORMAT_BC2_UNORM_BLOCK = 135, - VK_FORMAT_BC2_SRGB_BLOCK = 136, - VK_FORMAT_BC3_UNORM_BLOCK = 137, - VK_FORMAT_BC3_SRGB_BLOCK = 138, - VK_FORMAT_BC4_UNORM_BLOCK = 139, - VK_FORMAT_BC4_SNORM_BLOCK = 140, - VK_FORMAT_BC5_UNORM_BLOCK = 141, - VK_FORMAT_BC5_SNORM_BLOCK = 142, - VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, - VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, - VK_FORMAT_BC7_UNORM_BLOCK = 145, - VK_FORMAT_BC7_SRGB_BLOCK = 146, - VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, - VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, - VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, - VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, - VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, - VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, - VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, - VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, - VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, - VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, - VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, - VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, - VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, - VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, - VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, - VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, - VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, - VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, - VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, - VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, - VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, - VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, - VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, - VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, - VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, - VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, - VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, - VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, - VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, - VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, - VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, - VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, - VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, - VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, - VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, - VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, - VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, - VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, - VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, - VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, - VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, - VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003, - VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004, - VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, - VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, - VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_G8B8G8R8_422_UNORM_KHR = 1000156000, - VK_FORMAT_B8G8R8G8_422_UNORM_KHR = 1000156001, - VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = 1000156002, - VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = 1000156003, - VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = 1000156004, - VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = 1000156005, - VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = 1000156006, - VK_FORMAT_R10X6_UNORM_PACK16_KHR = 1000156007, - VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = 1000156008, - VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = 1000156009, - VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = 1000156010, - VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = 1000156011, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = 1000156012, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = 1000156013, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = 1000156014, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = 1000156015, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = 1000156016, - VK_FORMAT_R12X4_UNORM_PACK16_KHR = 1000156017, - VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = 1000156018, - VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = 1000156019, - VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = 1000156020, - VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = 1000156021, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = 1000156022, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = 1000156023, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = 1000156024, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = 1000156025, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = 1000156026, - VK_FORMAT_G16B16G16R16_422_UNORM_KHR = 1000156027, - VK_FORMAT_B16G16R16G16_422_UNORM_KHR = 1000156028, - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = 1000156029, - VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = 1000156030, - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = 1000156031, - VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = 1000156032, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = 1000156033, - VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED, - VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1), - VK_FORMAT_MAX_ENUM = 0x7FFFFFFF -} VkFormat; - -typedef enum VkImageType { - VK_IMAGE_TYPE_1D = 0, - VK_IMAGE_TYPE_2D = 1, - VK_IMAGE_TYPE_3D = 2, - VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D, - VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D, - VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1), - VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageType; - -typedef enum VkImageTiling { - VK_IMAGE_TILING_OPTIMAL = 0, - VK_IMAGE_TILING_LINEAR = 1, - VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, - VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), - VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF -} VkImageTiling; - -typedef enum VkPhysicalDeviceType { - VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, - VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, - VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, - VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, - VK_PHYSICAL_DEVICE_TYPE_CPU = 4, - VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU, - VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1), - VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkPhysicalDeviceType; - -typedef enum VkQueryType { - VK_QUERY_TYPE_OCCLUSION = 0, - VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, - VK_QUERY_TYPE_TIMESTAMP = 2, - VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, - VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, - VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), - VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkQueryType; - -typedef enum VkSharingMode { - VK_SHARING_MODE_EXCLUSIVE = 0, - VK_SHARING_MODE_CONCURRENT = 1, - VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE, - VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT, - VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1), - VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSharingMode; - -typedef enum VkImageLayout { - VK_IMAGE_LAYOUT_UNDEFINED = 0, - VK_IMAGE_LAYOUT_GENERAL = 1, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, - VK_IMAGE_LAYOUT_PREINITIALIZED = 8, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, - VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = 1000117000, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = 1000117001, - VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, - VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), - VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF -} VkImageLayout; - -typedef enum VkImageViewType { - VK_IMAGE_VIEW_TYPE_1D = 0, - VK_IMAGE_VIEW_TYPE_2D = 1, - VK_IMAGE_VIEW_TYPE_3D = 2, - VK_IMAGE_VIEW_TYPE_CUBE = 3, - VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, - VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, - VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, - VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), - VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageViewType; - -typedef enum VkComponentSwizzle { - VK_COMPONENT_SWIZZLE_IDENTITY = 0, - VK_COMPONENT_SWIZZLE_ZERO = 1, - VK_COMPONENT_SWIZZLE_ONE = 2, - VK_COMPONENT_SWIZZLE_R = 3, - VK_COMPONENT_SWIZZLE_G = 4, - VK_COMPONENT_SWIZZLE_B = 5, - VK_COMPONENT_SWIZZLE_A = 6, - VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, - VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), - VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF -} VkComponentSwizzle; - -typedef enum VkVertexInputRate { - VK_VERTEX_INPUT_RATE_VERTEX = 0, - VK_VERTEX_INPUT_RATE_INSTANCE = 1, - VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, - VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, - VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), - VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF -} VkVertexInputRate; - -typedef enum VkPrimitiveTopology { - VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, - VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, - VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), - VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF -} VkPrimitiveTopology; - -typedef enum VkPolygonMode { - VK_POLYGON_MODE_FILL = 0, - VK_POLYGON_MODE_LINE = 1, - VK_POLYGON_MODE_POINT = 2, - VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, - VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, - VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, - VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), - VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF -} VkPolygonMode; - -typedef enum VkFrontFace { - VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, - VK_FRONT_FACE_CLOCKWISE = 1, - VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, - VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, - VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), - VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF -} VkFrontFace; - -typedef enum VkCompareOp { - VK_COMPARE_OP_NEVER = 0, - VK_COMPARE_OP_LESS = 1, - VK_COMPARE_OP_EQUAL = 2, - VK_COMPARE_OP_LESS_OR_EQUAL = 3, - VK_COMPARE_OP_GREATER = 4, - VK_COMPARE_OP_NOT_EQUAL = 5, - VK_COMPARE_OP_GREATER_OR_EQUAL = 6, - VK_COMPARE_OP_ALWAYS = 7, - VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, - VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, - VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), - VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF -} VkCompareOp; - -typedef enum VkStencilOp { - VK_STENCIL_OP_KEEP = 0, - VK_STENCIL_OP_ZERO = 1, - VK_STENCIL_OP_REPLACE = 2, - VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, - VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, - VK_STENCIL_OP_INVERT = 5, - VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, - VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, - VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, - VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, - VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), - VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF -} VkStencilOp; - -typedef enum VkLogicOp { - VK_LOGIC_OP_CLEAR = 0, - VK_LOGIC_OP_AND = 1, - VK_LOGIC_OP_AND_REVERSE = 2, - VK_LOGIC_OP_COPY = 3, - VK_LOGIC_OP_AND_INVERTED = 4, - VK_LOGIC_OP_NO_OP = 5, - VK_LOGIC_OP_XOR = 6, - VK_LOGIC_OP_OR = 7, - VK_LOGIC_OP_NOR = 8, - VK_LOGIC_OP_EQUIVALENT = 9, - VK_LOGIC_OP_INVERT = 10, - VK_LOGIC_OP_OR_REVERSE = 11, - VK_LOGIC_OP_COPY_INVERTED = 12, - VK_LOGIC_OP_OR_INVERTED = 13, - VK_LOGIC_OP_NAND = 14, - VK_LOGIC_OP_SET = 15, - VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, - VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, - VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), - VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF -} VkLogicOp; - -typedef enum VkBlendFactor { - VK_BLEND_FACTOR_ZERO = 0, - VK_BLEND_FACTOR_ONE = 1, - VK_BLEND_FACTOR_SRC_COLOR = 2, - VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, - VK_BLEND_FACTOR_DST_COLOR = 4, - VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, - VK_BLEND_FACTOR_SRC_ALPHA = 6, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, - VK_BLEND_FACTOR_DST_ALPHA = 8, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, - VK_BLEND_FACTOR_CONSTANT_COLOR = 10, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, - VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, - VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, - VK_BLEND_FACTOR_SRC1_COLOR = 15, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, - VK_BLEND_FACTOR_SRC1_ALPHA = 17, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, - VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), - VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF -} VkBlendFactor; - -typedef enum VkBlendOp { - VK_BLEND_OP_ADD = 0, - VK_BLEND_OP_SUBTRACT = 1, - VK_BLEND_OP_REVERSE_SUBTRACT = 2, - VK_BLEND_OP_MIN = 3, - VK_BLEND_OP_MAX = 4, - VK_BLEND_OP_ZERO_EXT = 1000148000, - VK_BLEND_OP_SRC_EXT = 1000148001, - VK_BLEND_OP_DST_EXT = 1000148002, - VK_BLEND_OP_SRC_OVER_EXT = 1000148003, - VK_BLEND_OP_DST_OVER_EXT = 1000148004, - VK_BLEND_OP_SRC_IN_EXT = 1000148005, - VK_BLEND_OP_DST_IN_EXT = 1000148006, - VK_BLEND_OP_SRC_OUT_EXT = 1000148007, - VK_BLEND_OP_DST_OUT_EXT = 1000148008, - VK_BLEND_OP_SRC_ATOP_EXT = 1000148009, - VK_BLEND_OP_DST_ATOP_EXT = 1000148010, - VK_BLEND_OP_XOR_EXT = 1000148011, - VK_BLEND_OP_MULTIPLY_EXT = 1000148012, - VK_BLEND_OP_SCREEN_EXT = 1000148013, - VK_BLEND_OP_OVERLAY_EXT = 1000148014, - VK_BLEND_OP_DARKEN_EXT = 1000148015, - VK_BLEND_OP_LIGHTEN_EXT = 1000148016, - VK_BLEND_OP_COLORDODGE_EXT = 1000148017, - VK_BLEND_OP_COLORBURN_EXT = 1000148018, - VK_BLEND_OP_HARDLIGHT_EXT = 1000148019, - VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020, - VK_BLEND_OP_DIFFERENCE_EXT = 1000148021, - VK_BLEND_OP_EXCLUSION_EXT = 1000148022, - VK_BLEND_OP_INVERT_EXT = 1000148023, - VK_BLEND_OP_INVERT_RGB_EXT = 1000148024, - VK_BLEND_OP_LINEARDODGE_EXT = 1000148025, - VK_BLEND_OP_LINEARBURN_EXT = 1000148026, - VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027, - VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028, - VK_BLEND_OP_PINLIGHT_EXT = 1000148029, - VK_BLEND_OP_HARDMIX_EXT = 1000148030, - VK_BLEND_OP_HSL_HUE_EXT = 1000148031, - VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032, - VK_BLEND_OP_HSL_COLOR_EXT = 1000148033, - VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034, - VK_BLEND_OP_PLUS_EXT = 1000148035, - VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036, - VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037, - VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038, - VK_BLEND_OP_MINUS_EXT = 1000148039, - VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040, - VK_BLEND_OP_CONTRAST_EXT = 1000148041, - VK_BLEND_OP_INVERT_OVG_EXT = 1000148042, - VK_BLEND_OP_RED_EXT = 1000148043, - VK_BLEND_OP_GREEN_EXT = 1000148044, - VK_BLEND_OP_BLUE_EXT = 1000148045, - VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, - VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, - VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), - VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF -} VkBlendOp; - -typedef enum VkDynamicState { - VK_DYNAMIC_STATE_VIEWPORT = 0, - VK_DYNAMIC_STATE_SCISSOR = 1, - VK_DYNAMIC_STATE_LINE_WIDTH = 2, - VK_DYNAMIC_STATE_DEPTH_BIAS = 3, - VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, - VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, - VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, - VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, - VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, - VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, - VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), - VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF -} VkDynamicState; - -typedef enum VkFilter { - VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1, - VK_FILTER_CUBIC_IMG = 1000015000, - VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, - VK_FILTER_END_RANGE = VK_FILTER_LINEAR, - VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), - VK_FILTER_MAX_ENUM = 0x7FFFFFFF -} VkFilter; - -typedef enum VkSamplerMipmapMode { - VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, - VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, - VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), - VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerMipmapMode; - -typedef enum VkSamplerAddressMode { - VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, - VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, - VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, - VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, - VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), - VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerAddressMode; - -typedef enum VkBorderColor { - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, - VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, - VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, - VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, - VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, - VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), - VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF -} VkBorderColor; - -typedef enum VkDescriptorType { - VK_DESCRIPTOR_TYPE_SAMPLER = 0, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, - VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, - VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), - VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorType; - -typedef enum VkAttachmentLoadOp { - VK_ATTACHMENT_LOAD_OP_LOAD = 0, - VK_ATTACHMENT_LOAD_OP_CLEAR = 1, - VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), - VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentLoadOp; - -typedef enum VkAttachmentStoreOp { - VK_ATTACHMENT_STORE_OP_STORE = 0, - VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), - VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentStoreOp; - -typedef enum VkPipelineBindPoint { - VK_PIPELINE_BIND_POINT_GRAPHICS = 0, - VK_PIPELINE_BIND_POINT_COMPUTE = 1, - VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, - VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, - VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), - VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF -} VkPipelineBindPoint; - -typedef enum VkCommandBufferLevel { - VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, - VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, - VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), - VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferLevel; - -typedef enum VkIndexType { - VK_INDEX_TYPE_UINT16 = 0, - VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, - VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, - VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), - VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkIndexType; - -typedef enum VkSubpassContents { - VK_SUBPASS_CONTENTS_INLINE = 0, - VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, - VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, - VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), - VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassContents; - -typedef enum VkObjectType { - VK_OBJECT_TYPE_UNKNOWN = 0, - VK_OBJECT_TYPE_INSTANCE = 1, - VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, - VK_OBJECT_TYPE_DEVICE = 3, - VK_OBJECT_TYPE_QUEUE = 4, - VK_OBJECT_TYPE_SEMAPHORE = 5, - VK_OBJECT_TYPE_COMMAND_BUFFER = 6, - VK_OBJECT_TYPE_FENCE = 7, - VK_OBJECT_TYPE_DEVICE_MEMORY = 8, - VK_OBJECT_TYPE_BUFFER = 9, - VK_OBJECT_TYPE_IMAGE = 10, - VK_OBJECT_TYPE_EVENT = 11, - VK_OBJECT_TYPE_QUERY_POOL = 12, - VK_OBJECT_TYPE_BUFFER_VIEW = 13, - VK_OBJECT_TYPE_IMAGE_VIEW = 14, - VK_OBJECT_TYPE_SHADER_MODULE = 15, - VK_OBJECT_TYPE_PIPELINE_CACHE = 16, - VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, - VK_OBJECT_TYPE_RENDER_PASS = 18, - VK_OBJECT_TYPE_PIPELINE = 19, - VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, - VK_OBJECT_TYPE_SAMPLER = 21, - VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, - VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, - VK_OBJECT_TYPE_FRAMEBUFFER = 24, - VK_OBJECT_TYPE_COMMAND_POOL = 25, - VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, - VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, - VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, - VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, - VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = 1000085000, - VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000, - VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = 1000156000, - VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, - VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN, - VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL, - VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1), - VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkObjectType; - -typedef VkFlags VkInstanceCreateFlags; - -typedef enum VkFormatFeatureFlagBits { - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, - VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, - VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, - VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, - VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, - VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = 0x00004000, - VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = 0x00008000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, - VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000, - VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = 0x00400000, - VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000, - VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFormatFeatureFlagBits; -typedef VkFlags VkFormatFeatureFlags; - -typedef enum VkImageUsageFlagBits { - VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, - VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, - VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, - VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, - VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageUsageFlagBits; -typedef VkFlags VkImageUsageFlags; - -typedef enum VkImageCreateFlagBits { - VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, - VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, - VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, - VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, - VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, - VK_IMAGE_CREATE_BIND_SFR_BIT_KHX = 0x00000040, - VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = 0x00000020, - VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = 0x00000080, - VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = 0x00000100, - VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, - VK_IMAGE_CREATE_DISJOINT_BIT_KHR = 0x00000200, - VK_IMAGE_CREATE_ALIAS_BIT_KHR = 0x00000400, - VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageCreateFlagBits; -typedef VkFlags VkImageCreateFlags; - -typedef enum VkSampleCountFlagBits { - VK_SAMPLE_COUNT_1_BIT = 0x00000001, - VK_SAMPLE_COUNT_2_BIT = 0x00000002, - VK_SAMPLE_COUNT_4_BIT = 0x00000004, - VK_SAMPLE_COUNT_8_BIT = 0x00000008, - VK_SAMPLE_COUNT_16_BIT = 0x00000010, - VK_SAMPLE_COUNT_32_BIT = 0x00000020, - VK_SAMPLE_COUNT_64_BIT = 0x00000040, - VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSampleCountFlagBits; -typedef VkFlags VkSampleCountFlags; - -typedef enum VkQueueFlagBits { - VK_QUEUE_GRAPHICS_BIT = 0x00000001, - VK_QUEUE_COMPUTE_BIT = 0x00000002, - VK_QUEUE_TRANSFER_BIT = 0x00000004, - VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, - VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueueFlagBits; -typedef VkFlags VkQueueFlags; - -typedef enum VkMemoryPropertyFlagBits { - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, - VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, - VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryPropertyFlagBits; -typedef VkFlags VkMemoryPropertyFlags; - -typedef enum VkMemoryHeapFlagBits { - VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX = 0x00000002, - VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryHeapFlagBits; -typedef VkFlags VkMemoryHeapFlags; -typedef VkFlags VkDeviceCreateFlags; -typedef VkFlags VkDeviceQueueCreateFlags; - -typedef enum VkPipelineStageFlagBits { - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, - VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, - VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, - VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, - VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, - VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, - VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, - VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000, - VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineStageFlagBits; -typedef VkFlags VkPipelineStageFlags; -typedef VkFlags VkMemoryMapFlags; - -typedef enum VkImageAspectFlagBits { - VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, - VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, - VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, - VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, - VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = 0x00000010, - VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = 0x00000020, - VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = 0x00000040, - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageAspectFlagBits; -typedef VkFlags VkImageAspectFlags; - -typedef enum VkSparseImageFormatFlagBits { - VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, - VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, - VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, - VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseImageFormatFlagBits; -typedef VkFlags VkSparseImageFormatFlags; - -typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, - VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseMemoryBindFlagBits; -typedef VkFlags VkSparseMemoryBindFlags; - -typedef enum VkFenceCreateFlagBits { - VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, - VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFenceCreateFlagBits; -typedef VkFlags VkFenceCreateFlags; -typedef VkFlags VkSemaphoreCreateFlags; -typedef VkFlags VkEventCreateFlags; -typedef VkFlags VkQueryPoolCreateFlags; - -typedef enum VkQueryPipelineStatisticFlagBits { - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, - VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, - VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, - VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, - VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryPipelineStatisticFlagBits; -typedef VkFlags VkQueryPipelineStatisticFlags; - -typedef enum VkQueryResultFlagBits { - VK_QUERY_RESULT_64_BIT = 0x00000001, - VK_QUERY_RESULT_WAIT_BIT = 0x00000002, - VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, - VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, - VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryResultFlagBits; -typedef VkFlags VkQueryResultFlags; - -typedef enum VkBufferCreateFlagBits { - VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, - VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, - VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, - VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferCreateFlagBits; -typedef VkFlags VkBufferCreateFlags; - -typedef enum VkBufferUsageFlagBits { - VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, - VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, - VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, - VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, - VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, - VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferUsageFlagBits; -typedef VkFlags VkBufferUsageFlags; -typedef VkFlags VkBufferViewCreateFlags; -typedef VkFlags VkImageViewCreateFlags; -typedef VkFlags VkShaderModuleCreateFlags; -typedef VkFlags VkPipelineCacheCreateFlags; - -typedef enum VkPipelineCreateFlagBits { - VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, - VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, - VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, - VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX = 0x00000008, - VK_PIPELINE_CREATE_DISPATCH_BASE_KHX = 0x00000010, - VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreateFlagBits; -typedef VkFlags VkPipelineCreateFlags; -typedef VkFlags VkPipelineShaderStageCreateFlags; - -typedef enum VkShaderStageFlagBits { - VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, - VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, - VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, - VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, - VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, - VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkShaderStageFlagBits; -typedef VkFlags VkPipelineVertexInputStateCreateFlags; -typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; -typedef VkFlags VkPipelineTessellationStateCreateFlags; -typedef VkFlags VkPipelineViewportStateCreateFlags; -typedef VkFlags VkPipelineRasterizationStateCreateFlags; - -typedef enum VkCullModeFlagBits { - VK_CULL_MODE_NONE = 0, - VK_CULL_MODE_FRONT_BIT = 0x00000001, - VK_CULL_MODE_BACK_BIT = 0x00000002, - VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, - VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCullModeFlagBits; -typedef VkFlags VkCullModeFlags; -typedef VkFlags VkPipelineMultisampleStateCreateFlags; -typedef VkFlags VkPipelineDepthStencilStateCreateFlags; -typedef VkFlags VkPipelineColorBlendStateCreateFlags; - -typedef enum VkColorComponentFlagBits { - VK_COLOR_COMPONENT_R_BIT = 0x00000001, - VK_COLOR_COMPONENT_G_BIT = 0x00000002, - VK_COLOR_COMPONENT_B_BIT = 0x00000004, - VK_COLOR_COMPONENT_A_BIT = 0x00000008, - VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkColorComponentFlagBits; -typedef VkFlags VkColorComponentFlags; -typedef VkFlags VkPipelineDynamicStateCreateFlags; -typedef VkFlags VkPipelineLayoutCreateFlags; -typedef VkFlags VkShaderStageFlags; -typedef VkFlags VkSamplerCreateFlags; - -typedef enum VkDescriptorSetLayoutCreateFlagBits { - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorSetLayoutCreateFlagBits; -typedef VkFlags VkDescriptorSetLayoutCreateFlags; - -typedef enum VkDescriptorPoolCreateFlagBits { - VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, - VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorPoolCreateFlagBits; -typedef VkFlags VkDescriptorPoolCreateFlags; -typedef VkFlags VkDescriptorPoolResetFlags; -typedef VkFlags VkFramebufferCreateFlags; -typedef VkFlags VkRenderPassCreateFlags; - -typedef enum VkAttachmentDescriptionFlagBits { - VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, - VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentDescriptionFlagBits; -typedef VkFlags VkAttachmentDescriptionFlags; - -typedef enum VkSubpassDescriptionFlagBits { - VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, - VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, - VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassDescriptionFlagBits; -typedef VkFlags VkSubpassDescriptionFlags; - -typedef enum VkAccessFlagBits { - VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, - VK_ACCESS_INDEX_READ_BIT = 0x00000002, - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, - VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, - VK_ACCESS_SHADER_READ_BIT = 0x00000020, - VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, - VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, - VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, - VK_ACCESS_HOST_READ_BIT = 0x00002000, - VK_ACCESS_HOST_WRITE_BIT = 0x00004000, - VK_ACCESS_MEMORY_READ_BIT = 0x00008000, - VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, - VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000, - VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000, - VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, - VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAccessFlagBits; -typedef VkFlags VkAccessFlags; - -typedef enum VkDependencyFlagBits { - VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, - VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX = 0x00000002, - VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX = 0x00000004, - VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDependencyFlagBits; -typedef VkFlags VkDependencyFlags; - -typedef enum VkCommandPoolCreateFlagBits { - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, - VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolCreateFlagBits; -typedef VkFlags VkCommandPoolCreateFlags; - -typedef enum VkCommandPoolResetFlagBits { - VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolResetFlagBits; -typedef VkFlags VkCommandPoolResetFlags; - -typedef enum VkCommandBufferUsageFlagBits { - VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, - VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, - VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferUsageFlagBits; -typedef VkFlags VkCommandBufferUsageFlags; - -typedef enum VkQueryControlFlagBits { - VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, - VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryControlFlagBits; -typedef VkFlags VkQueryControlFlags; - -typedef enum VkCommandBufferResetFlagBits { - VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferResetFlagBits; -typedef VkFlags VkCommandBufferResetFlags; - -typedef enum VkStencilFaceFlagBits { - VK_STENCIL_FACE_FRONT_BIT = 0x00000001, - VK_STENCIL_FACE_BACK_BIT = 0x00000002, - VK_STENCIL_FRONT_AND_BACK = 0x00000003, - VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkStencilFaceFlagBits; -typedef VkFlags VkStencilFaceFlags; - -typedef struct VkApplicationInfo { - VkStructureType sType; - const void* pNext; - const char* pApplicationName; - uint32_t applicationVersion; - const char* pEngineName; - uint32_t engineVersion; - uint32_t apiVersion; -} VkApplicationInfo; - -typedef struct VkInstanceCreateInfo { - VkStructureType sType; - const void* pNext; - VkInstanceCreateFlags flags; - const VkApplicationInfo* pApplicationInfo; - uint32_t enabledLayerCount; - const char* const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char* const* ppEnabledExtensionNames; -} VkInstanceCreateInfo; - -typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( - void* pUserData, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); - -typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( - void* pUserData, - void* pOriginal, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); - -typedef void (VKAPI_PTR *PFN_vkFreeFunction)( - void* pUserData, - void* pMemory); - -typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); - -typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); - -typedef struct VkAllocationCallbacks { - void* pUserData; - PFN_vkAllocationFunction pfnAllocation; - PFN_vkReallocationFunction pfnReallocation; - PFN_vkFreeFunction pfnFree; - PFN_vkInternalAllocationNotification pfnInternalAllocation; - PFN_vkInternalFreeNotification pfnInternalFree; -} VkAllocationCallbacks; - -typedef struct VkPhysicalDeviceFeatures { - VkBool32 robustBufferAccess; - VkBool32 fullDrawIndexUint32; - VkBool32 imageCubeArray; - VkBool32 independentBlend; - VkBool32 geometryShader; - VkBool32 tessellationShader; - VkBool32 sampleRateShading; - VkBool32 dualSrcBlend; - VkBool32 logicOp; - VkBool32 multiDrawIndirect; - VkBool32 drawIndirectFirstInstance; - VkBool32 depthClamp; - VkBool32 depthBiasClamp; - VkBool32 fillModeNonSolid; - VkBool32 depthBounds; - VkBool32 wideLines; - VkBool32 largePoints; - VkBool32 alphaToOne; - VkBool32 multiViewport; - VkBool32 samplerAnisotropy; - VkBool32 textureCompressionETC2; - VkBool32 textureCompressionASTC_LDR; - VkBool32 textureCompressionBC; - VkBool32 occlusionQueryPrecise; - VkBool32 pipelineStatisticsQuery; - VkBool32 vertexPipelineStoresAndAtomics; - VkBool32 fragmentStoresAndAtomics; - VkBool32 shaderTessellationAndGeometryPointSize; - VkBool32 shaderImageGatherExtended; - VkBool32 shaderStorageImageExtendedFormats; - VkBool32 shaderStorageImageMultisample; - VkBool32 shaderStorageImageReadWithoutFormat; - VkBool32 shaderStorageImageWriteWithoutFormat; - VkBool32 shaderUniformBufferArrayDynamicIndexing; - VkBool32 shaderSampledImageArrayDynamicIndexing; - VkBool32 shaderStorageBufferArrayDynamicIndexing; - VkBool32 shaderStorageImageArrayDynamicIndexing; - VkBool32 shaderClipDistance; - VkBool32 shaderCullDistance; - VkBool32 shaderFloat64; - VkBool32 shaderInt64; - VkBool32 shaderInt16; - VkBool32 shaderResourceResidency; - VkBool32 shaderResourceMinLod; - VkBool32 sparseBinding; - VkBool32 sparseResidencyBuffer; - VkBool32 sparseResidencyImage2D; - VkBool32 sparseResidencyImage3D; - VkBool32 sparseResidency2Samples; - VkBool32 sparseResidency4Samples; - VkBool32 sparseResidency8Samples; - VkBool32 sparseResidency16Samples; - VkBool32 sparseResidencyAliased; - VkBool32 variableMultisampleRate; - VkBool32 inheritedQueries; -} VkPhysicalDeviceFeatures; - -typedef struct VkFormatProperties { - VkFormatFeatureFlags linearTilingFeatures; - VkFormatFeatureFlags optimalTilingFeatures; - VkFormatFeatureFlags bufferFeatures; -} VkFormatProperties; - -typedef struct VkExtent3D { - uint32_t width; - uint32_t height; - uint32_t depth; -} VkExtent3D; - -typedef struct VkImageFormatProperties { - VkExtent3D maxExtent; - uint32_t maxMipLevels; - uint32_t maxArrayLayers; - VkSampleCountFlags sampleCounts; - VkDeviceSize maxResourceSize; -} VkImageFormatProperties; - -typedef struct VkPhysicalDeviceLimits { - uint32_t maxImageDimension1D; - uint32_t maxImageDimension2D; - uint32_t maxImageDimension3D; - uint32_t maxImageDimensionCube; - uint32_t maxImageArrayLayers; - uint32_t maxTexelBufferElements; - uint32_t maxUniformBufferRange; - uint32_t maxStorageBufferRange; - uint32_t maxPushConstantsSize; - uint32_t maxMemoryAllocationCount; - uint32_t maxSamplerAllocationCount; - VkDeviceSize bufferImageGranularity; - VkDeviceSize sparseAddressSpaceSize; - uint32_t maxBoundDescriptorSets; - uint32_t maxPerStageDescriptorSamplers; - uint32_t maxPerStageDescriptorUniformBuffers; - uint32_t maxPerStageDescriptorStorageBuffers; - uint32_t maxPerStageDescriptorSampledImages; - uint32_t maxPerStageDescriptorStorageImages; - uint32_t maxPerStageDescriptorInputAttachments; - uint32_t maxPerStageResources; - uint32_t maxDescriptorSetSamplers; - uint32_t maxDescriptorSetUniformBuffers; - uint32_t maxDescriptorSetUniformBuffersDynamic; - uint32_t maxDescriptorSetStorageBuffers; - uint32_t maxDescriptorSetStorageBuffersDynamic; - uint32_t maxDescriptorSetSampledImages; - uint32_t maxDescriptorSetStorageImages; - uint32_t maxDescriptorSetInputAttachments; - uint32_t maxVertexInputAttributes; - uint32_t maxVertexInputBindings; - uint32_t maxVertexInputAttributeOffset; - uint32_t maxVertexInputBindingStride; - uint32_t maxVertexOutputComponents; - uint32_t maxTessellationGenerationLevel; - uint32_t maxTessellationPatchSize; - uint32_t maxTessellationControlPerVertexInputComponents; - uint32_t maxTessellationControlPerVertexOutputComponents; - uint32_t maxTessellationControlPerPatchOutputComponents; - uint32_t maxTessellationControlTotalOutputComponents; - uint32_t maxTessellationEvaluationInputComponents; - uint32_t maxTessellationEvaluationOutputComponents; - uint32_t maxGeometryShaderInvocations; - uint32_t maxGeometryInputComponents; - uint32_t maxGeometryOutputComponents; - uint32_t maxGeometryOutputVertices; - uint32_t maxGeometryTotalOutputComponents; - uint32_t maxFragmentInputComponents; - uint32_t maxFragmentOutputAttachments; - uint32_t maxFragmentDualSrcAttachments; - uint32_t maxFragmentCombinedOutputResources; - uint32_t maxComputeSharedMemorySize; - uint32_t maxComputeWorkGroupCount[3]; - uint32_t maxComputeWorkGroupInvocations; - uint32_t maxComputeWorkGroupSize[3]; - uint32_t subPixelPrecisionBits; - uint32_t subTexelPrecisionBits; - uint32_t mipmapPrecisionBits; - uint32_t maxDrawIndexedIndexValue; - uint32_t maxDrawIndirectCount; - float maxSamplerLodBias; - float maxSamplerAnisotropy; - uint32_t maxViewports; - uint32_t maxViewportDimensions[2]; - float viewportBoundsRange[2]; - uint32_t viewportSubPixelBits; - size_t minMemoryMapAlignment; - VkDeviceSize minTexelBufferOffsetAlignment; - VkDeviceSize minUniformBufferOffsetAlignment; - VkDeviceSize minStorageBufferOffsetAlignment; - int32_t minTexelOffset; - uint32_t maxTexelOffset; - int32_t minTexelGatherOffset; - uint32_t maxTexelGatherOffset; - float minInterpolationOffset; - float maxInterpolationOffset; - uint32_t subPixelInterpolationOffsetBits; - uint32_t maxFramebufferWidth; - uint32_t maxFramebufferHeight; - uint32_t maxFramebufferLayers; - VkSampleCountFlags framebufferColorSampleCounts; - VkSampleCountFlags framebufferDepthSampleCounts; - VkSampleCountFlags framebufferStencilSampleCounts; - VkSampleCountFlags framebufferNoAttachmentsSampleCounts; - uint32_t maxColorAttachments; - VkSampleCountFlags sampledImageColorSampleCounts; - VkSampleCountFlags sampledImageIntegerSampleCounts; - VkSampleCountFlags sampledImageDepthSampleCounts; - VkSampleCountFlags sampledImageStencilSampleCounts; - VkSampleCountFlags storageImageSampleCounts; - uint32_t maxSampleMaskWords; - VkBool32 timestampComputeAndGraphics; - float timestampPeriod; - uint32_t maxClipDistances; - uint32_t maxCullDistances; - uint32_t maxCombinedClipAndCullDistances; - uint32_t discreteQueuePriorities; - float pointSizeRange[2]; - float lineWidthRange[2]; - float pointSizeGranularity; - float lineWidthGranularity; - VkBool32 strictLines; - VkBool32 standardSampleLocations; - VkDeviceSize optimalBufferCopyOffsetAlignment; - VkDeviceSize optimalBufferCopyRowPitchAlignment; - VkDeviceSize nonCoherentAtomSize; -} VkPhysicalDeviceLimits; - -typedef struct VkPhysicalDeviceSparseProperties { - VkBool32 residencyStandard2DBlockShape; - VkBool32 residencyStandard2DMultisampleBlockShape; - VkBool32 residencyStandard3DBlockShape; - VkBool32 residencyAlignedMipSize; - VkBool32 residencyNonResidentStrict; -} VkPhysicalDeviceSparseProperties; - -typedef struct VkPhysicalDeviceProperties { - uint32_t apiVersion; - uint32_t driverVersion; - uint32_t vendorID; - uint32_t deviceID; - VkPhysicalDeviceType deviceType; - char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; - uint8_t pipelineCacheUUID[VK_UUID_SIZE]; - VkPhysicalDeviceLimits limits; - VkPhysicalDeviceSparseProperties sparseProperties; -} VkPhysicalDeviceProperties; - -typedef struct VkQueueFamilyProperties { - VkQueueFlags queueFlags; - uint32_t queueCount; - uint32_t timestampValidBits; - VkExtent3D minImageTransferGranularity; -} VkQueueFamilyProperties; - -typedef struct VkMemoryType { - VkMemoryPropertyFlags propertyFlags; - uint32_t heapIndex; -} VkMemoryType; - -typedef struct VkMemoryHeap { - VkDeviceSize size; - VkMemoryHeapFlags flags; -} VkMemoryHeap; - -typedef struct VkPhysicalDeviceMemoryProperties { - uint32_t memoryTypeCount; - VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; - uint32_t memoryHeapCount; - VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; -} VkPhysicalDeviceMemoryProperties; - -typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); -typedef struct VkDeviceQueueCreateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceQueueCreateFlags flags; - uint32_t queueFamilyIndex; - uint32_t queueCount; - const float* pQueuePriorities; -} VkDeviceQueueCreateInfo; - -typedef struct VkDeviceCreateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceCreateFlags flags; - uint32_t queueCreateInfoCount; - const VkDeviceQueueCreateInfo* pQueueCreateInfos; - uint32_t enabledLayerCount; - const char* const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char* const* ppEnabledExtensionNames; - const VkPhysicalDeviceFeatures* pEnabledFeatures; -} VkDeviceCreateInfo; - -typedef struct VkExtensionProperties { - char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; - uint32_t specVersion; -} VkExtensionProperties; - -typedef struct VkLayerProperties { - char layerName[VK_MAX_EXTENSION_NAME_SIZE]; - uint32_t specVersion; - uint32_t implementationVersion; - char description[VK_MAX_DESCRIPTION_SIZE]; -} VkLayerProperties; - -typedef struct VkSubmitInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - const VkPipelineStageFlags* pWaitDstStageMask; - uint32_t commandBufferCount; - const VkCommandBuffer* pCommandBuffers; - uint32_t signalSemaphoreCount; - const VkSemaphore* pSignalSemaphores; -} VkSubmitInfo; - -typedef struct VkMemoryAllocateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceSize allocationSize; - uint32_t memoryTypeIndex; -} VkMemoryAllocateInfo; - -typedef struct VkMappedMemoryRange { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkDeviceSize offset; - VkDeviceSize size; -} VkMappedMemoryRange; - -typedef struct VkMemoryRequirements { - VkDeviceSize size; - VkDeviceSize alignment; - uint32_t memoryTypeBits; -} VkMemoryRequirements; - -typedef struct VkSparseImageFormatProperties { - VkImageAspectFlags aspectMask; - VkExtent3D imageGranularity; - VkSparseImageFormatFlags flags; -} VkSparseImageFormatProperties; - -typedef struct VkSparseImageMemoryRequirements { - VkSparseImageFormatProperties formatProperties; - uint32_t imageMipTailFirstLod; - VkDeviceSize imageMipTailSize; - VkDeviceSize imageMipTailOffset; - VkDeviceSize imageMipTailStride; -} VkSparseImageMemoryRequirements; - -typedef struct VkSparseMemoryBind { - VkDeviceSize resourceOffset; - VkDeviceSize size; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseMemoryBind; - -typedef struct VkSparseBufferMemoryBindInfo { - VkBuffer buffer; - uint32_t bindCount; - const VkSparseMemoryBind* pBinds; -} VkSparseBufferMemoryBindInfo; - -typedef struct VkSparseImageOpaqueMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseMemoryBind* pBinds; -} VkSparseImageOpaqueMemoryBindInfo; - -typedef struct VkImageSubresource { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t arrayLayer; -} VkImageSubresource; - -typedef struct VkOffset3D { - int32_t x; - int32_t y; - int32_t z; -} VkOffset3D; - -typedef struct VkSparseImageMemoryBind { - VkImageSubresource subresource; - VkOffset3D offset; - VkExtent3D extent; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseImageMemoryBind; - -typedef struct VkSparseImageMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseImageMemoryBind* pBinds; -} VkSparseImageMemoryBindInfo; - -typedef struct VkBindSparseInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - uint32_t bufferBindCount; - const VkSparseBufferMemoryBindInfo* pBufferBinds; - uint32_t imageOpaqueBindCount; - const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; - uint32_t imageBindCount; - const VkSparseImageMemoryBindInfo* pImageBinds; - uint32_t signalSemaphoreCount; - const VkSemaphore* pSignalSemaphores; -} VkBindSparseInfo; - -typedef struct VkFenceCreateInfo { - VkStructureType sType; - const void* pNext; - VkFenceCreateFlags flags; -} VkFenceCreateInfo; - -typedef struct VkSemaphoreCreateInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreCreateFlags flags; -} VkSemaphoreCreateInfo; - -typedef struct VkEventCreateInfo { - VkStructureType sType; - const void* pNext; - VkEventCreateFlags flags; -} VkEventCreateInfo; - -typedef struct VkQueryPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkQueryPoolCreateFlags flags; - VkQueryType queryType; - uint32_t queryCount; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkQueryPoolCreateInfo; - -typedef struct VkBufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkBufferCreateFlags flags; - VkDeviceSize size; - VkBufferUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; -} VkBufferCreateInfo; - -typedef struct VkBufferViewCreateInfo { - VkStructureType sType; - const void* pNext; - VkBufferViewCreateFlags flags; - VkBuffer buffer; - VkFormat format; - VkDeviceSize offset; - VkDeviceSize range; -} VkBufferViewCreateInfo; - -typedef struct VkImageCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageCreateFlags flags; - VkImageType imageType; - VkFormat format; - VkExtent3D extent; - uint32_t mipLevels; - uint32_t arrayLayers; - VkSampleCountFlagBits samples; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; - VkImageLayout initialLayout; -} VkImageCreateInfo; - -typedef struct VkSubresourceLayout { - VkDeviceSize offset; - VkDeviceSize size; - VkDeviceSize rowPitch; - VkDeviceSize arrayPitch; - VkDeviceSize depthPitch; -} VkSubresourceLayout; - -typedef struct VkComponentMapping { - VkComponentSwizzle r; - VkComponentSwizzle g; - VkComponentSwizzle b; - VkComponentSwizzle a; -} VkComponentMapping; - -typedef struct VkImageSubresourceRange { - VkImageAspectFlags aspectMask; - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceRange; - -typedef struct VkImageViewCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageViewCreateFlags flags; - VkImage image; - VkImageViewType viewType; - VkFormat format; - VkComponentMapping components; - VkImageSubresourceRange subresourceRange; -} VkImageViewCreateInfo; - -typedef struct VkShaderModuleCreateInfo { - VkStructureType sType; - const void* pNext; - VkShaderModuleCreateFlags flags; - size_t codeSize; - const uint32_t* pCode; -} VkShaderModuleCreateInfo; - -typedef struct VkPipelineCacheCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCacheCreateFlags flags; - size_t initialDataSize; - const void* pInitialData; -} VkPipelineCacheCreateInfo; - -typedef struct VkSpecializationMapEntry { - uint32_t constantID; - uint32_t offset; - size_t size; -} VkSpecializationMapEntry; - -typedef struct VkSpecializationInfo { - uint32_t mapEntryCount; - const VkSpecializationMapEntry* pMapEntries; - size_t dataSize; - const void* pData; -} VkSpecializationInfo; - -typedef struct VkPipelineShaderStageCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineShaderStageCreateFlags flags; - VkShaderStageFlagBits stage; - VkShaderModule module; - const char* pName; - const VkSpecializationInfo* pSpecializationInfo; -} VkPipelineShaderStageCreateInfo; - -typedef struct VkVertexInputBindingDescription { - uint32_t binding; - uint32_t stride; - VkVertexInputRate inputRate; -} VkVertexInputBindingDescription; - -typedef struct VkVertexInputAttributeDescription { - uint32_t location; - uint32_t binding; - VkFormat format; - uint32_t offset; -} VkVertexInputAttributeDescription; - -typedef struct VkPipelineVertexInputStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineVertexInputStateCreateFlags flags; - uint32_t vertexBindingDescriptionCount; - const VkVertexInputBindingDescription* pVertexBindingDescriptions; - uint32_t vertexAttributeDescriptionCount; - const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; -} VkPipelineVertexInputStateCreateInfo; - -typedef struct VkPipelineInputAssemblyStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineInputAssemblyStateCreateFlags flags; - VkPrimitiveTopology topology; - VkBool32 primitiveRestartEnable; -} VkPipelineInputAssemblyStateCreateInfo; - -typedef struct VkPipelineTessellationStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineTessellationStateCreateFlags flags; - uint32_t patchControlPoints; -} VkPipelineTessellationStateCreateInfo; - -typedef struct VkViewport { - float x; - float y; - float width; - float height; - float minDepth; - float maxDepth; -} VkViewport; - -typedef struct VkOffset2D { - int32_t x; - int32_t y; -} VkOffset2D; - -typedef struct VkExtent2D { - uint32_t width; - uint32_t height; -} VkExtent2D; - -typedef struct VkRect2D { - VkOffset2D offset; - VkExtent2D extent; -} VkRect2D; - -typedef struct VkPipelineViewportStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineViewportStateCreateFlags flags; - uint32_t viewportCount; - const VkViewport* pViewports; - uint32_t scissorCount; - const VkRect2D* pScissors; -} VkPipelineViewportStateCreateInfo; - -typedef struct VkPipelineRasterizationStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineRasterizationStateCreateFlags flags; - VkBool32 depthClampEnable; - VkBool32 rasterizerDiscardEnable; - VkPolygonMode polygonMode; - VkCullModeFlags cullMode; - VkFrontFace frontFace; - VkBool32 depthBiasEnable; - float depthBiasConstantFactor; - float depthBiasClamp; - float depthBiasSlopeFactor; - float lineWidth; -} VkPipelineRasterizationStateCreateInfo; - -typedef struct VkPipelineMultisampleStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineMultisampleStateCreateFlags flags; - VkSampleCountFlagBits rasterizationSamples; - VkBool32 sampleShadingEnable; - float minSampleShading; - const VkSampleMask* pSampleMask; - VkBool32 alphaToCoverageEnable; - VkBool32 alphaToOneEnable; -} VkPipelineMultisampleStateCreateInfo; - -typedef struct VkStencilOpState { - VkStencilOp failOp; - VkStencilOp passOp; - VkStencilOp depthFailOp; - VkCompareOp compareOp; - uint32_t compareMask; - uint32_t writeMask; - uint32_t reference; -} VkStencilOpState; - -typedef struct VkPipelineDepthStencilStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineDepthStencilStateCreateFlags flags; - VkBool32 depthTestEnable; - VkBool32 depthWriteEnable; - VkCompareOp depthCompareOp; - VkBool32 depthBoundsTestEnable; - VkBool32 stencilTestEnable; - VkStencilOpState front; - VkStencilOpState back; - float minDepthBounds; - float maxDepthBounds; -} VkPipelineDepthStencilStateCreateInfo; - -typedef struct VkPipelineColorBlendAttachmentState { - VkBool32 blendEnable; - VkBlendFactor srcColorBlendFactor; - VkBlendFactor dstColorBlendFactor; - VkBlendOp colorBlendOp; - VkBlendFactor srcAlphaBlendFactor; - VkBlendFactor dstAlphaBlendFactor; - VkBlendOp alphaBlendOp; - VkColorComponentFlags colorWriteMask; -} VkPipelineColorBlendAttachmentState; - -typedef struct VkPipelineColorBlendStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineColorBlendStateCreateFlags flags; - VkBool32 logicOpEnable; - VkLogicOp logicOp; - uint32_t attachmentCount; - const VkPipelineColorBlendAttachmentState* pAttachments; - float blendConstants[4]; -} VkPipelineColorBlendStateCreateInfo; - -typedef struct VkPipelineDynamicStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineDynamicStateCreateFlags flags; - uint32_t dynamicStateCount; - const VkDynamicState* pDynamicStates; -} VkPipelineDynamicStateCreateInfo; - -typedef struct VkGraphicsPipelineCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo* pStages; - const VkPipelineVertexInputStateCreateInfo* pVertexInputState; - const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; - const VkPipelineTessellationStateCreateInfo* pTessellationState; - const VkPipelineViewportStateCreateInfo* pViewportState; - const VkPipelineRasterizationStateCreateInfo* pRasterizationState; - const VkPipelineMultisampleStateCreateInfo* pMultisampleState; - const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; - const VkPipelineColorBlendStateCreateInfo* pColorBlendState; - const VkPipelineDynamicStateCreateInfo* pDynamicState; - VkPipelineLayout layout; - VkRenderPass renderPass; - uint32_t subpass; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkGraphicsPipelineCreateInfo; - -typedef struct VkComputePipelineCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - VkPipelineShaderStageCreateInfo stage; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkComputePipelineCreateInfo; - -typedef struct VkPushConstantRange { - VkShaderStageFlags stageFlags; - uint32_t offset; - uint32_t size; -} VkPushConstantRange; - -typedef struct VkPipelineLayoutCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineLayoutCreateFlags flags; - uint32_t setLayoutCount; - const VkDescriptorSetLayout* pSetLayouts; - uint32_t pushConstantRangeCount; - const VkPushConstantRange* pPushConstantRanges; -} VkPipelineLayoutCreateInfo; - -typedef struct VkSamplerCreateInfo { - VkStructureType sType; - const void* pNext; - VkSamplerCreateFlags flags; - VkFilter magFilter; - VkFilter minFilter; - VkSamplerMipmapMode mipmapMode; - VkSamplerAddressMode addressModeU; - VkSamplerAddressMode addressModeV; - VkSamplerAddressMode addressModeW; - float mipLodBias; - VkBool32 anisotropyEnable; - float maxAnisotropy; - VkBool32 compareEnable; - VkCompareOp compareOp; - float minLod; - float maxLod; - VkBorderColor borderColor; - VkBool32 unnormalizedCoordinates; -} VkSamplerCreateInfo; - -typedef struct VkDescriptorSetLayoutBinding { - uint32_t binding; - VkDescriptorType descriptorType; - uint32_t descriptorCount; - VkShaderStageFlags stageFlags; - const VkSampler* pImmutableSamplers; -} VkDescriptorSetLayoutBinding; - -typedef struct VkDescriptorSetLayoutCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorSetLayoutCreateFlags flags; - uint32_t bindingCount; - const VkDescriptorSetLayoutBinding* pBindings; -} VkDescriptorSetLayoutCreateInfo; - -typedef struct VkDescriptorPoolSize { - VkDescriptorType type; - uint32_t descriptorCount; -} VkDescriptorPoolSize; - -typedef struct VkDescriptorPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorPoolCreateFlags flags; - uint32_t maxSets; - uint32_t poolSizeCount; - const VkDescriptorPoolSize* pPoolSizes; -} VkDescriptorPoolCreateInfo; - -typedef struct VkDescriptorSetAllocateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorPool descriptorPool; - uint32_t descriptorSetCount; - const VkDescriptorSetLayout* pSetLayouts; -} VkDescriptorSetAllocateInfo; - -typedef struct VkDescriptorImageInfo { - VkSampler sampler; - VkImageView imageView; - VkImageLayout imageLayout; -} VkDescriptorImageInfo; - -typedef struct VkDescriptorBufferInfo { - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize range; -} VkDescriptorBufferInfo; - -typedef struct VkWriteDescriptorSet { - VkStructureType sType; - const void* pNext; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - const VkDescriptorImageInfo* pImageInfo; - const VkDescriptorBufferInfo* pBufferInfo; - const VkBufferView* pTexelBufferView; -} VkWriteDescriptorSet; - -typedef struct VkCopyDescriptorSet { - VkStructureType sType; - const void* pNext; - VkDescriptorSet srcSet; - uint32_t srcBinding; - uint32_t srcArrayElement; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; -} VkCopyDescriptorSet; - -typedef struct VkFramebufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkFramebufferCreateFlags flags; - VkRenderPass renderPass; - uint32_t attachmentCount; - const VkImageView* pAttachments; - uint32_t width; - uint32_t height; - uint32_t layers; -} VkFramebufferCreateInfo; - -typedef struct VkAttachmentDescription { - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription; - -typedef struct VkAttachmentReference { - uint32_t attachment; - VkImageLayout layout; -} VkAttachmentReference; - -typedef struct VkSubpassDescription { - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t inputAttachmentCount; - const VkAttachmentReference* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference* pColorAttachments; - const VkAttachmentReference* pResolveAttachments; - const VkAttachmentReference* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription; - -typedef struct VkSubpassDependency { - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; -} VkSubpassDependency; - -typedef struct VkRenderPassCreateInfo { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency* pDependencies; -} VkRenderPassCreateInfo; - -typedef struct VkCommandPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkCommandPoolCreateFlags flags; - uint32_t queueFamilyIndex; -} VkCommandPoolCreateInfo; - -typedef struct VkCommandBufferAllocateInfo { - VkStructureType sType; - const void* pNext; - VkCommandPool commandPool; - VkCommandBufferLevel level; - uint32_t commandBufferCount; -} VkCommandBufferAllocateInfo; - -typedef struct VkCommandBufferInheritanceInfo { - VkStructureType sType; - const void* pNext; - VkRenderPass renderPass; - uint32_t subpass; - VkFramebuffer framebuffer; - VkBool32 occlusionQueryEnable; - VkQueryControlFlags queryFlags; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkCommandBufferInheritanceInfo; - -typedef struct VkCommandBufferBeginInfo { - VkStructureType sType; - const void* pNext; - VkCommandBufferUsageFlags flags; - const VkCommandBufferInheritanceInfo* pInheritanceInfo; -} VkCommandBufferBeginInfo; - -typedef struct VkBufferCopy { - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy; - -typedef struct VkImageSubresourceLayers { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceLayers; - -typedef struct VkImageCopy { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy; - -typedef struct VkImageBlit { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit; - -typedef struct VkBufferImageCopy { - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy; - -typedef union VkClearColorValue { - float float32[4]; - int32_t int32[4]; - uint32_t uint32[4]; -} VkClearColorValue; - -typedef struct VkClearDepthStencilValue { - float depth; - uint32_t stencil; -} VkClearDepthStencilValue; - -typedef union VkClearValue { - VkClearColorValue color; - VkClearDepthStencilValue depthStencil; -} VkClearValue; - -typedef struct VkClearAttachment { - VkImageAspectFlags aspectMask; - uint32_t colorAttachment; - VkClearValue clearValue; -} VkClearAttachment; - -typedef struct VkClearRect { - VkRect2D rect; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkClearRect; - -typedef struct VkImageResolve { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve; - -typedef struct VkMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; -} VkMemoryBarrier; - -typedef struct VkBufferMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier; - -typedef struct VkImageMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier; - -typedef struct VkRenderPassBeginInfo { - VkStructureType sType; - const void* pNext; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - VkRect2D renderArea; - uint32_t clearValueCount; - const VkClearValue* pClearValues; -} VkRenderPassBeginInfo; - -typedef struct VkDispatchIndirectCommand { - uint32_t x; - uint32_t y; - uint32_t z; -} VkDispatchIndirectCommand; - -typedef struct VkDrawIndexedIndirectCommand { - uint32_t indexCount; - uint32_t instanceCount; - uint32_t firstIndex; - int32_t vertexOffset; - uint32_t firstInstance; -} VkDrawIndexedIndirectCommand; - -typedef struct VkDrawIndirectCommand { - uint32_t vertexCount; - uint32_t instanceCount; - uint32_t firstVertex; - uint32_t firstInstance; -} VkDrawIndirectCommand; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); -typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); -typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); -typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); -typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); -typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); -typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); -typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); -typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); -typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); -typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); -typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); -typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); -typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); -typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); -typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); -typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); -typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); -typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); -typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); -typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); -typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); -typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); -typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); -typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); -typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); -typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); -typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); -typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); -typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); -typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); -typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); -typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); -typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); -typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); -typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); -typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); -typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); -typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); -typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); -typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); -typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); -typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); -typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( - const VkInstanceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkInstance* pInstance); - -VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( - VkInstance instance, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures* pFeatures); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties* pFormatProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties* pImageFormatProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties* pQueueFamilyProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties* pMemoryProperties); - -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( - VkInstance instance, - const char* pName); - -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( - VkDevice device, - const char* pName); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice* pDevice); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( - VkDevice device, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( - const char* pLayerName, - uint32_t* pPropertyCount, - VkExtensionProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( - VkPhysicalDevice physicalDevice, - const char* pLayerName, - uint32_t* pPropertyCount, - VkExtensionProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( - uint32_t* pPropertyCount, - VkLayerProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkLayerProperties* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( - VkDevice device, - uint32_t queueFamilyIndex, - uint32_t queueIndex, - VkQueue* pQueue); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo* pSubmits, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( - VkQueue queue); - -VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( - VkDevice device); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( - VkDevice device, - const VkMemoryAllocateInfo* pAllocateInfo, - const VkAllocationCallbacks* pAllocator, - VkDeviceMemory* pMemory); - -VKAPI_ATTR void VKAPI_CALL vkFreeMemory( - VkDevice device, - VkDeviceMemory memory, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize offset, - VkDeviceSize size, - VkMemoryMapFlags flags, - void** ppData); - -VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( - VkDevice device, - VkDeviceMemory memory); - -VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - -VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize* pCommittedMemoryInBytes); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( - VkDevice device, - VkBuffer buffer, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( - VkDevice device, - VkImage image, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - -VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( - VkDevice device, - VkBuffer buffer, - VkMemoryRequirements* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( - VkDevice device, - VkImage image, - VkMemoryRequirements* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( - VkDevice device, - VkImage image, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements* pSparseMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage, - VkImageTiling tiling, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( - VkQueue queue, - uint32_t bindInfoCount, - const VkBindSparseInfo* pBindInfo, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( - VkDevice device, - const VkFenceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR void VKAPI_CALL vkDestroyFence( - VkDevice device, - VkFence fence, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( - VkDevice device, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( - VkDevice device, - const VkSemaphoreCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSemaphore* pSemaphore); - -VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( - VkDevice device, - VkSemaphore semaphore, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( - VkDevice device, - const VkEventCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkEvent* pEvent); - -VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( - VkDevice device, - VkEvent event, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( - VkDevice device, - const VkQueryPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkQueryPool* pQueryPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( - VkDevice device, - VkQueryPool queryPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - void* pData, - VkDeviceSize stride, - VkQueryResultFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( - VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer); - -VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( - VkDevice device, - VkBuffer buffer, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( - VkDevice device, - const VkBufferViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBufferView* pView); - -VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( - VkDevice device, - VkBufferView bufferView, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( - VkDevice device, - const VkImageCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage* pImage); - -VKAPI_ATTR void VKAPI_CALL vkDestroyImage( - VkDevice device, - VkImage image, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( - VkDevice device, - VkImage image, - const VkImageSubresource* pSubresource, - VkSubresourceLayout* pLayout); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( - VkDevice device, - const VkImageViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImageView* pView); - -VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( - VkDevice device, - VkImageView imageView, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule); - -VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( - VkDevice device, - VkShaderModule shaderModule, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( - VkDevice device, - VkPipelineCache pipelineCache, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( - VkDevice device, - VkPipelineCache pipelineCache, - size_t* pDataSize, - void* pData); - -VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( - VkDevice device, - VkPipelineCache dstCache, - uint32_t srcCacheCount, - const VkPipelineCache* pSrcCaches); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkGraphicsPipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkComputePipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( - VkDevice device, - VkPipeline pipeline, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( - VkDevice device, - const VkPipelineLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineLayout* pPipelineLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( - VkDevice device, - VkPipelineLayout pipelineLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( - VkDevice device, - const VkSamplerCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSampler* pSampler); - -VKAPI_ATTR void VKAPI_CALL vkDestroySampler( - VkDevice device, - VkSampler sampler, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorSetLayout* pSetLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( - VkDevice device, - VkDescriptorSetLayout descriptorSetLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( - VkDevice device, - const VkDescriptorPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorPool* pDescriptorPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( - VkDevice device, - VkDescriptorPool descriptorPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( - VkDevice device, - VkDescriptorPool descriptorPool, - VkDescriptorPoolResetFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( - VkDevice device, - const VkDescriptorSetAllocateInfo* pAllocateInfo, - VkDescriptorSet* pDescriptorSets); - -VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( - VkDevice device, - VkDescriptorPool descriptorPool, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets); - -VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( - VkDevice device, - uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t descriptorCopyCount, - const VkCopyDescriptorSet* pDescriptorCopies); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( - VkDevice device, - const VkFramebufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFramebuffer* pFramebuffer); - -VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( - VkDevice device, - VkFramebuffer framebuffer, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( - VkDevice device, - const VkRenderPassCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass); - -VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( - VkDevice device, - VkRenderPass renderPass, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( - VkDevice device, - VkRenderPass renderPass, - VkExtent2D* pGranularity); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( - VkDevice device, - const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCommandPool* pCommandPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( - VkDevice device, - VkCommandPool commandPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolResetFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( - VkDevice device, - const VkCommandBufferAllocateInfo* pAllocateInfo, - VkCommandBuffer* pCommandBuffers); - -VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( - VkDevice device, - VkCommandPool commandPool, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); - -VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( - VkCommandBuffer commandBuffer, - VkCommandBufferResetFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewport* pViewports); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( - VkCommandBuffer commandBuffer, - uint32_t firstScissor, - uint32_t scissorCount, - const VkRect2D* pScissors); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( - VkCommandBuffer commandBuffer, - float lineWidth); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( - VkCommandBuffer commandBuffer, - float depthBiasConstantFactor, - float depthBiasClamp, - float depthBiasSlopeFactor); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( - VkCommandBuffer commandBuffer, - const float blendConstants[4]); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( - VkCommandBuffer commandBuffer, - float minDepthBounds, - float maxDepthBounds); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t compareMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t writeMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t reference); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkIndexType indexType); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdDraw( - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( - VkCommandBuffer commandBuffer, - uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - int32_t vertexOffset, - uint32_t firstInstance); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( - VkCommandBuffer commandBuffer, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize dataSize, - const void* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize size, - uint32_t data); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearColorValue* pColor, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearDepthStencilValue* pDepthStencil, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects); - -VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - -VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize stride, - VkQueryResultFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( - VkCommandBuffer commandBuffer, - VkPipelineLayout layout, - VkShaderStageFlags stageFlags, - uint32_t offset, - uint32_t size, - const void* pValues); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents); - -VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( - VkCommandBuffer commandBuffer, - VkSubpassContents contents); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); -#endif - -#define VK_KHR_surface 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) - -#define VK_KHR_SURFACE_SPEC_VERSION 25 -#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" -#define VK_COLORSPACE_SRGB_NONLINEAR_KHR VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - - -typedef enum VkColorSpaceKHR { - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, - VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, - VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, - VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104003, - VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004, - VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005, - VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, - VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, - VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, - VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, - VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, - VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, - VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, - VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, - VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, - VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), - VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkColorSpaceKHR; - -typedef enum VkPresentModeKHR { - VK_PRESENT_MODE_IMMEDIATE_KHR = 0, - VK_PRESENT_MODE_MAILBOX_KHR = 1, - VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, - VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, - VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, - VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), - VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPresentModeKHR; - - -typedef enum VkSurfaceTransformFlagBitsKHR { - VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, - VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, - VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, - VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, - VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, - VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSurfaceTransformFlagBitsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; - -typedef enum VkCompositeAlphaFlagBitsKHR { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, - VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, - VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, - VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkCompositeAlphaFlagBitsKHR; -typedef VkFlags VkCompositeAlphaFlagsKHR; - -typedef struct VkSurfaceCapabilitiesKHR { - uint32_t minImageCount; - uint32_t maxImageCount; - VkExtent2D currentExtent; - VkExtent2D minImageExtent; - VkExtent2D maxImageExtent; - uint32_t maxImageArrayLayers; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkSurfaceTransformFlagBitsKHR currentTransform; - VkCompositeAlphaFlagsKHR supportedCompositeAlpha; - VkImageUsageFlags supportedUsageFlags; -} VkSurfaceCapabilitiesKHR; - -typedef struct VkSurfaceFormatKHR { - VkFormat format; - VkColorSpaceKHR colorSpace; -} VkSurfaceFormatKHR; - - -typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( - VkInstance instance, - VkSurfaceKHR surface, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - VkSurfaceKHR surface, - VkBool32* pSupported); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormatKHR* pSurfaceFormats); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pPresentModeCount, - VkPresentModeKHR* pPresentModes); -#endif - -#define VK_KHR_swapchain 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) - -#define VK_KHR_SWAPCHAIN_SPEC_VERSION 68 -#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" - - -typedef enum VkSwapchainCreateFlagBitsKHR { - VK_SWAPCHAIN_CREATE_BIND_SFR_BIT_KHX = 0x00000001, - VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSwapchainCreateFlagBitsKHR; -typedef VkFlags VkSwapchainCreateFlagsKHR; - -typedef struct VkSwapchainCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkSwapchainCreateFlagsKHR flags; - VkSurfaceKHR surface; - uint32_t minImageCount; - VkFormat imageFormat; - VkColorSpaceKHR imageColorSpace; - VkExtent2D imageExtent; - uint32_t imageArrayLayers; - VkImageUsageFlags imageUsage; - VkSharingMode imageSharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; - VkSurfaceTransformFlagBitsKHR preTransform; - VkCompositeAlphaFlagBitsKHR compositeAlpha; - VkPresentModeKHR presentMode; - VkBool32 clipped; - VkSwapchainKHR oldSwapchain; -} VkSwapchainCreateInfoKHR; - -typedef struct VkPresentInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - uint32_t swapchainCount; - const VkSwapchainKHR* pSwapchains; - const uint32_t* pImageIndices; - VkResult* pResults; -} VkPresentInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); -typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); -typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( - VkDevice device, - const VkSwapchainCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchain); - -VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( - VkDevice device, - VkSwapchainKHR swapchain, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pSwapchainImageCount, - VkImage* pSwapchainImages); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint64_t timeout, - VkSemaphore semaphore, - VkFence fence, - uint32_t* pImageIndex); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( - VkQueue queue, - const VkPresentInfoKHR* pPresentInfo); -#endif - -#define VK_KHR_display 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) - -#define VK_KHR_DISPLAY_SPEC_VERSION 21 -#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" - - -typedef enum VkDisplayPlaneAlphaFlagBitsKHR { - VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, - VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, - VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDisplayPlaneAlphaFlagBitsKHR; -typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; -typedef VkFlags VkDisplayModeCreateFlagsKHR; -typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; - -typedef struct VkDisplayPropertiesKHR { - VkDisplayKHR display; - const char* displayName; - VkExtent2D physicalDimensions; - VkExtent2D physicalResolution; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkBool32 planeReorderPossible; - VkBool32 persistentContent; -} VkDisplayPropertiesKHR; - -typedef struct VkDisplayModeParametersKHR { - VkExtent2D visibleRegion; - uint32_t refreshRate; -} VkDisplayModeParametersKHR; - -typedef struct VkDisplayModePropertiesKHR { - VkDisplayModeKHR displayMode; - VkDisplayModeParametersKHR parameters; -} VkDisplayModePropertiesKHR; - -typedef struct VkDisplayModeCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDisplayModeCreateFlagsKHR flags; - VkDisplayModeParametersKHR parameters; -} VkDisplayModeCreateInfoKHR; - -typedef struct VkDisplayPlaneCapabilitiesKHR { - VkDisplayPlaneAlphaFlagsKHR supportedAlpha; - VkOffset2D minSrcPosition; - VkOffset2D maxSrcPosition; - VkExtent2D minSrcExtent; - VkExtent2D maxSrcExtent; - VkOffset2D minDstPosition; - VkOffset2D maxDstPosition; - VkExtent2D minDstExtent; - VkExtent2D maxDstExtent; -} VkDisplayPlaneCapabilitiesKHR; - -typedef struct VkDisplayPlanePropertiesKHR { - VkDisplayKHR currentDisplay; - uint32_t currentStackIndex; -} VkDisplayPlanePropertiesKHR; - -typedef struct VkDisplaySurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDisplaySurfaceCreateFlagsKHR flags; - VkDisplayModeKHR displayMode; - uint32_t planeIndex; - uint32_t planeStackIndex; - VkSurfaceTransformFlagBitsKHR transform; - float globalAlpha; - VkDisplayPlaneAlphaFlagBitsKHR alphaMode; - VkExtent2D imageExtent; -} VkDisplaySurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayPropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayPlanePropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( - VkPhysicalDevice physicalDevice, - uint32_t planeIndex, - uint32_t* pDisplayCount, - VkDisplayKHR* pDisplays); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display, - uint32_t* pPropertyCount, - VkDisplayModePropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display, - const VkDisplayModeCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDisplayModeKHR* pMode); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( - VkPhysicalDevice physicalDevice, - VkDisplayModeKHR mode, - uint32_t planeIndex, - VkDisplayPlaneCapabilitiesKHR* pCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( - VkInstance instance, - const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif - -#define VK_KHR_display_swapchain 1 -#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9 -#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" - -typedef struct VkDisplayPresentInfoKHR { - VkStructureType sType; - const void* pNext; - VkRect2D srcRect; - VkRect2D dstRect; - VkBool32 persistent; -} VkDisplayPresentInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( - VkDevice device, - uint32_t swapchainCount, - const VkSwapchainCreateInfoKHR* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchains); -#endif - -#ifdef VK_USE_PLATFORM_XLIB_KHR -#define VK_KHR_xlib_surface 1 -#include - -#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 -#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" - -typedef VkFlags VkXlibSurfaceCreateFlagsKHR; - -typedef struct VkXlibSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkXlibSurfaceCreateFlagsKHR flags; - Display* dpy; - Window window; -} VkXlibSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( - VkInstance instance, - const VkXlibSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - Display* dpy, - VisualID visualID); -#endif -#endif /* VK_USE_PLATFORM_XLIB_KHR */ - -#ifdef VK_USE_PLATFORM_XCB_KHR -#define VK_KHR_xcb_surface 1 -#include - -#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 -#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" - -typedef VkFlags VkXcbSurfaceCreateFlagsKHR; - -typedef struct VkXcbSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkXcbSurfaceCreateFlagsKHR flags; - xcb_connection_t* connection; - xcb_window_t window; -} VkXcbSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( - VkInstance instance, - const VkXcbSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - xcb_connection_t* connection, - xcb_visualid_t visual_id); -#endif -#endif /* VK_USE_PLATFORM_XCB_KHR */ - -#ifdef VK_USE_PLATFORM_WAYLAND_KHR -#define VK_KHR_wayland_surface 1 -#include - -#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 -#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" - -typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; - -typedef struct VkWaylandSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkWaylandSurfaceCreateFlagsKHR flags; - struct wl_display* display; - struct wl_surface* surface; -} VkWaylandSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( - VkInstance instance, - const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - struct wl_display* display); -#endif -#endif /* VK_USE_PLATFORM_WAYLAND_KHR */ - -#ifdef VK_USE_PLATFORM_MIR_KHR -#define VK_KHR_mir_surface 1 -#include - -#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4 -#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface" - -typedef VkFlags VkMirSurfaceCreateFlagsKHR; - -typedef struct VkMirSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkMirSurfaceCreateFlagsKHR flags; - MirConnection* connection; - MirSurface* mirSurface; -} VkMirSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( - VkInstance instance, - const VkMirSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - MirConnection* connection); -#endif -#endif /* VK_USE_PLATFORM_MIR_KHR */ +#include "vulkan_core.h" #ifdef VK_USE_PLATFORM_ANDROID_KHR -#define VK_KHR_android_surface 1 -#include - -#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 -#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface" - -typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; - -typedef struct VkAndroidSurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkAndroidSurfaceCreateFlagsKHR flags; - ANativeWindow* window; -} VkAndroidSurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( - VkInstance instance, - const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif -#endif /* VK_USE_PLATFORM_ANDROID_KHR */ - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_KHR_win32_surface 1 -#include - -#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 -#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" - -typedef VkFlags VkWin32SurfaceCreateFlagsKHR; - -typedef struct VkWin32SurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkWin32SurfaceCreateFlagsKHR flags; - HINSTANCE hinstance; - HWND hwnd; -} VkWin32SurfaceCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( - VkInstance instance, - const VkWin32SurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex); -#endif -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHR_sampler_mirror_clamp_to_edge 1 -#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 -#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" - - -#define VK_KHR_get_physical_device_properties2 1 -#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1 -#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" - -typedef struct VkPhysicalDeviceFeatures2KHR { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceFeatures features; -} VkPhysicalDeviceFeatures2KHR; - -typedef struct VkPhysicalDeviceProperties2KHR { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceProperties properties; -} VkPhysicalDeviceProperties2KHR; - -typedef struct VkFormatProperties2KHR { - VkStructureType sType; - void* pNext; - VkFormatProperties formatProperties; -} VkFormatProperties2KHR; - -typedef struct VkImageFormatProperties2KHR { - VkStructureType sType; - void* pNext; - VkImageFormatProperties imageFormatProperties; -} VkImageFormatProperties2KHR; - -typedef struct VkPhysicalDeviceImageFormatInfo2KHR { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkImageType type; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkImageCreateFlags flags; -} VkPhysicalDeviceImageFormatInfo2KHR; - -typedef struct VkQueueFamilyProperties2KHR { - VkStructureType sType; - void* pNext; - VkQueueFamilyProperties queueFamilyProperties; -} VkQueueFamilyProperties2KHR; - -typedef struct VkPhysicalDeviceMemoryProperties2KHR { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceMemoryProperties memoryProperties; -} VkPhysicalDeviceMemoryProperties2KHR; - -typedef struct VkSparseImageFormatProperties2KHR { - VkStructureType sType; - void* pNext; - VkSparseImageFormatProperties properties; -} VkSparseImageFormatProperties2KHR; - -typedef struct VkPhysicalDeviceSparseImageFormatInfo2KHR { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkImageType type; - VkSampleCountFlagBits samples; - VkImageUsageFlags usage; - VkImageTiling tiling; -} VkPhysicalDeviceSparseImageFormatInfo2KHR; - - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2KHR* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2KHR* pFormatProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR* pQueueFamilyProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2KHR* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures2KHR* pFeatures); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties2KHR* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties2KHR* pFormatProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, - VkImageFormatProperties2KHR* pImageFormatProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties2KHR* pQueueFamilyProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties2KHR* pProperties); +#include "vulkan_android.h" #endif -#define VK_KHR_shader_draw_parameters 1 -#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1 -#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters" - -#define VK_KHR_maintenance1 1 -#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" - -typedef VkFlags VkCommandPoolTrimFlagsKHR; - -typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlagsKHR flags); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR( - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolTrimFlagsKHR flags); +#ifdef VK_USE_PLATFORM_IOS_MVK +#include "vulkan_ios.h" #endif -#define VK_KHR_external_memory_capabilities 1 -#define VK_LUID_SIZE_KHR 8 -#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities" - -typedef enum VkExternalMemoryHandleTypeFlagBitsKHR { - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = 0x00000008, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = 0x00000010, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = 0x00000020, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = 0x00000040, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalMemoryHandleTypeFlagBitsKHR; -typedef VkFlags VkExternalMemoryHandleTypeFlagsKHR; - -typedef enum VkExternalMemoryFeatureFlagBitsKHR { - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = 0x00000001, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = 0x00000002, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = 0x00000004, - VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalMemoryFeatureFlagBitsKHR; -typedef VkFlags VkExternalMemoryFeatureFlagsKHR; - -typedef struct VkExternalMemoryPropertiesKHR { - VkExternalMemoryFeatureFlagsKHR externalMemoryFeatures; - VkExternalMemoryHandleTypeFlagsKHR exportFromImportedHandleTypes; - VkExternalMemoryHandleTypeFlagsKHR compatibleHandleTypes; -} VkExternalMemoryPropertiesKHR; - -typedef struct VkPhysicalDeviceExternalImageFormatInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; -} VkPhysicalDeviceExternalImageFormatInfoKHR; - -typedef struct VkExternalImageFormatPropertiesKHR { - VkStructureType sType; - void* pNext; - VkExternalMemoryPropertiesKHR externalMemoryProperties; -} VkExternalImageFormatPropertiesKHR; - -typedef struct VkPhysicalDeviceExternalBufferInfoKHR { - VkStructureType sType; - const void* pNext; - VkBufferCreateFlags flags; - VkBufferUsageFlags usage; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; -} VkPhysicalDeviceExternalBufferInfoKHR; - -typedef struct VkExternalBufferPropertiesKHR { - VkStructureType sType; - void* pNext; - VkExternalMemoryPropertiesKHR externalMemoryProperties; -} VkExternalBufferPropertiesKHR; - -typedef struct VkPhysicalDeviceIDPropertiesKHR { - VkStructureType sType; - void* pNext; - uint8_t deviceUUID[VK_UUID_SIZE]; - uint8_t driverUUID[VK_UUID_SIZE]; - uint8_t deviceLUID[VK_LUID_SIZE_KHR]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; -} VkPhysicalDeviceIDPropertiesKHR; - - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo, VkExternalBufferPropertiesKHR* pExternalBufferProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo, - VkExternalBufferPropertiesKHR* pExternalBufferProperties); +#ifdef VK_USE_PLATFORM_MACOS_MVK +#include "vulkan_macos.h" #endif -#define VK_KHR_external_memory 1 -#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory" -#define VK_QUEUE_FAMILY_EXTERNAL_KHR (~0U-1) -typedef struct VkExternalMemoryImageCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsKHR handleTypes; -} VkExternalMemoryImageCreateInfoKHR; - -typedef struct VkExternalMemoryBufferCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsKHR handleTypes; -} VkExternalMemoryBufferCreateInfoKHR; - -typedef struct VkExportMemoryAllocateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsKHR handleTypes; -} VkExportMemoryAllocateInfoKHR; - - - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_KHR_external_memory_win32 1 -#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32" - -typedef struct VkImportMemoryWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; - HANDLE handle; - LPCWSTR name; -} VkImportMemoryWin32HandleInfoKHR; - -typedef struct VkExportMemoryWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportMemoryWin32HandleInfoKHR; - -typedef struct VkMemoryWin32HandlePropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t memoryTypeBits; -} VkMemoryWin32HandlePropertiesKHR; - -typedef struct VkMemoryGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; -} VkMemoryGetWin32HandleInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHR handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR( - VkDevice device, - const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( - VkDevice device, - VkExternalMemoryHandleTypeFlagBitsKHR handleType, - HANDLE handle, - VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); +#ifdef VK_USE_PLATFORM_MIR_KHR +#include +#include "vulkan_mir.h" #endif -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHR_external_memory_fd 1 -#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd" - -typedef struct VkImportMemoryFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; - int fd; -} VkImportMemoryFdInfoKHR; - -typedef struct VkMemoryFdPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t memoryTypeBits; -} VkMemoryFdPropertiesKHR; - -typedef struct VkMemoryGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkExternalMemoryHandleTypeFlagBitsKHR handleType; -} VkMemoryGetFdInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd); -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHR handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR( - VkDevice device, - const VkMemoryGetFdInfoKHR* pGetFdInfo, - int* pFd); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR( - VkDevice device, - VkExternalMemoryHandleTypeFlagBitsKHR handleType, - int fd, - VkMemoryFdPropertiesKHR* pMemoryFdProperties); -#endif - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_KHR_win32_keyed_mutex 1 -#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1 -#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex" - -typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t acquireCount; - const VkDeviceMemory* pAcquireSyncs; - const uint64_t* pAcquireKeys; - const uint32_t* pAcquireTimeouts; - uint32_t releaseCount; - const VkDeviceMemory* pReleaseSyncs; - const uint64_t* pReleaseKeys; -} VkWin32KeyedMutexAcquireReleaseInfoKHR; - - -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHR_external_semaphore_capabilities 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities" - - -typedef enum VkExternalSemaphoreHandleTypeFlagBitsKHR { - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = 0x00000008, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = 0x00000010, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalSemaphoreHandleTypeFlagBitsKHR; -typedef VkFlags VkExternalSemaphoreHandleTypeFlagsKHR; - -typedef enum VkExternalSemaphoreFeatureFlagBitsKHR { - VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = 0x00000001, - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = 0x00000002, - VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalSemaphoreFeatureFlagBitsKHR; -typedef VkFlags VkExternalSemaphoreFeatureFlagsKHR; - -typedef struct VkPhysicalDeviceExternalSemaphoreInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalSemaphoreHandleTypeFlagBitsKHR handleType; -} VkPhysicalDeviceExternalSemaphoreInfoKHR; - -typedef struct VkExternalSemaphorePropertiesKHR { - VkStructureType sType; - void* pNext; - VkExternalSemaphoreHandleTypeFlagsKHR exportFromImportedHandleTypes; - VkExternalSemaphoreHandleTypeFlagsKHR compatibleHandleTypes; - VkExternalSemaphoreFeatureFlagsKHR externalSemaphoreFeatures; -} VkExternalSemaphorePropertiesKHR; - - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo, VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo, - VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties); -#endif - -#define VK_KHR_external_semaphore 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore" - - -typedef enum VkSemaphoreImportFlagBitsKHR { - VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = 0x00000001, - VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSemaphoreImportFlagBitsKHR; -typedef VkFlags VkSemaphoreImportFlagsKHR; - -typedef struct VkExportSemaphoreCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalSemaphoreHandleTypeFlagsKHR handleTypes; -} VkExportSemaphoreCreateInfoKHR; - - - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_KHR_external_semaphore_win32 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32" - -typedef struct VkImportSemaphoreWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkSemaphoreImportFlagsKHR flags; - VkExternalSemaphoreHandleTypeFlagBitsKHR handleType; - HANDLE handle; - LPCWSTR name; -} VkImportSemaphoreWin32HandleInfoKHR; - -typedef struct VkExportSemaphoreWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportSemaphoreWin32HandleInfoKHR; - -typedef struct VkD3D12FenceSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreValuesCount; - const uint64_t* pWaitSemaphoreValues; - uint32_t signalSemaphoreValuesCount; - const uint64_t* pSignalSemaphoreValues; -} VkD3D12FenceSubmitInfoKHR; - -typedef struct VkSemaphoreGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkExternalSemaphoreHandleTypeFlagBitsKHR handleType; -} VkSemaphoreGetWin32HandleInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR( - VkDevice device, - const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( - VkDevice device, - const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); -#endif -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHR_external_semaphore_fd 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd" - -typedef struct VkImportSemaphoreFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkSemaphoreImportFlagsKHR flags; - VkExternalSemaphoreHandleTypeFlagBitsKHR handleType; - int fd; -} VkImportSemaphoreFdInfoKHR; - -typedef struct VkSemaphoreGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkExternalSemaphoreHandleTypeFlagBitsKHR handleType; -} VkSemaphoreGetFdInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR( - VkDevice device, - const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR( - VkDevice device, - const VkSemaphoreGetFdInfoKHR* pGetFdInfo, - int* pFd); -#endif - -#define VK_KHR_push_descriptor 1 -#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 1 -#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" - -typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t maxPushDescriptors; -} VkPhysicalDevicePushDescriptorPropertiesKHR; - - -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t set, - uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites); -#endif - -#define VK_KHR_16bit_storage 1 -#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 -#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" - -typedef struct VkPhysicalDevice16BitStorageFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; -} VkPhysicalDevice16BitStorageFeaturesKHR; - - - -#define VK_KHR_incremental_present 1 -#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 -#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" - -typedef struct VkRectLayerKHR { - VkOffset2D offset; - VkExtent2D extent; - uint32_t layer; -} VkRectLayerKHR; - -typedef struct VkPresentRegionKHR { - uint32_t rectangleCount; - const VkRectLayerKHR* pRectangles; -} VkPresentRegionKHR; - -typedef struct VkPresentRegionsKHR { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkPresentRegionKHR* pRegions; -} VkPresentRegionsKHR; - - - -#define VK_KHR_descriptor_update_template 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplateKHR) - -#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 -#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template" - - -typedef enum VkDescriptorUpdateTemplateTypeKHR { - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = 0, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_BEGIN_RANGE_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_END_RANGE_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_RANGE_SIZE_KHR = (VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR + 1), - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDescriptorUpdateTemplateTypeKHR; - -typedef VkFlags VkDescriptorUpdateTemplateCreateFlagsKHR; - -typedef struct VkDescriptorUpdateTemplateEntryKHR { - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - size_t offset; - size_t stride; -} VkDescriptorUpdateTemplateEntryKHR; - -typedef struct VkDescriptorUpdateTemplateCreateInfoKHR { - VkStructureType sType; - void* pNext; - VkDescriptorUpdateTemplateCreateFlagsKHR flags; - uint32_t descriptorUpdateEntryCount; - const VkDescriptorUpdateTemplateEntryKHR* pDescriptorUpdateEntries; - VkDescriptorUpdateTemplateTypeKHR templateType; - VkDescriptorSetLayout descriptorSetLayout; - VkPipelineBindPoint pipelineBindPoint; - VkPipelineLayout pipelineLayout; - uint32_t set; -} VkDescriptorUpdateTemplateCreateInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR( - VkDevice device, - const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR( - VkDevice device, - VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( - VkDevice device, - VkDescriptorSet descriptorSet, - VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, - const void* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( - VkCommandBuffer commandBuffer, - VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, - VkPipelineLayout layout, - uint32_t set, - const void* pData); -#endif - -#define VK_KHR_shared_presentable_image 1 -#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 -#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image" - -typedef struct VkSharedPresentSurfaceCapabilitiesKHR { - VkStructureType sType; - void* pNext; - VkImageUsageFlags sharedPresentSupportedUsageFlags; -} VkSharedPresentSurfaceCapabilitiesKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR( - VkDevice device, - VkSwapchainKHR swapchain); -#endif - -#define VK_KHR_external_fence_capabilities 1 -#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities" - - -typedef enum VkExternalFenceHandleTypeFlagBitsKHR { - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004, - VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = 0x00000008, - VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalFenceHandleTypeFlagBitsKHR; -typedef VkFlags VkExternalFenceHandleTypeFlagsKHR; - -typedef enum VkExternalFenceFeatureFlagBitsKHR { - VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = 0x00000001, - VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = 0x00000002, - VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkExternalFenceFeatureFlagBitsKHR; -typedef VkFlags VkExternalFenceFeatureFlagsKHR; - -typedef struct VkPhysicalDeviceExternalFenceInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalFenceHandleTypeFlagBitsKHR handleType; -} VkPhysicalDeviceExternalFenceInfoKHR; - -typedef struct VkExternalFencePropertiesKHR { - VkStructureType sType; - void* pNext; - VkExternalFenceHandleTypeFlagsKHR exportFromImportedHandleTypes; - VkExternalFenceHandleTypeFlagsKHR compatibleHandleTypes; - VkExternalFenceFeatureFlagsKHR externalFenceFeatures; -} VkExternalFencePropertiesKHR; - - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR* pExternalFenceInfo, VkExternalFencePropertiesKHR* pExternalFenceProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalFenceInfoKHR* pExternalFenceInfo, - VkExternalFencePropertiesKHR* pExternalFenceProperties); -#endif - -#define VK_KHR_external_fence 1 -#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence" - - -typedef enum VkFenceImportFlagBitsKHR { - VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = 0x00000001, - VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkFenceImportFlagBitsKHR; -typedef VkFlags VkFenceImportFlagsKHR; - -typedef struct VkExportFenceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalFenceHandleTypeFlagsKHR handleTypes; -} VkExportFenceCreateInfoKHR; - - - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_KHR_external_fence_win32 1 -#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32" - -typedef struct VkImportFenceWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkFenceImportFlagsKHR flags; - VkExternalFenceHandleTypeFlagBitsKHR handleType; - HANDLE handle; - LPCWSTR name; -} VkImportFenceWin32HandleInfoKHR; - -typedef struct VkExportFenceWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportFenceWin32HandleInfoKHR; - -typedef struct VkFenceGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkExternalFenceHandleTypeFlagBitsKHR handleType; -} VkFenceGetWin32HandleInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR( - VkDevice device, - const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( - VkDevice device, - const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); -#endif -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHR_external_fence_fd 1 -#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd" - -typedef struct VkImportFenceFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkFenceImportFlagsKHR flags; - VkExternalFenceHandleTypeFlagBitsKHR handleType; - int fd; -} VkImportFenceFdInfoKHR; - -typedef struct VkFenceGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkExternalFenceHandleTypeFlagBitsKHR handleType; -} VkFenceGetFdInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR( - VkDevice device, - const VkImportFenceFdInfoKHR* pImportFenceFdInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( - VkDevice device, - const VkFenceGetFdInfoKHR* pGetFdInfo, - int* pFd); -#endif - -#define VK_KHR_maintenance2 1 -#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" - - -typedef enum VkPointClippingBehaviorKHR { - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = 0, - VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = 1, - VK_POINT_CLIPPING_BEHAVIOR_BEGIN_RANGE_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR, - VK_POINT_CLIPPING_BEHAVIOR_END_RANGE_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR, - VK_POINT_CLIPPING_BEHAVIOR_RANGE_SIZE_KHR = (VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR + 1), - VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPointClippingBehaviorKHR; - -typedef enum VkTessellationDomainOriginKHR { - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = 0, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = 1, - VK_TESSELLATION_DOMAIN_ORIGIN_BEGIN_RANGE_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR, - VK_TESSELLATION_DOMAIN_ORIGIN_END_RANGE_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR, - VK_TESSELLATION_DOMAIN_ORIGIN_RANGE_SIZE_KHR = (VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR + 1), - VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM_KHR = 0x7FFFFFFF -} VkTessellationDomainOriginKHR; - -typedef struct VkPhysicalDevicePointClippingPropertiesKHR { - VkStructureType sType; - void* pNext; - VkPointClippingBehaviorKHR pointClippingBehavior; -} VkPhysicalDevicePointClippingPropertiesKHR; - -typedef struct VkInputAttachmentAspectReferenceKHR { - uint32_t subpass; - uint32_t inputAttachmentIndex; - VkImageAspectFlags aspectMask; -} VkInputAttachmentAspectReferenceKHR; - -typedef struct VkRenderPassInputAttachmentAspectCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t aspectReferenceCount; - const VkInputAttachmentAspectReferenceKHR* pAspectReferences; -} VkRenderPassInputAttachmentAspectCreateInfoKHR; - -typedef struct VkImageViewUsageCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageUsageFlags usage; -} VkImageViewUsageCreateInfoKHR; - -typedef struct VkPipelineTessellationDomainOriginStateCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkTessellationDomainOriginKHR domainOrigin; -} VkPipelineTessellationDomainOriginStateCreateInfoKHR; - - - -#define VK_KHR_get_surface_capabilities2 1 -#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1 -#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2" - -typedef struct VkPhysicalDeviceSurfaceInfo2KHR { - VkStructureType sType; - const void* pNext; - VkSurfaceKHR surface; -} VkPhysicalDeviceSurfaceInfo2KHR; - -typedef struct VkSurfaceCapabilities2KHR { - VkStructureType sType; - void* pNext; - VkSurfaceCapabilitiesKHR surfaceCapabilities; -} VkSurfaceCapabilities2KHR; - -typedef struct VkSurfaceFormat2KHR { - VkStructureType sType; - void* pNext; - VkSurfaceFormatKHR surfaceFormat; -} VkSurfaceFormat2KHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - VkSurfaceCapabilities2KHR* pSurfaceCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormat2KHR* pSurfaceFormats); -#endif - -#define VK_KHR_variable_pointers 1 -#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1 -#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers" - -typedef struct VkPhysicalDeviceVariablePointerFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; -} VkPhysicalDeviceVariablePointerFeaturesKHR; - - - -#define VK_KHR_dedicated_allocation 1 -#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 -#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" - -typedef struct VkMemoryDedicatedRequirementsKHR { - VkStructureType sType; - void* pNext; - VkBool32 prefersDedicatedAllocation; - VkBool32 requiresDedicatedAllocation; -} VkMemoryDedicatedRequirementsKHR; - -typedef struct VkMemoryDedicatedAllocateInfoKHR { - VkStructureType sType; - const void* pNext; - VkImage image; - VkBuffer buffer; -} VkMemoryDedicatedAllocateInfoKHR; - - - -#define VK_KHR_storage_buffer_storage_class 1 -#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1 -#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" - - -#define VK_KHR_relaxed_block_layout 1 -#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 -#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout" - - -#define VK_KHR_get_memory_requirements2 1 -#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 -#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" - -typedef struct VkBufferMemoryRequirementsInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferMemoryRequirementsInfo2KHR; - -typedef struct VkImageMemoryRequirementsInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage image; -} VkImageMemoryRequirementsInfo2KHR; - -typedef struct VkImageSparseMemoryRequirementsInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage image; -} VkImageSparseMemoryRequirementsInfo2KHR; - -typedef struct VkMemoryRequirements2KHR { - VkStructureType sType; - void* pNext; - VkMemoryRequirements memoryRequirements; -} VkMemoryRequirements2KHR; - -typedef struct VkSparseImageMemoryRequirements2KHR { - VkStructureType sType; - void* pNext; - VkSparseImageMemoryRequirements memoryRequirements; -} VkSparseImageMemoryRequirements2KHR; - - -typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2KHR* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR( - VkDevice device, - const VkImageMemoryRequirementsInfo2KHR* pInfo, - VkMemoryRequirements2KHR* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR( - VkDevice device, - const VkBufferMemoryRequirementsInfo2KHR* pInfo, - VkMemoryRequirements2KHR* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( - VkDevice device, - const VkImageSparseMemoryRequirementsInfo2KHR* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements); -#endif - -#define VK_KHR_image_format_list 1 -#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 -#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" - -typedef struct VkImageFormatListCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkImageFormatListCreateInfoKHR; - - - -#define VK_KHR_sampler_ycbcr_conversion 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversionKHR) - -#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 1 -#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" - - -typedef enum VkSamplerYcbcrModelConversionKHR { - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR = 0, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR = 1, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = 2, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = 3, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = 4, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_BEGIN_RANGE_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_END_RANGE_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RANGE_SIZE_KHR = (VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR + 1), - VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSamplerYcbcrModelConversionKHR; - -typedef enum VkSamplerYcbcrRangeKHR { - VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = 0, - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = 1, - VK_SAMPLER_YCBCR_RANGE_BEGIN_RANGE_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR, - VK_SAMPLER_YCBCR_RANGE_END_RANGE_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR, - VK_SAMPLER_YCBCR_RANGE_RANGE_SIZE_KHR = (VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR - VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR + 1), - VK_SAMPLER_YCBCR_RANGE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSamplerYcbcrRangeKHR; - -typedef enum VkChromaLocationKHR { - VK_CHROMA_LOCATION_COSITED_EVEN_KHR = 0, - VK_CHROMA_LOCATION_MIDPOINT_KHR = 1, - VK_CHROMA_LOCATION_BEGIN_RANGE_KHR = VK_CHROMA_LOCATION_COSITED_EVEN_KHR, - VK_CHROMA_LOCATION_END_RANGE_KHR = VK_CHROMA_LOCATION_MIDPOINT_KHR, - VK_CHROMA_LOCATION_RANGE_SIZE_KHR = (VK_CHROMA_LOCATION_MIDPOINT_KHR - VK_CHROMA_LOCATION_COSITED_EVEN_KHR + 1), - VK_CHROMA_LOCATION_MAX_ENUM_KHR = 0x7FFFFFFF -} VkChromaLocationKHR; - -typedef struct VkSamplerYcbcrConversionCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkSamplerYcbcrModelConversionKHR ycbcrModel; - VkSamplerYcbcrRangeKHR ycbcrRange; - VkComponentMapping components; - VkChromaLocationKHR xChromaOffset; - VkChromaLocationKHR yChromaOffset; - VkFilter chromaFilter; - VkBool32 forceExplicitReconstruction; -} VkSamplerYcbcrConversionCreateInfoKHR; - -typedef struct VkSamplerYcbcrConversionInfoKHR { - VkStructureType sType; - const void* pNext; - VkSamplerYcbcrConversionKHR conversion; -} VkSamplerYcbcrConversionInfoKHR; - -typedef struct VkBindImagePlaneMemoryInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageAspectFlagBits planeAspect; -} VkBindImagePlaneMemoryInfoKHR; - -typedef struct VkImagePlaneMemoryRequirementsInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageAspectFlagBits planeAspect; -} VkImagePlaneMemoryRequirementsInfoKHR; - -typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 samplerYcbcrConversion; -} VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR; - -typedef struct VkSamplerYcbcrConversionImageFormatPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t combinedImageSamplerDescriptorCount; -} VkSamplerYcbcrConversionImageFormatPropertiesKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice device, const VkSamplerYcbcrConversionCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversionKHR* pYcbcrConversion); -typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversionKHR ycbcrConversion, const VkAllocationCallbacks* pAllocator); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR( - VkDevice device, - const VkSamplerYcbcrConversionCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSamplerYcbcrConversionKHR* pYcbcrConversion); - -VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR( - VkDevice device, - VkSamplerYcbcrConversionKHR ycbcrConversion, - const VkAllocationCallbacks* pAllocator); -#endif - -#define VK_KHR_bind_memory2 1 -#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1 -#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2" - -typedef struct VkBindBufferMemoryInfoKHR { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindBufferMemoryInfoKHR; - -typedef struct VkBindImageMemoryInfoKHR { - VkStructureType sType; - const void* pNext; - VkImage image; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindImageMemoryInfoKHR; - - -typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfoKHR* pBindInfos); -typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfoKHR* pBindInfos); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR( - VkDevice device, - uint32_t bindInfoCount, - const VkBindBufferMemoryInfoKHR* pBindInfos); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( - VkDevice device, - uint32_t bindInfoCount, - const VkBindImageMemoryInfoKHR* pBindInfos); -#endif - -#define VK_EXT_debug_report 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) - -#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 8 -#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" -#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT -#define VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT - - -typedef enum VkDebugReportObjectTypeEXT { - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, - VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, - VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, - VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, - VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, - VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, - VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, - VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, - VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, - VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, - VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, - VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, - VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, - VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31, - VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32, - VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = 33, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = 1000085000, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = 1000156000, - VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1), - VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportObjectTypeEXT; - - -typedef enum VkDebugReportFlagBitsEXT { - VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, - VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, - VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, - VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, - VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportFlagBitsEXT; -typedef VkFlags VkDebugReportFlagsEXT; - -typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserData); - -typedef struct VkDebugReportCallbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportFlagsEXT flags; - PFN_vkDebugReportCallbackEXT pfnCallback; - void* pUserData; -} VkDebugReportCallbackCreateInfoEXT; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); -typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( - VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( - VkInstance instance, - VkDebugReportCallbackEXT callback, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( - VkInstance instance, - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage); -#endif - -#define VK_NV_glsl_shader 1 -#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 -#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" - - -#define VK_EXT_depth_range_unrestricted 1 -#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1 -#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted" - - -#define VK_IMG_filter_cubic 1 -#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 -#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" - - -#define VK_AMD_rasterization_order 1 -#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 -#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" - - -typedef enum VkRasterizationOrderAMD { - VK_RASTERIZATION_ORDER_STRICT_AMD = 0, - VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, - VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD, - VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD, - VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1), - VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF -} VkRasterizationOrderAMD; - -typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { - VkStructureType sType; - const void* pNext; - VkRasterizationOrderAMD rasterizationOrder; -} VkPipelineRasterizationStateRasterizationOrderAMD; - - - -#define VK_AMD_shader_trinary_minmax 1 -#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1 -#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax" - - -#define VK_AMD_shader_explicit_vertex_parameter 1 -#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1 -#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter" - - -#define VK_EXT_debug_marker 1 -#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4 -#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker" - -typedef struct VkDebugMarkerObjectNameInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportObjectTypeEXT objectType; - uint64_t object; - const char* pObjectName; -} VkDebugMarkerObjectNameInfoEXT; - -typedef struct VkDebugMarkerObjectTagInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportObjectTypeEXT objectType; - uint64_t object; - uint64_t tagName; - size_t tagSize; - const void* pTag; -} VkDebugMarkerObjectTagInfoEXT; - -typedef struct VkDebugMarkerMarkerInfoEXT { - VkStructureType sType; - const void* pNext; - const char* pMarkerName; - float color[4]; -} VkDebugMarkerMarkerInfoEXT; - - -typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo); -typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( - VkDevice device, - const VkDebugMarkerObjectTagInfoEXT* pTagInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( - VkDevice device, - const VkDebugMarkerObjectNameInfoEXT* pNameInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( - VkCommandBuffer commandBuffer, - const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( - VkCommandBuffer commandBuffer, - const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); -#endif - -#define VK_AMD_gcn_shader 1 -#define VK_AMD_GCN_SHADER_SPEC_VERSION 1 -#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader" - - -#define VK_NV_dedicated_allocation 1 -#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1 -#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation" - -typedef struct VkDedicatedAllocationImageCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 dedicatedAllocation; -} VkDedicatedAllocationImageCreateInfoNV; - -typedef struct VkDedicatedAllocationBufferCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 dedicatedAllocation; -} VkDedicatedAllocationBufferCreateInfoNV; - -typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { - VkStructureType sType; - const void* pNext; - VkImage image; - VkBuffer buffer; -} VkDedicatedAllocationMemoryAllocateInfoNV; - - - -#define VK_AMD_draw_indirect_count 1 -#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 -#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" - -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); -#endif - -#define VK_AMD_negative_viewport_height 1 -#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1 -#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height" - - -#define VK_AMD_gpu_shader_half_float 1 -#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1 -#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float" - - -#define VK_AMD_shader_ballot 1 -#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1 -#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot" - - -#define VK_AMD_texture_gather_bias_lod 1 -#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1 -#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod" - -typedef struct VkTextureLODGatherFormatPropertiesAMD { - VkStructureType sType; - void* pNext; - VkBool32 supportsTextureGatherLODBiasAMD; -} VkTextureLODGatherFormatPropertiesAMD; - - - -#define VK_KHX_multiview 1 -#define VK_KHX_MULTIVIEW_SPEC_VERSION 1 -#define VK_KHX_MULTIVIEW_EXTENSION_NAME "VK_KHX_multiview" - -typedef struct VkRenderPassMultiviewCreateInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t subpassCount; - const uint32_t* pViewMasks; - uint32_t dependencyCount; - const int32_t* pViewOffsets; - uint32_t correlationMaskCount; - const uint32_t* pCorrelationMasks; -} VkRenderPassMultiviewCreateInfoKHX; - -typedef struct VkPhysicalDeviceMultiviewFeaturesKHX { - VkStructureType sType; - void* pNext; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; -} VkPhysicalDeviceMultiviewFeaturesKHX; - -typedef struct VkPhysicalDeviceMultiviewPropertiesKHX { - VkStructureType sType; - void* pNext; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; -} VkPhysicalDeviceMultiviewPropertiesKHX; - - - -#define VK_IMG_format_pvrtc 1 -#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 -#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" - - -#define VK_NV_external_memory_capabilities 1 -#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities" - - -typedef enum VkExternalMemoryHandleTypeFlagBitsNV { - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkExternalMemoryHandleTypeFlagBitsNV; -typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; - -typedef enum VkExternalMemoryFeatureFlagBitsNV { - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004, - VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkExternalMemoryFeatureFlagBitsNV; -typedef VkFlags VkExternalMemoryFeatureFlagsNV; - -typedef struct VkExternalImageFormatPropertiesNV { - VkImageFormatProperties imageFormatProperties; - VkExternalMemoryFeatureFlagsNV externalMemoryFeatures; - VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes; - VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes; -} VkExternalImageFormatPropertiesNV; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkExternalMemoryHandleTypeFlagsNV externalHandleType, - VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); -#endif - -#define VK_NV_external_memory 1 -#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory" - -typedef struct VkExternalMemoryImageCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleTypes; -} VkExternalMemoryImageCreateInfoNV; - -typedef struct VkExportMemoryAllocateInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleTypes; -} VkExportMemoryAllocateInfoNV; - - - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_NV_external_memory_win32 1 -#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32" - -typedef struct VkImportMemoryWin32HandleInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleType; - HANDLE handle; -} VkImportMemoryWin32HandleInfoNV; - -typedef struct VkExportMemoryWin32HandleInfoNV { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; -} VkExportMemoryWin32HandleInfoNV; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( - VkDevice device, - VkDeviceMemory memory, - VkExternalMemoryHandleTypeFlagsNV handleType, - HANDLE* pHandle); -#endif -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#define VK_NV_win32_keyed_mutex 1 -#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1 -#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" - -typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t acquireCount; - const VkDeviceMemory* pAcquireSyncs; - const uint64_t* pAcquireKeys; - const uint32_t* pAcquireTimeoutMilliseconds; - uint32_t releaseCount; - const VkDeviceMemory* pReleaseSyncs; - const uint64_t* pReleaseKeys; -} VkWin32KeyedMutexAcquireReleaseInfoNV; - - -#endif /* VK_USE_PLATFORM_WIN32_KHR */ - -#define VK_KHX_device_group 1 -#define VK_KHX_DEVICE_GROUP_SPEC_VERSION 2 -#define VK_KHX_DEVICE_GROUP_EXTENSION_NAME "VK_KHX_device_group" -#define VK_MAX_DEVICE_GROUP_SIZE_KHX 32 - - -typedef enum VkPeerMemoryFeatureFlagBitsKHX { - VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHX = 0x00000001, - VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX = 0x00000002, - VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHX = 0x00000004, - VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHX = 0x00000008, - VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF -} VkPeerMemoryFeatureFlagBitsKHX; -typedef VkFlags VkPeerMemoryFeatureFlagsKHX; - -typedef enum VkMemoryAllocateFlagBitsKHX { - VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX = 0x00000001, - VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF -} VkMemoryAllocateFlagBitsKHX; -typedef VkFlags VkMemoryAllocateFlagsKHX; - -typedef enum VkDeviceGroupPresentModeFlagBitsKHX { - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHX = 0x00000001, - VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHX = 0x00000002, - VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHX = 0x00000004, - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHX = 0x00000008, - VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF -} VkDeviceGroupPresentModeFlagBitsKHX; -typedef VkFlags VkDeviceGroupPresentModeFlagsKHX; - -typedef struct VkMemoryAllocateFlagsInfoKHX { - VkStructureType sType; - const void* pNext; - VkMemoryAllocateFlagsKHX flags; - uint32_t deviceMask; -} VkMemoryAllocateFlagsInfoKHX; - -typedef struct VkDeviceGroupRenderPassBeginInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t deviceMask; - uint32_t deviceRenderAreaCount; - const VkRect2D* pDeviceRenderAreas; -} VkDeviceGroupRenderPassBeginInfoKHX; - -typedef struct VkDeviceGroupCommandBufferBeginInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t deviceMask; -} VkDeviceGroupCommandBufferBeginInfoKHX; - -typedef struct VkDeviceGroupSubmitInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const uint32_t* pWaitSemaphoreDeviceIndices; - uint32_t commandBufferCount; - const uint32_t* pCommandBufferDeviceMasks; - uint32_t signalSemaphoreCount; - const uint32_t* pSignalSemaphoreDeviceIndices; -} VkDeviceGroupSubmitInfoKHX; - -typedef struct VkDeviceGroupBindSparseInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t resourceDeviceIndex; - uint32_t memoryDeviceIndex; -} VkDeviceGroupBindSparseInfoKHX; - -typedef struct VkBindBufferMemoryDeviceGroupInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; -} VkBindBufferMemoryDeviceGroupInfoKHX; - -typedef struct VkBindImageMemoryDeviceGroupInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; - uint32_t SFRRectCount; - const VkRect2D* pSFRRects; -} VkBindImageMemoryDeviceGroupInfoKHX; - -typedef struct VkDeviceGroupPresentCapabilitiesKHX { - VkStructureType sType; - const void* pNext; - uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE_KHX]; - VkDeviceGroupPresentModeFlagsKHX modes; -} VkDeviceGroupPresentCapabilitiesKHX; - -typedef struct VkImageSwapchainCreateInfoKHX { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; -} VkImageSwapchainCreateInfoKHX; - -typedef struct VkBindImageMemorySwapchainInfoKHX { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; - uint32_t imageIndex; -} VkBindImageMemorySwapchainInfoKHX; - -typedef struct VkAcquireNextImageInfoKHX { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; - uint64_t timeout; - VkSemaphore semaphore; - VkFence fence; - uint32_t deviceMask; -} VkAcquireNextImageInfoKHX; - -typedef struct VkDeviceGroupPresentInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const uint32_t* pDeviceMasks; - VkDeviceGroupPresentModeFlagBitsKHX mode; -} VkDeviceGroupPresentInfoKHX; - -typedef struct VkDeviceGroupSwapchainCreateInfoKHX { - VkStructureType sType; - const void* pNext; - VkDeviceGroupPresentModeFlagsKHX modes; -} VkDeviceGroupSwapchainCreateInfoKHX; - - -typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHX)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlagsKHX* pPeerMemoryFeatures); -typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHX)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHX)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHX)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHX* pDeviceGroupPresentCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHX)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHX* pModes); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHX)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHX)(VkDevice device, const VkAcquireNextImageInfoKHX* pAcquireInfo, uint32_t* pImageIndex); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHX( - VkDevice device, - uint32_t heapIndex, - uint32_t localDeviceIndex, - uint32_t remoteDeviceIndex, - VkPeerMemoryFeatureFlagsKHX* pPeerMemoryFeatures); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHX( - VkCommandBuffer commandBuffer, - uint32_t deviceMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHX( - VkCommandBuffer commandBuffer, - uint32_t baseGroupX, - uint32_t baseGroupY, - uint32_t baseGroupZ, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHX( - VkDevice device, - VkDeviceGroupPresentCapabilitiesKHX* pDeviceGroupPresentCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHX( - VkDevice device, - VkSurfaceKHR surface, - VkDeviceGroupPresentModeFlagsKHX* pModes); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHX( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pRectCount, - VkRect2D* pRects); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHX( - VkDevice device, - const VkAcquireNextImageInfoKHX* pAcquireInfo, - uint32_t* pImageIndex); -#endif - -#define VK_EXT_validation_flags 1 -#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1 -#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags" - - -typedef enum VkValidationCheckEXT { - VK_VALIDATION_CHECK_ALL_EXT = 0, - VK_VALIDATION_CHECK_SHADERS_EXT = 1, - VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT, - VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_SHADERS_EXT, - VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_SHADERS_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1), - VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationCheckEXT; - -typedef struct VkValidationFlagsEXT { - VkStructureType sType; - const void* pNext; - uint32_t disabledValidationCheckCount; - VkValidationCheckEXT* pDisabledValidationChecks; -} VkValidationFlagsEXT; - #ifdef VK_USE_PLATFORM_VI_NN -#define VK_NN_vi_surface 1 -#define VK_NN_VI_SURFACE_SPEC_VERSION 1 -#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" - -typedef VkFlags VkViSurfaceCreateFlagsNN; - -typedef struct VkViSurfaceCreateInfoNN { - VkStructureType sType; - const void* pNext; - VkViSurfaceCreateFlagsNN flags; - void* window; -} VkViSurfaceCreateInfoNN; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN( - VkInstance instance, - const VkViSurfaceCreateInfoNN* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif -#endif /* VK_USE_PLATFORM_VI_NN */ - -#define VK_EXT_shader_subgroup_ballot 1 -#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1 -#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot" - - -#define VK_EXT_shader_subgroup_vote 1 -#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1 -#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" - - -#define VK_KHX_device_group_creation 1 -#define VK_KHX_DEVICE_GROUP_CREATION_SPEC_VERSION 1 -#define VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHX_device_group_creation" - -typedef struct VkPhysicalDeviceGroupPropertiesKHX { - VkStructureType sType; - void* pNext; - uint32_t physicalDeviceCount; - VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE_KHX]; - VkBool32 subsetAllocation; -} VkPhysicalDeviceGroupPropertiesKHX; - -typedef struct VkDeviceGroupDeviceCreateInfoKHX { - VkStructureType sType; - const void* pNext; - uint32_t physicalDeviceCount; - const VkPhysicalDevice* pPhysicalDevices; -} VkDeviceGroupDeviceCreateInfoKHX; - - -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHX)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupPropertiesKHX* pPhysicalDeviceGroupProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHX( - VkInstance instance, - uint32_t* pPhysicalDeviceGroupCount, - VkPhysicalDeviceGroupPropertiesKHX* pPhysicalDeviceGroupProperties); +#include "vulkan_vi.h" #endif -#define VK_NVX_device_generated_commands 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX) -#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 -#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands" - - -typedef enum VkIndirectCommandsTokenTypeNVX { - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX = 0, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX = 1, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX = 2, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX = 3, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX = 4, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX = 5, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX = 6, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX = 7, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX + 1), - VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsTokenTypeNVX; - -typedef enum VkObjectEntryTypeNVX { - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX = 0, - VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX = 1, - VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX = 2, - VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX = 3, - VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX = 4, - VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX, - VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX, - VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX + 1), - VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryTypeNVX; - - -typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX { - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsLayoutUsageFlagBitsNVX; -typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX; - -typedef enum VkObjectEntryUsageFlagBitsNVX { - VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001, - VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002, - VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryUsageFlagBitsNVX; -typedef VkFlags VkObjectEntryUsageFlagsNVX; - -typedef struct VkDeviceGeneratedCommandsFeaturesNVX { - VkStructureType sType; - const void* pNext; - VkBool32 computeBindingPointSupport; -} VkDeviceGeneratedCommandsFeaturesNVX; - -typedef struct VkDeviceGeneratedCommandsLimitsNVX { - VkStructureType sType; - const void* pNext; - uint32_t maxIndirectCommandsLayoutTokenCount; - uint32_t maxObjectEntryCounts; - uint32_t minSequenceCountBufferOffsetAlignment; - uint32_t minSequenceIndexBufferOffsetAlignment; - uint32_t minCommandsTokenBufferOffsetAlignment; -} VkDeviceGeneratedCommandsLimitsNVX; - -typedef struct VkIndirectCommandsTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - VkBuffer buffer; - VkDeviceSize offset; -} VkIndirectCommandsTokenNVX; - -typedef struct VkIndirectCommandsLayoutTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - uint32_t bindingUnit; - uint32_t dynamicCount; - uint32_t divisor; -} VkIndirectCommandsLayoutTokenNVX; - -typedef struct VkIndirectCommandsLayoutCreateInfoNVX { - VkStructureType sType; - const void* pNext; - VkPipelineBindPoint pipelineBindPoint; - VkIndirectCommandsLayoutUsageFlagsNVX flags; - uint32_t tokenCount; - const VkIndirectCommandsLayoutTokenNVX* pTokens; -} VkIndirectCommandsLayoutCreateInfoNVX; - -typedef struct VkCmdProcessCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t indirectCommandsTokenCount; - const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens; - uint32_t maxSequencesCount; - VkCommandBuffer targetCommandBuffer; - VkBuffer sequencesCountBuffer; - VkDeviceSize sequencesCountOffset; - VkBuffer sequencesIndexBuffer; - VkDeviceSize sequencesIndexOffset; -} VkCmdProcessCommandsInfoNVX; - -typedef struct VkCmdReserveSpaceForCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t maxSequencesCount; -} VkCmdReserveSpaceForCommandsInfoNVX; - -typedef struct VkObjectTableCreateInfoNVX { - VkStructureType sType; - const void* pNext; - uint32_t objectCount; - const VkObjectEntryTypeNVX* pObjectEntryTypes; - const uint32_t* pObjectEntryCounts; - const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags; - uint32_t maxUniformBuffersPerDescriptor; - uint32_t maxStorageBuffersPerDescriptor; - uint32_t maxStorageImagesPerDescriptor; - uint32_t maxSampledImagesPerDescriptor; - uint32_t maxPipelineLayouts; -} VkObjectTableCreateInfoNVX; - -typedef struct VkObjectTableEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; -} VkObjectTableEntryNVX; - -typedef struct VkObjectTablePipelineEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipeline pipeline; -} VkObjectTablePipelineEntryNVX; - -typedef struct VkObjectTableDescriptorSetEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkDescriptorSet descriptorSet; -} VkObjectTableDescriptorSetEntryNVX; - -typedef struct VkObjectTableVertexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; -} VkObjectTableVertexBufferEntryNVX; - -typedef struct VkObjectTableIndexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; - VkIndexType indexType; -} VkObjectTableIndexBufferEntryNVX; - -typedef struct VkObjectTablePushConstantEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkShaderStageFlags stageFlags; -} VkObjectTablePushConstantEntryNVX; - - -typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable); -typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices); -typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX( - VkDevice device, - const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX( - VkDevice device, - VkIndirectCommandsLayoutNVX indirectCommandsLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX( - VkDevice device, - const VkObjectTableCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkObjectTableNVX* pObjectTable); - -VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX( - VkDevice device, - VkObjectTableNVX objectTable, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectTableEntryNVX* const* ppObjectTableEntries, - const uint32_t* pObjectIndices); - -VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectEntryTypeNVX* pObjectEntryTypes, - const uint32_t* pObjectIndices); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX( - VkPhysicalDevice physicalDevice, - VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, - VkDeviceGeneratedCommandsLimitsNVX* pLimits); +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#include +#include "vulkan_wayland.h" #endif -#define VK_NV_clip_space_w_scaling 1 -#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 -#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" -typedef struct VkViewportWScalingNV { - float xcoeff; - float ycoeff; -} VkViewportWScalingNV; - -typedef struct VkPipelineViewportWScalingStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 viewportWScalingEnable; - uint32_t viewportCount; - const VkViewportWScalingNV* pViewportWScalings; -} VkPipelineViewportWScalingStateCreateInfoNV; - - -typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewportWScalingNV* pViewportWScalings); +#ifdef VK_USE_PLATFORM_WIN32_KHR +#include +#include "vulkan_win32.h" #endif -#define VK_EXT_direct_mode_display 1 -#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1 -#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display" -typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display); +#ifdef VK_USE_PLATFORM_XCB_KHR +#include +#include "vulkan_xcb.h" #endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR +#include +#include "vulkan_xlib.h" +#endif + + #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT -#define VK_EXT_acquire_xlib_display 1 +#include #include - -#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 -#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" - -typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); -typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT( - VkPhysicalDevice physicalDevice, - Display* dpy, - VkDisplayKHR display); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT( - VkPhysicalDevice physicalDevice, - Display* dpy, - RROutput rrOutput, - VkDisplayKHR* pDisplay); -#endif -#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */ - -#define VK_EXT_display_surface_counter 1 -#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1 -#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" -#define VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT - - -typedef enum VkSurfaceCounterFlagBitsEXT { - VK_SURFACE_COUNTER_VBLANK_EXT = 0x00000001, - VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSurfaceCounterFlagBitsEXT; -typedef VkFlags VkSurfaceCounterFlagsEXT; - -typedef struct VkSurfaceCapabilities2EXT { - VkStructureType sType; - void* pNext; - uint32_t minImageCount; - uint32_t maxImageCount; - VkExtent2D currentExtent; - VkExtent2D minImageExtent; - VkExtent2D maxImageExtent; - uint32_t maxImageArrayLayers; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkSurfaceTransformFlagBitsKHR currentTransform; - VkCompositeAlphaFlagsKHR supportedCompositeAlpha; - VkImageUsageFlags supportedUsageFlags; - VkSurfaceCounterFlagsEXT supportedSurfaceCounters; -} VkSurfaceCapabilities2EXT; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilities2EXT* pSurfaceCapabilities); +#include "vulkan_xlib_xrandr.h" #endif -#define VK_EXT_display_control 1 -#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1 -#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control" - - -typedef enum VkDisplayPowerStateEXT { - VK_DISPLAY_POWER_STATE_OFF_EXT = 0, - VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, - VK_DISPLAY_POWER_STATE_ON_EXT = 2, - VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT, - VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT, - VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1), - VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDisplayPowerStateEXT; - -typedef enum VkDeviceEventTypeEXT { - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, - VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1), - VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDeviceEventTypeEXT; - -typedef enum VkDisplayEventTypeEXT { - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, - VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1), - VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDisplayEventTypeEXT; - -typedef struct VkDisplayPowerInfoEXT { - VkStructureType sType; - const void* pNext; - VkDisplayPowerStateEXT powerState; -} VkDisplayPowerInfoEXT; - -typedef struct VkDeviceEventInfoEXT { - VkStructureType sType; - const void* pNext; - VkDeviceEventTypeEXT deviceEvent; -} VkDeviceEventInfoEXT; - -typedef struct VkDisplayEventInfoEXT { - VkStructureType sType; - const void* pNext; - VkDisplayEventTypeEXT displayEvent; -} VkDisplayEventInfoEXT; - -typedef struct VkSwapchainCounterCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkSurfaceCounterFlagsEXT surfaceCounters; -} VkSwapchainCounterCreateInfoEXT; - - -typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT( - VkDevice device, - VkDisplayKHR display, - const VkDisplayPowerInfoEXT* pDisplayPowerInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT( - VkDevice device, - const VkDeviceEventInfoEXT* pDeviceEventInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT( - VkDevice device, - VkDisplayKHR display, - const VkDisplayEventInfoEXT* pDisplayEventInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT( - VkDevice device, - VkSwapchainKHR swapchain, - VkSurfaceCounterFlagBitsEXT counter, - uint64_t* pCounterValue); -#endif - -#define VK_GOOGLE_display_timing 1 -#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 -#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing" - -typedef struct VkRefreshCycleDurationGOOGLE { - uint64_t refreshDuration; -} VkRefreshCycleDurationGOOGLE; - -typedef struct VkPastPresentationTimingGOOGLE { - uint32_t presentID; - uint64_t desiredPresentTime; - uint64_t actualPresentTime; - uint64_t earliestPresentTime; - uint64_t presentMargin; -} VkPastPresentationTimingGOOGLE; - -typedef struct VkPresentTimeGOOGLE { - uint32_t presentID; - uint64_t desiredPresentTime; -} VkPresentTimeGOOGLE; - -typedef struct VkPresentTimesInfoGOOGLE { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkPresentTimeGOOGLE* pTimes; -} VkPresentTimesInfoGOOGLE; - - -typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( - VkDevice device, - VkSwapchainKHR swapchain, - VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pPresentationTimingCount, - VkPastPresentationTimingGOOGLE* pPresentationTimings); -#endif - -#define VK_NV_sample_mask_override_coverage 1 -#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1 -#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage" - - -#define VK_NV_geometry_shader_passthrough 1 -#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1 -#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough" - - -#define VK_NV_viewport_array2 1 -#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2" - - -#define VK_NVX_multiview_per_view_attributes 1 -#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1 -#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes" - -typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX { - VkStructureType sType; - void* pNext; - VkBool32 perViewPositionAllComponents; -} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX; - - - -#define VK_NV_viewport_swizzle 1 -#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle" - - -typedef enum VkViewportCoordinateSwizzleNV { - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, - VK_VIEWPORT_COORDINATE_SWIZZLE_BEGIN_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_END_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_RANGE_SIZE_NV = (VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV + 1), - VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF -} VkViewportCoordinateSwizzleNV; - -typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; - -typedef struct VkViewportSwizzleNV { - VkViewportCoordinateSwizzleNV x; - VkViewportCoordinateSwizzleNV y; - VkViewportCoordinateSwizzleNV z; - VkViewportCoordinateSwizzleNV w; -} VkViewportSwizzleNV; - -typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineViewportSwizzleStateCreateFlagsNV flags; - uint32_t viewportCount; - const VkViewportSwizzleNV* pViewportSwizzles; -} VkPipelineViewportSwizzleStateCreateInfoNV; - - - -#define VK_EXT_discard_rectangles 1 -#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1 -#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles" - - -typedef enum VkDiscardRectangleModeEXT { - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, - VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, - VK_DISCARD_RECTANGLE_MODE_BEGIN_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_END_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_RANGE_SIZE_EXT = (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT + 1), - VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDiscardRectangleModeEXT; - -typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; - -typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxDiscardRectangles; -} VkPhysicalDeviceDiscardRectanglePropertiesEXT; - -typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineDiscardRectangleStateCreateFlagsEXT flags; - VkDiscardRectangleModeEXT discardRectangleMode; - uint32_t discardRectangleCount; - const VkRect2D* pDiscardRectangles; -} VkPipelineDiscardRectangleStateCreateInfoEXT; - - -typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( - VkCommandBuffer commandBuffer, - uint32_t firstDiscardRectangle, - uint32_t discardRectangleCount, - const VkRect2D* pDiscardRectangles); -#endif - -#define VK_EXT_swapchain_colorspace 1 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 3 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" - - -#define VK_EXT_hdr_metadata 1 -#define VK_EXT_HDR_METADATA_SPEC_VERSION 1 -#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" - -typedef struct VkXYColorEXT { - float x; - float y; -} VkXYColorEXT; - -typedef struct VkHdrMetadataEXT { - VkStructureType sType; - const void* pNext; - VkXYColorEXT displayPrimaryRed; - VkXYColorEXT displayPrimaryGreen; - VkXYColorEXT displayPrimaryBlue; - VkXYColorEXT whitePoint; - float maxLuminance; - float minLuminance; - float maxContentLightLevel; - float maxFrameAverageLightLevel; -} VkHdrMetadataEXT; - - -typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( - VkDevice device, - uint32_t swapchainCount, - const VkSwapchainKHR* pSwapchains, - const VkHdrMetadataEXT* pMetadata); -#endif - -#ifdef VK_USE_PLATFORM_IOS_MVK -#define VK_MVK_ios_surface 1 -#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2 -#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" - -typedef VkFlags VkIOSSurfaceCreateFlagsMVK; - -typedef struct VkIOSSurfaceCreateInfoMVK { - VkStructureType sType; - const void* pNext; - VkIOSSurfaceCreateFlagsMVK flags; - const void* pView; -} VkIOSSurfaceCreateInfoMVK; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK( - VkInstance instance, - const VkIOSSurfaceCreateInfoMVK* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif -#endif /* VK_USE_PLATFORM_IOS_MVK */ - -#ifdef VK_USE_PLATFORM_MACOS_MVK -#define VK_MVK_macos_surface 1 -#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2 -#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" - -typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; - -typedef struct VkMacOSSurfaceCreateInfoMVK { - VkStructureType sType; - const void* pNext; - VkMacOSSurfaceCreateFlagsMVK flags; - const void* pView; -} VkMacOSSurfaceCreateInfoMVK; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK( - VkInstance instance, - const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif -#endif /* VK_USE_PLATFORM_MACOS_MVK */ - -#define VK_EXT_sampler_filter_minmax 1 -#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 1 -#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" - - -typedef enum VkSamplerReductionModeEXT { - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0, - VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1, - VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2, - VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, - VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT, - VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1), - VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSamplerReductionModeEXT; - -typedef struct VkSamplerReductionModeCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkSamplerReductionModeEXT reductionMode; -} VkSamplerReductionModeCreateInfoEXT; - -typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; - - - -#define VK_AMD_gpu_shader_int16 1 -#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 1 -#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" - - -#define VK_AMD_mixed_attachment_samples 1 -#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 -#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" - - -#define VK_AMD_shader_fragment_mask 1 -#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1 -#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" - - -#define VK_EXT_shader_stencil_export 1 -#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 -#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" - - -#define VK_EXT_sample_locations 1 -#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1 -#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations" - -typedef struct VkSampleLocationEXT { - float x; - float y; -} VkSampleLocationEXT; - -typedef struct VkSampleLocationsInfoEXT { - VkStructureType sType; - const void* pNext; - VkSampleCountFlagBits sampleLocationsPerPixel; - VkExtent2D sampleLocationGridSize; - uint32_t sampleLocationsCount; - const VkSampleLocationEXT* pSampleLocations; -} VkSampleLocationsInfoEXT; - -typedef struct VkAttachmentSampleLocationsEXT { - uint32_t attachmentIndex; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkAttachmentSampleLocationsEXT; - -typedef struct VkSubpassSampleLocationsEXT { - uint32_t subpassIndex; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkSubpassSampleLocationsEXT; - -typedef struct VkRenderPassSampleLocationsBeginInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t attachmentInitialSampleLocationsCount; - const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations; - uint32_t postSubpassSampleLocationsCount; - const VkSubpassSampleLocationsEXT* pSubpassSampleLocations; -} VkRenderPassSampleLocationsBeginInfoEXT; - -typedef struct VkPipelineSampleLocationsStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 sampleLocationsEnable; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkPipelineSampleLocationsStateCreateInfoEXT; - -typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT { - VkStructureType sType; - void* pNext; - VkSampleCountFlags sampleLocationSampleCounts; - VkExtent2D maxSampleLocationGridSize; - float sampleLocationCoordinateRange[2]; - uint32_t sampleLocationSubPixelBits; - VkBool32 variableSampleLocations; -} VkPhysicalDeviceSampleLocationsPropertiesEXT; - -typedef struct VkMultisamplePropertiesEXT { - VkStructureType sType; - void* pNext; - VkExtent2D maxSampleLocationGridSize; -} VkMultisamplePropertiesEXT; - - -typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT( - VkCommandBuffer commandBuffer, - const VkSampleLocationsInfoEXT* pSampleLocationsInfo); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT( - VkPhysicalDevice physicalDevice, - VkSampleCountFlagBits samples, - VkMultisamplePropertiesEXT* pMultisampleProperties); -#endif - -#define VK_EXT_blend_operation_advanced 1 -#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2 -#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" - - -typedef enum VkBlendOverlapEXT { - VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, - VK_BLEND_OVERLAP_DISJOINT_EXT = 1, - VK_BLEND_OVERLAP_CONJOINT_EXT = 2, - VK_BLEND_OVERLAP_BEGIN_RANGE_EXT = VK_BLEND_OVERLAP_UNCORRELATED_EXT, - VK_BLEND_OVERLAP_END_RANGE_EXT = VK_BLEND_OVERLAP_CONJOINT_EXT, - VK_BLEND_OVERLAP_RANGE_SIZE_EXT = (VK_BLEND_OVERLAP_CONJOINT_EXT - VK_BLEND_OVERLAP_UNCORRELATED_EXT + 1), - VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF -} VkBlendOverlapEXT; - -typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 advancedBlendCoherentOperations; -} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT; - -typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t advancedBlendMaxColorAttachments; - VkBool32 advancedBlendIndependentBlend; - VkBool32 advancedBlendNonPremultipliedSrcColor; - VkBool32 advancedBlendNonPremultipliedDstColor; - VkBool32 advancedBlendCorrelatedOverlap; - VkBool32 advancedBlendAllOperations; -} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT; - -typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 srcPremultiplied; - VkBool32 dstPremultiplied; - VkBlendOverlapEXT blendOverlap; -} VkPipelineColorBlendAdvancedStateCreateInfoEXT; - - - -#define VK_NV_fragment_coverage_to_color 1 -#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 -#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" - -typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; - -typedef struct VkPipelineCoverageToColorStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCoverageToColorStateCreateFlagsNV flags; - VkBool32 coverageToColorEnable; - uint32_t coverageToColorLocation; -} VkPipelineCoverageToColorStateCreateInfoNV; - - - -#define VK_NV_framebuffer_mixed_samples 1 -#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 -#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" - - -typedef enum VkCoverageModulationModeNV { - VK_COVERAGE_MODULATION_MODE_NONE_NV = 0, - VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, - VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, - VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, - VK_COVERAGE_MODULATION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_MODULATION_MODE_NONE_NV, - VK_COVERAGE_MODULATION_MODE_END_RANGE_NV = VK_COVERAGE_MODULATION_MODE_RGBA_NV, - VK_COVERAGE_MODULATION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_MODULATION_MODE_RGBA_NV - VK_COVERAGE_MODULATION_MODE_NONE_NV + 1), - VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCoverageModulationModeNV; - -typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; - -typedef struct VkPipelineCoverageModulationStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCoverageModulationStateCreateFlagsNV flags; - VkCoverageModulationModeNV coverageModulationMode; - VkBool32 coverageModulationTableEnable; - uint32_t coverageModulationTableCount; - const float* pCoverageModulationTable; -} VkPipelineCoverageModulationStateCreateInfoNV; - - - -#define VK_NV_fill_rectangle 1 -#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 -#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle" - - -#define VK_EXT_post_depth_coverage 1 -#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1 -#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" - - -#define VK_EXT_validation_cache 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) - -#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 -#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" - - -typedef enum VkValidationCacheHeaderVersionEXT { - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, - VK_VALIDATION_CACHE_HEADER_VERSION_BEGIN_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_END_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_RANGE_SIZE_EXT = (VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT + 1), - VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationCacheHeaderVersionEXT; - -typedef VkFlags VkValidationCacheCreateFlagsEXT; - -typedef struct VkValidationCacheCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkValidationCacheCreateFlagsEXT flags; - size_t initialDataSize; - const void* pInitialData; -} VkValidationCacheCreateInfoEXT; - -typedef struct VkShaderModuleValidationCacheCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkValidationCacheEXT validationCache; -} VkShaderModuleValidationCacheCreateInfoEXT; - - -typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache); -typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches); -typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT( - VkDevice device, - const VkValidationCacheCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkValidationCacheEXT* pValidationCache); - -VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT( - VkDevice device, - VkValidationCacheEXT validationCache, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT( - VkDevice device, - VkValidationCacheEXT dstCache, - uint32_t srcCacheCount, - const VkValidationCacheEXT* pSrcCaches); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( - VkDevice device, - VkValidationCacheEXT validationCache, - size_t* pDataSize, - void* pData); -#endif - -#define VK_EXT_shader_viewport_index_layer 1 -#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 -#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" - - -#ifdef __cplusplus -} -#endif - -#endif +#endif // VULKAN_H_ diff --git a/ext/vulkan/vulkan_android.h b/ext/vulkan/vulkan_android.h new file mode 100644 index 0000000000..5e61c0531a --- /dev/null +++ b/ext/vulkan/vulkan_android.h @@ -0,0 +1,60 @@ +#ifndef VULKAN_ANDROID_H_ +#define VULKAN_ANDROID_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_android_surface 1 +struct ANativeWindow; + +#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 +#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface" + +typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; + +typedef struct VkAndroidSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAndroidSurfaceCreateFlagsKHR flags; + struct ANativeWindow* window; +} VkAndroidSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( + VkInstance instance, + const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_core.h b/ext/vulkan/vulkan_core.h new file mode 100644 index 0000000000..c115fa6616 --- /dev/null +++ b/ext/vulkan/vulkan_core.h @@ -0,0 +1,7334 @@ +#ifndef VULKAN_CORE_H_ +#define VULKAN_CORE_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_VERSION_1_0 1 +#include "vk_platform.h" + +#define VK_MAKE_VERSION(major, minor, patch) \ + (((major) << 22) | ((minor) << 12) | (patch)) + +// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. +//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 + +// Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)// Patch version should always be set to 0 + +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) +// Version of this file +#define VK_HEADER_VERSION 70 + + +#define VK_NULL_HANDLE 0 + + + +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + + +#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE) +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif +#endif + + + +typedef uint32_t VkFlags; +typedef uint32_t VkBool32; +typedef uint64_t VkDeviceSize; +typedef uint32_t VkSampleMask; + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_HANDLE(VkPhysicalDevice) +VK_DEFINE_HANDLE(VkDevice) +VK_DEFINE_HANDLE(VkQueue) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) +VK_DEFINE_HANDLE(VkCommandBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) + +#define VK_LOD_CLAMP_NONE 1000.0f +#define VK_REMAINING_MIP_LEVELS (~0U) +#define VK_REMAINING_ARRAY_LAYERS (~0U) +#define VK_WHOLE_SIZE (~0ULL) +#define VK_ATTACHMENT_UNUSED (~0U) +#define VK_TRUE 1 +#define VK_FALSE 0 +#define VK_QUEUE_FAMILY_IGNORED (~0U) +#define VK_SUBPASS_EXTERNAL (~0U) +#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 +#define VK_UUID_SIZE 16 +#define VK_MAX_MEMORY_TYPES 32 +#define VK_MAX_MEMORY_HEAPS 16 +#define VK_MAX_EXTENSION_NAME_SIZE 256 +#define VK_MAX_DESCRIPTION_SIZE 256 + + +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, + VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, + VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1), + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + +typedef enum VkResult { + VK_SUCCESS = 0, + VK_NOT_READY = 1, + VK_TIMEOUT = 2, + VK_EVENT_SET = 3, + VK_EVENT_RESET = 4, + VK_INCOMPLETE = 5, + VK_ERROR_OUT_OF_HOST_MEMORY = -1, + VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, + VK_ERROR_INITIALIZATION_FAILED = -3, + VK_ERROR_DEVICE_LOST = -4, + VK_ERROR_MEMORY_MAP_FAILED = -5, + VK_ERROR_LAYER_NOT_PRESENT = -6, + VK_ERROR_EXTENSION_NOT_PRESENT = -7, + VK_ERROR_FEATURE_NOT_PRESENT = -8, + VK_ERROR_INCOMPATIBLE_DRIVER = -9, + VK_ERROR_TOO_MANY_OBJECTS = -10, + VK_ERROR_FORMAT_NOT_SUPPORTED = -11, + VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, + VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_SURFACE_LOST_KHR = -1000000000, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_SUBOPTIMAL_KHR = 1000001003, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, + VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, + VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, + VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL, + VK_RESULT_END_RANGE = VK_INCOMPLETE, + VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1), + VK_RESULT_MAX_ENUM = 0x7FFFFFFF +} VkResult; + +typedef enum VkStructureType { + VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, + VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, + VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, + VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, + VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, + VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, + VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, + VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, + VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, + VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, + VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = 1000120000, + VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, + VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, + VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001, + VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, + VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, + VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, + VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, + VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, + VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, + VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000, + VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, + VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, + VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, + VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000, + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, + VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, + VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, + VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, + VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, + VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, + VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000, + VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001, + VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002, + VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, + VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, + VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001, + VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002, + VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, + VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, + VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, + VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, + VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001, + VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002, + VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, + VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, + VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, + VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, + VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, + VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, + VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, + VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, + VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, + VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, + VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, + VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, + VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, + VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002, + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, + VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, + VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, + VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, + VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, + VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, + VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, + VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, + VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, + VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, + VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkStructureType; + +typedef enum VkSystemAllocationScope { + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, + VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, + VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, + VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE, + VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), + VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF +} VkSystemAllocationScope; + +typedef enum VkInternalAllocationType { + VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, + VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, + VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, + VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), + VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkInternalAllocationType; + +typedef enum VkFormat { + VK_FORMAT_UNDEFINED = 0, + VK_FORMAT_R4G4_UNORM_PACK8 = 1, + VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, + VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, + VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, + VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, + VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, + VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, + VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, + VK_FORMAT_R8_UNORM = 9, + VK_FORMAT_R8_SNORM = 10, + VK_FORMAT_R8_USCALED = 11, + VK_FORMAT_R8_SSCALED = 12, + VK_FORMAT_R8_UINT = 13, + VK_FORMAT_R8_SINT = 14, + VK_FORMAT_R8_SRGB = 15, + VK_FORMAT_R8G8_UNORM = 16, + VK_FORMAT_R8G8_SNORM = 17, + VK_FORMAT_R8G8_USCALED = 18, + VK_FORMAT_R8G8_SSCALED = 19, + VK_FORMAT_R8G8_UINT = 20, + VK_FORMAT_R8G8_SINT = 21, + VK_FORMAT_R8G8_SRGB = 22, + VK_FORMAT_R8G8B8_UNORM = 23, + VK_FORMAT_R8G8B8_SNORM = 24, + VK_FORMAT_R8G8B8_USCALED = 25, + VK_FORMAT_R8G8B8_SSCALED = 26, + VK_FORMAT_R8G8B8_UINT = 27, + VK_FORMAT_R8G8B8_SINT = 28, + VK_FORMAT_R8G8B8_SRGB = 29, + VK_FORMAT_B8G8R8_UNORM = 30, + VK_FORMAT_B8G8R8_SNORM = 31, + VK_FORMAT_B8G8R8_USCALED = 32, + VK_FORMAT_B8G8R8_SSCALED = 33, + VK_FORMAT_B8G8R8_UINT = 34, + VK_FORMAT_B8G8R8_SINT = 35, + VK_FORMAT_B8G8R8_SRGB = 36, + VK_FORMAT_R8G8B8A8_UNORM = 37, + VK_FORMAT_R8G8B8A8_SNORM = 38, + VK_FORMAT_R8G8B8A8_USCALED = 39, + VK_FORMAT_R8G8B8A8_SSCALED = 40, + VK_FORMAT_R8G8B8A8_UINT = 41, + VK_FORMAT_R8G8B8A8_SINT = 42, + VK_FORMAT_R8G8B8A8_SRGB = 43, + VK_FORMAT_B8G8R8A8_UNORM = 44, + VK_FORMAT_B8G8R8A8_SNORM = 45, + VK_FORMAT_B8G8R8A8_USCALED = 46, + VK_FORMAT_B8G8R8A8_SSCALED = 47, + VK_FORMAT_B8G8R8A8_UINT = 48, + VK_FORMAT_B8G8R8A8_SINT = 49, + VK_FORMAT_B8G8R8A8_SRGB = 50, + VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, + VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, + VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, + VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, + VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, + VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, + VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, + VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, + VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, + VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, + VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, + VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, + VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, + VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, + VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, + VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, + VK_FORMAT_R16_UNORM = 70, + VK_FORMAT_R16_SNORM = 71, + VK_FORMAT_R16_USCALED = 72, + VK_FORMAT_R16_SSCALED = 73, + VK_FORMAT_R16_UINT = 74, + VK_FORMAT_R16_SINT = 75, + VK_FORMAT_R16_SFLOAT = 76, + VK_FORMAT_R16G16_UNORM = 77, + VK_FORMAT_R16G16_SNORM = 78, + VK_FORMAT_R16G16_USCALED = 79, + VK_FORMAT_R16G16_SSCALED = 80, + VK_FORMAT_R16G16_UINT = 81, + VK_FORMAT_R16G16_SINT = 82, + VK_FORMAT_R16G16_SFLOAT = 83, + VK_FORMAT_R16G16B16_UNORM = 84, + VK_FORMAT_R16G16B16_SNORM = 85, + VK_FORMAT_R16G16B16_USCALED = 86, + VK_FORMAT_R16G16B16_SSCALED = 87, + VK_FORMAT_R16G16B16_UINT = 88, + VK_FORMAT_R16G16B16_SINT = 89, + VK_FORMAT_R16G16B16_SFLOAT = 90, + VK_FORMAT_R16G16B16A16_UNORM = 91, + VK_FORMAT_R16G16B16A16_SNORM = 92, + VK_FORMAT_R16G16B16A16_USCALED = 93, + VK_FORMAT_R16G16B16A16_SSCALED = 94, + VK_FORMAT_R16G16B16A16_UINT = 95, + VK_FORMAT_R16G16B16A16_SINT = 96, + VK_FORMAT_R16G16B16A16_SFLOAT = 97, + VK_FORMAT_R32_UINT = 98, + VK_FORMAT_R32_SINT = 99, + VK_FORMAT_R32_SFLOAT = 100, + VK_FORMAT_R32G32_UINT = 101, + VK_FORMAT_R32G32_SINT = 102, + VK_FORMAT_R32G32_SFLOAT = 103, + VK_FORMAT_R32G32B32_UINT = 104, + VK_FORMAT_R32G32B32_SINT = 105, + VK_FORMAT_R32G32B32_SFLOAT = 106, + VK_FORMAT_R32G32B32A32_UINT = 107, + VK_FORMAT_R32G32B32A32_SINT = 108, + VK_FORMAT_R32G32B32A32_SFLOAT = 109, + VK_FORMAT_R64_UINT = 110, + VK_FORMAT_R64_SINT = 111, + VK_FORMAT_R64_SFLOAT = 112, + VK_FORMAT_R64G64_UINT = 113, + VK_FORMAT_R64G64_SINT = 114, + VK_FORMAT_R64G64_SFLOAT = 115, + VK_FORMAT_R64G64B64_UINT = 116, + VK_FORMAT_R64G64B64_SINT = 117, + VK_FORMAT_R64G64B64_SFLOAT = 118, + VK_FORMAT_R64G64B64A64_UINT = 119, + VK_FORMAT_R64G64B64A64_SINT = 120, + VK_FORMAT_R64G64B64A64_SFLOAT = 121, + VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, + VK_FORMAT_D16_UNORM = 124, + VK_FORMAT_X8_D24_UNORM_PACK32 = 125, + VK_FORMAT_D32_SFLOAT = 126, + VK_FORMAT_S8_UINT = 127, + VK_FORMAT_D16_UNORM_S8_UINT = 128, + VK_FORMAT_D24_UNORM_S8_UINT = 129, + VK_FORMAT_D32_SFLOAT_S8_UINT = 130, + VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, + VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, + VK_FORMAT_BC2_UNORM_BLOCK = 135, + VK_FORMAT_BC2_SRGB_BLOCK = 136, + VK_FORMAT_BC3_UNORM_BLOCK = 137, + VK_FORMAT_BC3_SRGB_BLOCK = 138, + VK_FORMAT_BC4_UNORM_BLOCK = 139, + VK_FORMAT_BC4_SNORM_BLOCK = 140, + VK_FORMAT_BC5_UNORM_BLOCK = 141, + VK_FORMAT_BC5_SNORM_BLOCK = 142, + VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, + VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, + VK_FORMAT_BC7_UNORM_BLOCK = 145, + VK_FORMAT_BC7_SRGB_BLOCK = 146, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, + VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, + VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, + VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, + VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, + VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, + VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, + VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, + VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, + VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, + VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, + VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, + VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, + VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003, + VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004, + VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, + VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, + VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, + VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, + VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, + VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, + VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM, + VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED, + VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, + VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1), + VK_FORMAT_MAX_ENUM = 0x7FFFFFFF +} VkFormat; + +typedef enum VkImageType { + VK_IMAGE_TYPE_1D = 0, + VK_IMAGE_TYPE_2D = 1, + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D, + VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D, + VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1), + VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageType; + +typedef enum VkImageTiling { + VK_IMAGE_TILING_OPTIMAL = 0, + VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, + VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), + VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF +} VkImageTiling; + +typedef enum VkPhysicalDeviceType { + VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, + VK_PHYSICAL_DEVICE_TYPE_CPU = 4, + VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU, + VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1), + VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkPhysicalDeviceType; + +typedef enum VkQueryType { + VK_QUERY_TYPE_OCCLUSION = 0, + VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, + VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, + VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, + VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), + VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkQueryType; + +typedef enum VkSharingMode { + VK_SHARING_MODE_EXCLUSIVE = 0, + VK_SHARING_MODE_CONCURRENT = 1, + VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE, + VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT, + VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1), + VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSharingMode; + +typedef enum VkImageLayout { + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, + VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + +typedef enum VkImageViewType { + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, + VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageViewType; + +typedef enum VkComponentSwizzle { + VK_COMPONENT_SWIZZLE_IDENTITY = 0, + VK_COMPONENT_SWIZZLE_ZERO = 1, + VK_COMPONENT_SWIZZLE_ONE = 2, + VK_COMPONENT_SWIZZLE_R = 3, + VK_COMPONENT_SWIZZLE_G = 4, + VK_COMPONENT_SWIZZLE_B = 5, + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, + VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF +} VkComponentSwizzle; + +typedef enum VkVertexInputRate { + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, + VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, + VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF +} VkVertexInputRate; + +typedef enum VkPrimitiveTopology { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, + VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF +} VkPrimitiveTopology; + +typedef enum VkPolygonMode { + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, + VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, + VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, + VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPolygonMode; + +typedef enum VkFrontFace { + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, + VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF +} VkFrontFace; + +typedef enum VkCompareOp { + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, + VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, + VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + +typedef enum VkStencilOp { + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, + VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + +typedef enum VkLogicOp { + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, + VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, + VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; + +typedef enum VkBlendFactor { + VK_BLEND_FACTOR_ZERO = 0, + VK_BLEND_FACTOR_ONE = 1, + VK_BLEND_FACTOR_SRC_COLOR = 2, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, + VK_BLEND_FACTOR_DST_COLOR = 4, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, + VK_BLEND_FACTOR_SRC_ALPHA = 6, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, + VK_BLEND_FACTOR_DST_ALPHA = 8, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, + VK_BLEND_FACTOR_CONSTANT_COLOR = 10, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, + VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, + VK_BLEND_FACTOR_SRC1_COLOR = 15, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, + VK_BLEND_FACTOR_SRC1_ALPHA = 17, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), + VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF +} VkBlendFactor; + +typedef enum VkBlendOp { + VK_BLEND_OP_ADD = 0, + VK_BLEND_OP_SUBTRACT = 1, + VK_BLEND_OP_REVERSE_SUBTRACT = 2, + VK_BLEND_OP_MIN = 3, + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_ZERO_EXT = 1000148000, + VK_BLEND_OP_SRC_EXT = 1000148001, + VK_BLEND_OP_DST_EXT = 1000148002, + VK_BLEND_OP_SRC_OVER_EXT = 1000148003, + VK_BLEND_OP_DST_OVER_EXT = 1000148004, + VK_BLEND_OP_SRC_IN_EXT = 1000148005, + VK_BLEND_OP_DST_IN_EXT = 1000148006, + VK_BLEND_OP_SRC_OUT_EXT = 1000148007, + VK_BLEND_OP_DST_OUT_EXT = 1000148008, + VK_BLEND_OP_SRC_ATOP_EXT = 1000148009, + VK_BLEND_OP_DST_ATOP_EXT = 1000148010, + VK_BLEND_OP_XOR_EXT = 1000148011, + VK_BLEND_OP_MULTIPLY_EXT = 1000148012, + VK_BLEND_OP_SCREEN_EXT = 1000148013, + VK_BLEND_OP_OVERLAY_EXT = 1000148014, + VK_BLEND_OP_DARKEN_EXT = 1000148015, + VK_BLEND_OP_LIGHTEN_EXT = 1000148016, + VK_BLEND_OP_COLORDODGE_EXT = 1000148017, + VK_BLEND_OP_COLORBURN_EXT = 1000148018, + VK_BLEND_OP_HARDLIGHT_EXT = 1000148019, + VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020, + VK_BLEND_OP_DIFFERENCE_EXT = 1000148021, + VK_BLEND_OP_EXCLUSION_EXT = 1000148022, + VK_BLEND_OP_INVERT_EXT = 1000148023, + VK_BLEND_OP_INVERT_RGB_EXT = 1000148024, + VK_BLEND_OP_LINEARDODGE_EXT = 1000148025, + VK_BLEND_OP_LINEARBURN_EXT = 1000148026, + VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027, + VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028, + VK_BLEND_OP_PINLIGHT_EXT = 1000148029, + VK_BLEND_OP_HARDMIX_EXT = 1000148030, + VK_BLEND_OP_HSL_HUE_EXT = 1000148031, + VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032, + VK_BLEND_OP_HSL_COLOR_EXT = 1000148033, + VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034, + VK_BLEND_OP_PLUS_EXT = 1000148035, + VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036, + VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037, + VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038, + VK_BLEND_OP_MINUS_EXT = 1000148039, + VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040, + VK_BLEND_OP_CONTRAST_EXT = 1000148041, + VK_BLEND_OP_INVERT_OVG_EXT = 1000148042, + VK_BLEND_OP_RED_EXT = 1000148043, + VK_BLEND_OP_GREEN_EXT = 1000148044, + VK_BLEND_OP_BLUE_EXT = 1000148045, + VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, + VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, + VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), + VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF +} VkBlendOp; + +typedef enum VkDynamicState { + VK_DYNAMIC_STATE_VIEWPORT = 0, + VK_DYNAMIC_STATE_SCISSOR = 1, + VK_DYNAMIC_STATE_LINE_WIDTH = 2, + VK_DYNAMIC_STATE_DEPTH_BIAS = 3, + VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, + VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, + VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, + VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, + VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, + VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), + VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF +} VkDynamicState; + +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_IMG = 1000015000, + VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, + VK_FILTER_END_RANGE = VK_FILTER_LINEAR, + VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + +typedef enum VkSamplerAddressMode { + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +typedef enum VkBorderColor { + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, + VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, + VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF +} VkBorderColor; + +typedef enum VkDescriptorType { + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, + VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +typedef enum VkAttachmentLoadOp { + VK_ATTACHMENT_LOAD_OP_LOAD = 0, + VK_ATTACHMENT_LOAD_OP_CLEAR = 1, + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentLoadOp; + +typedef enum VkAttachmentStoreOp { + VK_ATTACHMENT_STORE_OP_STORE = 0, + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentStoreOp; + +typedef enum VkPipelineBindPoint { + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, + VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, + VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF +} VkPipelineBindPoint; + +typedef enum VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferLevel; + +typedef enum VkIndexType { + VK_INDEX_TYPE_UINT16 = 0, + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, + VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, + VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkIndexType; + +typedef enum VkSubpassContents { + VK_SUBPASS_CONTENTS_INLINE = 0, + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, + VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, + VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassContents; + +typedef enum VkObjectType { + VK_OBJECT_TYPE_UNKNOWN = 0, + VK_OBJECT_TYPE_INSTANCE = 1, + VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, + VK_OBJECT_TYPE_DEVICE = 3, + VK_OBJECT_TYPE_QUEUE = 4, + VK_OBJECT_TYPE_SEMAPHORE = 5, + VK_OBJECT_TYPE_COMMAND_BUFFER = 6, + VK_OBJECT_TYPE_FENCE = 7, + VK_OBJECT_TYPE_DEVICE_MEMORY = 8, + VK_OBJECT_TYPE_BUFFER = 9, + VK_OBJECT_TYPE_IMAGE = 10, + VK_OBJECT_TYPE_EVENT = 11, + VK_OBJECT_TYPE_QUERY_POOL = 12, + VK_OBJECT_TYPE_BUFFER_VIEW = 13, + VK_OBJECT_TYPE_IMAGE_VIEW = 14, + VK_OBJECT_TYPE_SHADER_MODULE = 15, + VK_OBJECT_TYPE_PIPELINE_CACHE = 16, + VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, + VK_OBJECT_TYPE_RENDER_PASS = 18, + VK_OBJECT_TYPE_PIPELINE = 19, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, + VK_OBJECT_TYPE_SAMPLER = 21, + VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, + VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, + VK_OBJECT_TYPE_FRAMEBUFFER = 24, + VK_OBJECT_TYPE_COMMAND_POOL = 25, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, + VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, + VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, + VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, + VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, + VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000, + VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001, + VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, + VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN, + VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL, + VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1), + VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkObjectType; + +typedef VkFlags VkInstanceCreateFlags; + +typedef enum VkFormatFeatureFlagBits { + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, + VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, + VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, + VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 0x00004000, + VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 0x00008000, + VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, + VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = VK_FORMAT_FEATURE_DISJOINT_BIT, + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFormatFeatureFlagBits; +typedef VkFlags VkFormatFeatureFlags; + +typedef enum VkImageUsageFlagBits { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageUsageFlagBits; +typedef VkFlags VkImageUsageFlags; + +typedef enum VkImageCreateFlagBits { + VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, + VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400, + VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040, + VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020, + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080, + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, + VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, + VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, + VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, + VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT, + VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT, + VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageCreateFlagBits; +typedef VkFlags VkImageCreateFlags; + +typedef enum VkSampleCountFlagBits { + VK_SAMPLE_COUNT_1_BIT = 0x00000001, + VK_SAMPLE_COUNT_2_BIT = 0x00000002, + VK_SAMPLE_COUNT_4_BIT = 0x00000004, + VK_SAMPLE_COUNT_8_BIT = 0x00000008, + VK_SAMPLE_COUNT_16_BIT = 0x00000010, + VK_SAMPLE_COUNT_32_BIT = 0x00000020, + VK_SAMPLE_COUNT_64_BIT = 0x00000040, + VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSampleCountFlagBits; +typedef VkFlags VkSampleCountFlags; + +typedef enum VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, + VK_QUEUE_PROTECTED_BIT = 0x00000010, + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueueFlagBits; +typedef VkFlags VkQueueFlags; + +typedef enum VkMemoryPropertyFlagBits { + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, + VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryPropertyFlagBits; +typedef VkFlags VkMemoryPropertyFlags; + +typedef enum VkMemoryHeapFlagBits { + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002, + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT, + VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryHeapFlagBits; +typedef VkFlags VkMemoryHeapFlags; +typedef VkFlags VkDeviceCreateFlags; + +typedef enum VkDeviceQueueCreateFlagBits { + VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001, + VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDeviceQueueCreateFlagBits; +typedef VkFlags VkDeviceQueueCreateFlags; + +typedef enum VkPipelineStageFlagBits { + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, + VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, + VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000, + VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineStageFlagBits; +typedef VkFlags VkPipelineStageFlags; +typedef VkFlags VkMemoryMapFlags; + +typedef enum VkImageAspectFlagBits { + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, + VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, + VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, + VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, + VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, + VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; + +typedef enum VkSparseImageFormatFlagBits { + VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, + VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, + VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseImageFormatFlagBits; +typedef VkFlags VkSparseImageFormatFlags; + +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; + +typedef enum VkFenceCreateFlagBits { + VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, + VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFenceCreateFlagBits; +typedef VkFlags VkFenceCreateFlags; +typedef VkFlags VkSemaphoreCreateFlags; +typedef VkFlags VkEventCreateFlags; +typedef VkFlags VkQueryPoolCreateFlags; + +typedef enum VkQueryPipelineStatisticFlagBits { + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, + VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, + VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, + VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryPipelineStatisticFlagBits; +typedef VkFlags VkQueryPipelineStatisticFlags; + +typedef enum VkQueryResultFlagBits { + VK_QUERY_RESULT_64_BIT = 0x00000001, + VK_QUERY_RESULT_WAIT_BIT = 0x00000002, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, + VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, + VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryResultFlagBits; +typedef VkFlags VkQueryResultFlags; + +typedef enum VkBufferCreateFlagBits { + VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, + VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferCreateFlagBits; +typedef VkFlags VkBufferCreateFlags; + +typedef enum VkBufferUsageFlagBits { + VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferUsageFlagBits; +typedef VkFlags VkBufferUsageFlags; +typedef VkFlags VkBufferViewCreateFlags; +typedef VkFlags VkImageViewCreateFlags; +typedef VkFlags VkShaderModuleCreateFlags; +typedef VkFlags VkPipelineCacheCreateFlags; + +typedef enum VkPipelineCreateFlagBits { + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, + VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, + VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, + VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreateFlagBits; +typedef VkFlags VkPipelineCreateFlags; +typedef VkFlags VkPipelineShaderStageCreateFlags; + +typedef enum VkShaderStageFlagBits { + VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, + VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, + VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, + VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkShaderStageFlagBits; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; + +typedef enum VkCullModeFlagBits { + VK_CULL_MODE_NONE = 0, + VK_CULL_MODE_FRONT_BIT = 0x00000001, + VK_CULL_MODE_BACK_BIT = 0x00000002, + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCullModeFlagBits; +typedef VkFlags VkCullModeFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; + +typedef enum VkColorComponentFlagBits { + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; +typedef VkFlags VkPipelineDynamicStateCreateFlags; +typedef VkFlags VkPipelineLayoutCreateFlags; +typedef VkFlags VkShaderStageFlags; +typedef VkFlags VkSamplerCreateFlags; + +typedef enum VkDescriptorSetLayoutCreateFlagBits { + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorSetLayoutCreateFlagBits; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; + +typedef enum VkDescriptorPoolCreateFlagBits { + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, + VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorPoolCreateFlagBits; +typedef VkFlags VkDescriptorPoolCreateFlags; +typedef VkFlags VkDescriptorPoolResetFlags; +typedef VkFlags VkFramebufferCreateFlags; +typedef VkFlags VkRenderPassCreateFlags; + +typedef enum VkAttachmentDescriptionFlagBits { + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, + VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentDescriptionFlagBits; +typedef VkFlags VkAttachmentDescriptionFlags; + +typedef enum VkSubpassDescriptionFlagBits { + VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, + VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, + VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassDescriptionFlagBits; +typedef VkFlags VkSubpassDescriptionFlags; + +typedef enum VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000, + VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000, + VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; + +typedef enum VkDependencyFlagBits { + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, + VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, + VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, + VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, + VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDependencyFlagBits; +typedef VkFlags VkDependencyFlags; + +typedef enum VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, + VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolCreateFlagBits; +typedef VkFlags VkCommandPoolCreateFlags; + +typedef enum VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolResetFlagBits; +typedef VkFlags VkCommandPoolResetFlags; + +typedef enum VkCommandBufferUsageFlagBits { + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferUsageFlagBits; +typedef VkFlags VkCommandBufferUsageFlags; + +typedef enum VkQueryControlFlagBits { + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryControlFlagBits; +typedef VkFlags VkQueryControlFlags; + +typedef enum VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferResetFlagBits; +typedef VkFlags VkCommandBufferResetFlags; + +typedef enum VkStencilFaceFlagBits { + VK_STENCIL_FACE_FRONT_BIT = 0x00000001, + VK_STENCIL_FACE_BACK_BIT = 0x00000002, + VK_STENCIL_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkStencilFaceFlagBits; +typedef VkFlags VkStencilFaceFlags; + +typedef struct VkApplicationInfo { + VkStructureType sType; + const void* pNext; + const char* pApplicationName; + uint32_t applicationVersion; + const char* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkInstanceCreateInfo { + VkStructureType sType; + const void* pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( + void* pUserData, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( + void* pUserData, + void* pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkFreeFunction)( + void* pUserData, + void* pMemory); + +typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef struct VkAllocationCallbacks { + void* pUserData; + PFN_vkAllocationFunction pfnAllocation; + PFN_vkReallocationFunction pfnReallocation; + PFN_vkFreeFunction pfnFree; + PFN_vkInternalAllocationNotification pfnInternalAllocation; + PFN_vkInternalFreeNotification pfnInternalFree; +} VkAllocationCallbacks; + +typedef struct VkPhysicalDeviceFeatures { + VkBool32 robustBufferAccess; + VkBool32 fullDrawIndexUint32; + VkBool32 imageCubeArray; + VkBool32 independentBlend; + VkBool32 geometryShader; + VkBool32 tessellationShader; + VkBool32 sampleRateShading; + VkBool32 dualSrcBlend; + VkBool32 logicOp; + VkBool32 multiDrawIndirect; + VkBool32 drawIndirectFirstInstance; + VkBool32 depthClamp; + VkBool32 depthBiasClamp; + VkBool32 fillModeNonSolid; + VkBool32 depthBounds; + VkBool32 wideLines; + VkBool32 largePoints; + VkBool32 alphaToOne; + VkBool32 multiViewport; + VkBool32 samplerAnisotropy; + VkBool32 textureCompressionETC2; + VkBool32 textureCompressionASTC_LDR; + VkBool32 textureCompressionBC; + VkBool32 occlusionQueryPrecise; + VkBool32 pipelineStatisticsQuery; + VkBool32 vertexPipelineStoresAndAtomics; + VkBool32 fragmentStoresAndAtomics; + VkBool32 shaderTessellationAndGeometryPointSize; + VkBool32 shaderImageGatherExtended; + VkBool32 shaderStorageImageExtendedFormats; + VkBool32 shaderStorageImageMultisample; + VkBool32 shaderStorageImageReadWithoutFormat; + VkBool32 shaderStorageImageWriteWithoutFormat; + VkBool32 shaderUniformBufferArrayDynamicIndexing; + VkBool32 shaderSampledImageArrayDynamicIndexing; + VkBool32 shaderStorageBufferArrayDynamicIndexing; + VkBool32 shaderStorageImageArrayDynamicIndexing; + VkBool32 shaderClipDistance; + VkBool32 shaderCullDistance; + VkBool32 shaderFloat64; + VkBool32 shaderInt64; + VkBool32 shaderInt16; + VkBool32 shaderResourceResidency; + VkBool32 shaderResourceMinLod; + VkBool32 sparseBinding; + VkBool32 sparseResidencyBuffer; + VkBool32 sparseResidencyImage2D; + VkBool32 sparseResidencyImage3D; + VkBool32 sparseResidency2Samples; + VkBool32 sparseResidency4Samples; + VkBool32 sparseResidency8Samples; + VkBool32 sparseResidency16Samples; + VkBool32 sparseResidencyAliased; + VkBool32 variableMultisampleRate; + VkBool32 inheritedQueries; +} VkPhysicalDeviceFeatures; + +typedef struct VkFormatProperties { + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkImageFormatProperties { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkPhysicalDeviceLimits { + uint32_t maxImageDimension1D; + uint32_t maxImageDimension2D; + uint32_t maxImageDimension3D; + uint32_t maxImageDimensionCube; + uint32_t maxImageArrayLayers; + uint32_t maxTexelBufferElements; + uint32_t maxUniformBufferRange; + uint32_t maxStorageBufferRange; + uint32_t maxPushConstantsSize; + uint32_t maxMemoryAllocationCount; + uint32_t maxSamplerAllocationCount; + VkDeviceSize bufferImageGranularity; + VkDeviceSize sparseAddressSpaceSize; + uint32_t maxBoundDescriptorSets; + uint32_t maxPerStageDescriptorSamplers; + uint32_t maxPerStageDescriptorUniformBuffers; + uint32_t maxPerStageDescriptorStorageBuffers; + uint32_t maxPerStageDescriptorSampledImages; + uint32_t maxPerStageDescriptorStorageImages; + uint32_t maxPerStageDescriptorInputAttachments; + uint32_t maxPerStageResources; + uint32_t maxDescriptorSetSamplers; + uint32_t maxDescriptorSetUniformBuffers; + uint32_t maxDescriptorSetUniformBuffersDynamic; + uint32_t maxDescriptorSetStorageBuffers; + uint32_t maxDescriptorSetStorageBuffersDynamic; + uint32_t maxDescriptorSetSampledImages; + uint32_t maxDescriptorSetStorageImages; + uint32_t maxDescriptorSetInputAttachments; + uint32_t maxVertexInputAttributes; + uint32_t maxVertexInputBindings; + uint32_t maxVertexInputAttributeOffset; + uint32_t maxVertexInputBindingStride; + uint32_t maxVertexOutputComponents; + uint32_t maxTessellationGenerationLevel; + uint32_t maxTessellationPatchSize; + uint32_t maxTessellationControlPerVertexInputComponents; + uint32_t maxTessellationControlPerVertexOutputComponents; + uint32_t maxTessellationControlPerPatchOutputComponents; + uint32_t maxTessellationControlTotalOutputComponents; + uint32_t maxTessellationEvaluationInputComponents; + uint32_t maxTessellationEvaluationOutputComponents; + uint32_t maxGeometryShaderInvocations; + uint32_t maxGeometryInputComponents; + uint32_t maxGeometryOutputComponents; + uint32_t maxGeometryOutputVertices; + uint32_t maxGeometryTotalOutputComponents; + uint32_t maxFragmentInputComponents; + uint32_t maxFragmentOutputAttachments; + uint32_t maxFragmentDualSrcAttachments; + uint32_t maxFragmentCombinedOutputResources; + uint32_t maxComputeSharedMemorySize; + uint32_t maxComputeWorkGroupCount[3]; + uint32_t maxComputeWorkGroupInvocations; + uint32_t maxComputeWorkGroupSize[3]; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; + uint32_t maxDrawIndexedIndexValue; + uint32_t maxDrawIndirectCount; + float maxSamplerLodBias; + float maxSamplerAnisotropy; + uint32_t maxViewports; + uint32_t maxViewportDimensions[2]; + float viewportBoundsRange[2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize minTexelBufferOffsetAlignment; + VkDeviceSize minUniformBufferOffsetAlignment; + VkDeviceSize minStorageBufferOffsetAlignment; + int32_t minTexelOffset; + uint32_t maxTexelOffset; + int32_t minTexelGatherOffset; + uint32_t maxTexelGatherOffset; + float minInterpolationOffset; + float maxInterpolationOffset; + uint32_t subPixelInterpolationOffsetBits; + uint32_t maxFramebufferWidth; + uint32_t maxFramebufferHeight; + uint32_t maxFramebufferLayers; + VkSampleCountFlags framebufferColorSampleCounts; + VkSampleCountFlags framebufferDepthSampleCounts; + VkSampleCountFlags framebufferStencilSampleCounts; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts; + uint32_t maxColorAttachments; + VkSampleCountFlags sampledImageColorSampleCounts; + VkSampleCountFlags sampledImageIntegerSampleCounts; + VkSampleCountFlags sampledImageDepthSampleCounts; + VkSampleCountFlags sampledImageStencilSampleCounts; + VkSampleCountFlags storageImageSampleCounts; + uint32_t maxSampleMaskWords; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; + uint32_t maxClipDistances; + uint32_t maxCullDistances; + uint32_t maxCombinedClipAndCullDistances; + uint32_t discreteQueuePriorities; + float pointSizeRange[2]; + float lineWidthRange[2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize optimalBufferCopyOffsetAlignment; + VkDeviceSize optimalBufferCopyRowPitchAlignment; + VkDeviceSize nonCoherentAtomSize; +} VkPhysicalDeviceLimits; + +typedef struct VkPhysicalDeviceSparseProperties { + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; +} VkPhysicalDeviceSparseProperties; + +typedef struct VkPhysicalDeviceProperties { + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties; + +typedef struct VkQueueFamilyProperties { + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties; + +typedef struct VkMemoryType { + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + +typedef struct VkMemoryHeap { + VkDeviceSize size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkPhysicalDeviceMemoryProperties { + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + +typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); +typedef struct VkDeviceQueueCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float* pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo; + +typedef struct VkExtensionProperties { + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; +} VkExtensionProperties; + +typedef struct VkLayerProperties { + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; + uint32_t implementationVersion; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkLayerProperties; + +typedef struct VkSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + const VkPipelineStageFlags* pWaitDstStageMask; + uint32_t commandBufferCount; + const VkCommandBuffer* pCommandBuffers; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkSubmitInfo; + +typedef struct VkMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + +typedef struct VkMappedMemoryRange { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMappedMemoryRange; + +typedef struct VkMemoryRequirements { + VkDeviceSize size; + VkDeviceSize alignment; + uint32_t memoryTypeBits; +} VkMemoryRequirements; + +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + +typedef struct VkSparseMemoryBind { + VkDeviceSize resourceOffset; + VkDeviceSize size; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseMemoryBind; + +typedef struct VkSparseBufferMemoryBindInfo { + VkBuffer buffer; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseBufferMemoryBindInfo; + +typedef struct VkSparseImageOpaqueMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseImageOpaqueMemoryBindInfo; + +typedef struct VkImageSubresource { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkSparseImageMemoryBind { + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseImageMemoryBind; + +typedef struct VkSparseImageMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseImageMemoryBind* pBinds; +} VkSparseImageMemoryBindInfo; + +typedef struct VkBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t bufferBindCount; + const VkSparseBufferMemoryBindInfo* pBufferBinds; + uint32_t imageOpaqueBindCount; + const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; + uint32_t imageBindCount; + const VkSparseImageMemoryBindInfo* pImageBinds; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkBindSparseInfo; + +typedef struct VkFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo; + +typedef struct VkSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo; + +typedef struct VkEventCreateInfo { + VkStructureType sType; + const void* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkQueryPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkQueryPoolCreateFlags flags; + VkQueryType queryType; + uint32_t queryCount; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkQueryPoolCreateInfo; + +typedef struct VkBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkDeviceSize size; + VkBufferUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkBufferCreateInfo; + +typedef struct VkBufferViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferViewCreateFlags flags; + VkBuffer buffer; + VkFormat format; + VkDeviceSize offset; + VkDeviceSize range; +} VkBufferViewCreateInfo; + +typedef struct VkImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + VkSampleCountFlagBits samples; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkImageLayout initialLayout; +} VkImageCreateInfo; + +typedef struct VkSubresourceLayout { + VkDeviceSize offset; + VkDeviceSize size; + VkDeviceSize rowPitch; + VkDeviceSize arrayPitch; + VkDeviceSize depthPitch; +} VkSubresourceLayout; + +typedef struct VkComponentMapping { + VkComponentSwizzle r; + VkComponentSwizzle g; + VkComponentSwizzle b; + VkComponentSwizzle a; +} VkComponentMapping; + +typedef struct VkImageSubresourceRange { + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageViewCreateFlags flags; + VkImage image; + VkImageViewType viewType; + VkFormat format; + VkComponentMapping components; + VkImageSubresourceRange subresourceRange; +} VkImageViewCreateInfo; + +typedef struct VkShaderModuleCreateInfo { + VkStructureType sType; + const void* pNext; + VkShaderModuleCreateFlags flags; + size_t codeSize; + const uint32_t* pCode; +} VkShaderModuleCreateInfo; + +typedef struct VkPipelineCacheCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCacheCreateFlags flags; + size_t initialDataSize; + const void* pInitialData; +} VkPipelineCacheCreateInfo; + +typedef struct VkSpecializationMapEntry { + uint32_t constantID; + uint32_t offset; + size_t size; +} VkSpecializationMapEntry; + +typedef struct VkSpecializationInfo { + uint32_t mapEntryCount; + const VkSpecializationMapEntry* pMapEntries; + size_t dataSize; + const void* pData; +} VkSpecializationInfo; + +typedef struct VkPipelineShaderStageCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineShaderStageCreateFlags flags; + VkShaderStageFlagBits stage; + VkShaderModule module; + const char* pName; + const VkSpecializationInfo* pSpecializationInfo; +} VkPipelineShaderStageCreateInfo; + +typedef struct VkVertexInputBindingDescription { + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkVertexInputAttributeDescription { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkPipelineVertexInputStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineVertexInputStateCreateFlags flags; + uint32_t vertexBindingDescriptionCount; + const VkVertexInputBindingDescription* pVertexBindingDescriptions; + uint32_t vertexAttributeDescriptionCount; + const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; +} VkPipelineVertexInputStateCreateInfo; + +typedef struct VkPipelineInputAssemblyStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +typedef struct VkPipelineTessellationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +typedef struct VkViewport { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +typedef struct VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkPipelineViewportStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport* pViewports; + uint32_t scissorCount; + const VkRect2D* pScissors; +} VkPipelineViewportStateCreateInfo; + +typedef struct VkPipelineRasterizationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateCreateFlags flags; + VkBool32 depthClampEnable; + VkBool32 rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + VkBool32 depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; +} VkPipelineRasterizationStateCreateInfo; + +typedef struct VkPipelineMultisampleStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineMultisampleStateCreateFlags flags; + VkSampleCountFlagBits rasterizationSamples; + VkBool32 sampleShadingEnable; + float minSampleShading; + const VkSampleMask* pSampleMask; + VkBool32 alphaToCoverageEnable; + VkBool32 alphaToOneEnable; +} VkPipelineMultisampleStateCreateInfo; + +typedef struct VkStencilOpState { + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkPipelineDepthStencilStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDepthStencilStateCreateFlags flags; + VkBool32 depthTestEnable; + VkBool32 depthWriteEnable; + VkCompareOp depthCompareOp; + VkBool32 depthBoundsTestEnable; + VkBool32 stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; +} VkPipelineDepthStencilStateCreateInfo; + +typedef struct VkPipelineColorBlendAttachmentState { + VkBool32 blendEnable; + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; + VkColorComponentFlags colorWriteMask; +} VkPipelineColorBlendAttachmentState; + +typedef struct VkPipelineColorBlendStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineColorBlendStateCreateFlags flags; + VkBool32 logicOpEnable; + VkLogicOp logicOp; + uint32_t attachmentCount; + const VkPipelineColorBlendAttachmentState* pAttachments; + float blendConstants[4]; +} VkPipelineColorBlendStateCreateInfo; + +typedef struct VkPipelineDynamicStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState* pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkGraphicsPipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; + const VkPipelineViewportStateCreateInfo* pViewportState; + const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkRenderPass renderPass; + uint32_t subpass; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkGraphicsPipelineCreateInfo; + +typedef struct VkComputePipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo stage; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + +typedef struct VkPushConstantRange { + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; +} VkPushConstantRange; + +typedef struct VkPipelineLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineLayoutCreateFlags flags; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; +} VkPipelineLayoutCreateInfo; + +typedef struct VkSamplerCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerCreateFlags flags; + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; +} VkSamplerCreateInfo; + +typedef struct VkDescriptorSetLayoutBinding { + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler* pImmutableSamplers; +} VkDescriptorSetLayoutBinding; + +typedef struct VkDescriptorSetLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding* pBindings; +} VkDescriptorSetLayoutCreateInfo; + +typedef struct VkDescriptorPoolSize { + VkDescriptorType type; + uint32_t descriptorCount; +} VkDescriptorPoolSize; + +typedef struct VkDescriptorPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPoolCreateFlags flags; + uint32_t maxSets; + uint32_t poolSizeCount; + const VkDescriptorPoolSize* pPoolSizes; +} VkDescriptorPoolCreateInfo; + +typedef struct VkDescriptorSetAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPool descriptorPool; + uint32_t descriptorSetCount; + const VkDescriptorSetLayout* pSetLayouts; +} VkDescriptorSetAllocateInfo; + +typedef struct VkDescriptorImageInfo { + VkSampler sampler; + VkImageView imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; + +typedef struct VkDescriptorBufferInfo { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize range; +} VkDescriptorBufferInfo; + +typedef struct VkWriteDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + const VkDescriptorImageInfo* pImageInfo; + const VkDescriptorBufferInfo* pBufferInfo; + const VkBufferView* pTexelBufferView; +} VkWriteDescriptorSet; + +typedef struct VkCopyDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; + +typedef struct VkFramebufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkFramebufferCreateFlags flags; + VkRenderPass renderPass; + uint32_t attachmentCount; + const VkImageView* pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + +typedef struct VkAttachmentDescription { + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription; + +typedef struct VkAttachmentReference { + uint32_t attachment; + VkImageLayout layout; +} VkAttachmentReference; + +typedef struct VkSubpassDescription { + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t inputAttachmentCount; + const VkAttachmentReference* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference* pColorAttachments; + const VkAttachmentReference* pResolveAttachments; + const VkAttachmentReference* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription; + +typedef struct VkSubpassDependency { + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + +typedef struct VkRenderPassCreateInfo { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency* pDependencies; +} VkRenderPassCreateInfo; + +typedef struct VkCommandPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo; + +typedef struct VkCommandBufferAllocateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo; + +typedef struct VkCommandBufferInheritanceInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + uint32_t subpass; + VkFramebuffer framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo; + +typedef struct VkCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + VkCommandBufferUsageFlags flags; + const VkCommandBufferInheritanceInfo* pInheritanceInfo; +} VkCommandBufferBeginInfo; + +typedef struct VkBufferCopy { + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy; + +typedef struct VkImageSubresourceLayers { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceLayers; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +typedef struct VkImageBlit { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkBufferImageCopy { + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef union VkClearColorValue { + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +typedef struct VkClearDepthStencilValue { + float depth; + uint32_t stencil; +} VkClearDepthStencilValue; + +typedef union VkClearValue { + VkClearColorValue color; + VkClearDepthStencilValue depthStencil; +} VkClearValue; + +typedef struct VkClearAttachment { + VkImageAspectFlags aspectMask; + uint32_t colorAttachment; + VkClearValue clearValue; +} VkClearAttachment; + +typedef struct VkClearRect { + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + +typedef struct VkImageResolve { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve; + +typedef struct VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkBufferMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier; + +typedef struct VkImageMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + VkRect2D renderArea; + uint32_t clearValueCount; + const VkClearValue* pClearValues; +} VkRenderPassBeginInfo; + +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkDrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); +typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); +typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); +typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); +typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); +typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); +typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); +typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); +typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); +typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); +typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); +typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); +typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); +typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); +typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( + VkInstance instance, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkImageFormatProperties* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties* pMemoryProperties); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( + VkInstance instance, + const char* pName); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( + VkDevice device, + const char* pName); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( + VkQueue queue); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( + VkDevice device); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( + VkDevice device, + const VkMemoryAllocateInfo* pAllocateInfo, + const VkAllocationCallbacks* pAllocator, + VkDeviceMemory* pMemory); + +VKAPI_ATTR void VKAPI_CALL vkFreeMemory( + VkDevice device, + VkDeviceMemory memory, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize offset, + VkDeviceSize size, + VkMemoryMapFlags flags, + void** ppData); + +VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( + VkDevice device, + VkDeviceMemory memory); + +VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize* pCommittedMemoryInBytes); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( + VkDevice device, + VkBuffer buffer, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( + VkDevice device, + VkImage image, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( + VkDevice device, + VkBuffer buffer, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( + VkDevice device, + VkImage image, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( + VkDevice device, + VkImage image, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkSampleCountFlagBits samples, + VkImageUsageFlags usage, + VkImageTiling tiling, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( + VkQueue queue, + uint32_t bindInfoCount, + const VkBindSparseInfo* pBindInfo, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( + VkDevice device, + const VkFenceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFence( + VkDevice device, + VkFence fence, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( + VkDevice device, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( + VkDevice device, + const VkSemaphoreCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSemaphore* pSemaphore); + +VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( + VkDevice device, + VkSemaphore semaphore, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( + VkDevice device, + const VkEventCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkEvent* pEvent); + +VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( + VkDevice device, + VkEvent event, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( + VkDevice device, + const VkQueryPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkQueryPool* pQueryPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( + VkDevice device, + VkQueryPool queryPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + void* pData, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( + VkDevice device, + const VkBufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBuffer* pBuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( + VkDevice device, + VkBuffer buffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( + VkDevice device, + const VkBufferViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBufferView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( + VkDevice device, + VkBufferView bufferView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( + VkDevice device, + const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImage( + VkDevice device, + VkImage image, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( + VkDevice device, + VkImage image, + const VkImageSubresource* pSubresource, + VkSubresourceLayout* pLayout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( + VkDevice device, + const VkImageViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImageView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( + VkDevice device, + VkImageView imageView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule); + +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( + VkDevice device, + VkShaderModule shaderModule, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( + VkDevice device, + const VkPipelineCacheCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineCache* pPipelineCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( + VkDevice device, + VkPipelineCache pipelineCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( + VkDevice device, + VkPipelineCache pipelineCache, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( + VkDevice device, + VkPipelineCache dstCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkComputePipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( + VkDevice device, + VkPipeline pipeline, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( + VkDevice device, + const VkPipelineLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineLayout* pPipelineLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( + VkDevice device, + VkPipelineLayout pipelineLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( + VkDevice device, + const VkSamplerCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSampler* pSampler); + +VKAPI_ATTR void VKAPI_CALL vkDestroySampler( + VkDevice device, + VkSampler sampler, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorSetLayout* pSetLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( + VkDevice device, + VkDescriptorSetLayout descriptorSetLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( + VkDevice device, + const VkDescriptorPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorPool* pDescriptorPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( + VkDevice device, + const VkDescriptorSetAllocateInfo* pAllocateInfo, + VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( + VkDevice device, + VkDescriptorPool descriptorPool, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( + VkDevice device, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet* pDescriptorCopies); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( + VkDevice device, + const VkFramebufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFramebuffer* pFramebuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( + VkDevice device, + VkFramebuffer framebuffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( + VkDevice device, + const VkRenderPassCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( + VkDevice device, + VkRenderPass renderPass, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( + VkDevice device, + VkRenderPass renderPass, + VkExtent2D* pGranularity); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( + VkDevice device, + const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCommandPool* pCommandPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( + VkDevice device, + VkCommandPool commandPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( + VkDevice device, + const VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( + VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo* pBeginInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( + VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( + VkCommandBuffer commandBuffer, + uint32_t firstScissor, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( + VkCommandBuffer commandBuffer, + float lineWidth); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( + VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, + float depthBiasClamp, + float depthBiasSlopeFactor); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( + VkCommandBuffer commandBuffer, + const float blendConstants[4]); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( + VkCommandBuffer commandBuffer, + float minDepthBounds, + float maxDepthBounds); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdDraw( + VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( + VkCommandBuffer commandBuffer, + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( + VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit* pRegions, + VkFilter filter); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize dataSize, + const void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment* pAttachments, + uint32_t rectCount, + const VkClearRect* pRects); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void* pValues); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( + VkCommandBuffer commandBuffer, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); +#endif + +#define VK_VERSION_1_1 1 +// Vulkan 1.1 version number +#define VK_API_VERSION_1_1 VK_MAKE_VERSION(1, 1, 0)// Patch version should always be set to 0 + + +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) + +#define VK_MAX_DEVICE_GROUP_SIZE 32 +#define VK_LUID_SIZE 8 +#define VK_QUEUE_FAMILY_EXTERNAL (~0U-1) + + +typedef enum VkPointClippingBehavior { + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, + VK_POINT_CLIPPING_BEHAVIOR_BEGIN_RANGE = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, + VK_POINT_CLIPPING_BEHAVIOR_END_RANGE = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, + VK_POINT_CLIPPING_BEHAVIOR_RANGE_SIZE = (VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES + 1), + VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF +} VkPointClippingBehavior; + +typedef enum VkTessellationDomainOrigin { + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_BEGIN_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_END_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_RANGE_SIZE = (VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT + 1), + VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF +} VkTessellationDomainOrigin; + +typedef enum VkSamplerYcbcrModelConversion { + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_BEGIN_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_END_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RANGE_SIZE = (VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + 1), + VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF +} VkSamplerYcbcrModelConversion; + +typedef enum VkSamplerYcbcrRange { + VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, + VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, + VK_SAMPLER_YCBCR_RANGE_BEGIN_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, + VK_SAMPLER_YCBCR_RANGE_END_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, + VK_SAMPLER_YCBCR_RANGE_RANGE_SIZE = (VK_SAMPLER_YCBCR_RANGE_ITU_NARROW - VK_SAMPLER_YCBCR_RANGE_ITU_FULL + 1), + VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerYcbcrRange; + +typedef enum VkChromaLocation { + VK_CHROMA_LOCATION_COSITED_EVEN = 0, + VK_CHROMA_LOCATION_MIDPOINT = 1, + VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN, + VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT, + VK_CHROMA_LOCATION_BEGIN_RANGE = VK_CHROMA_LOCATION_COSITED_EVEN, + VK_CHROMA_LOCATION_END_RANGE = VK_CHROMA_LOCATION_MIDPOINT, + VK_CHROMA_LOCATION_RANGE_SIZE = (VK_CHROMA_LOCATION_MIDPOINT - VK_CHROMA_LOCATION_COSITED_EVEN + 1), + VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF +} VkChromaLocation; + +typedef enum VkDescriptorUpdateTemplateType { + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_END_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET + 1), + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorUpdateTemplateType; + + +typedef enum VkSubgroupFeatureFlagBits { + VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001, + VK_SUBGROUP_FEATURE_VOTE_BIT = 0x00000002, + VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 0x00000004, + VK_SUBGROUP_FEATURE_BALLOT_BIT = 0x00000008, + VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 0x00000010, + VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, + VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, + VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, + VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubgroupFeatureFlagBits; +typedef VkFlags VkSubgroupFeatureFlags; + +typedef enum VkPeerMemoryFeatureFlagBits { + VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001, + VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002, + VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004, + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008, + VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT, + VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT, + VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT, + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT, + VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPeerMemoryFeatureFlagBits; +typedef VkFlags VkPeerMemoryFeatureFlags; + +typedef enum VkMemoryAllocateFlagBits { + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, + VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryAllocateFlagBits; +typedef VkFlags VkMemoryAllocateFlags; +typedef VkFlags VkCommandPoolTrimFlags; +typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; + +typedef enum VkExternalMemoryHandleTypeFlagBits { + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalMemoryHandleTypeFlagBits; +typedef VkFlags VkExternalMemoryHandleTypeFlags; + +typedef enum VkExternalMemoryFeatureFlagBits { + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalMemoryFeatureFlagBits; +typedef VkFlags VkExternalMemoryFeatureFlags; + +typedef enum VkExternalFenceHandleTypeFlagBits { + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000008, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalFenceHandleTypeFlagBits; +typedef VkFlags VkExternalFenceHandleTypeFlags; + +typedef enum VkExternalFenceFeatureFlagBits { + VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalFenceFeatureFlagBits; +typedef VkFlags VkExternalFenceFeatureFlags; + +typedef enum VkFenceImportFlagBits { + VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = VK_FENCE_IMPORT_TEMPORARY_BIT, + VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFenceImportFlagBits; +typedef VkFlags VkFenceImportFlags; + +typedef enum VkSemaphoreImportFlagBits { + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, + VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreImportFlagBits; +typedef VkFlags VkSemaphoreImportFlags; + +typedef enum VkExternalSemaphoreHandleTypeFlagBits { + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalSemaphoreHandleTypeFlagBits; +typedef VkFlags VkExternalSemaphoreHandleTypeFlags; + +typedef enum VkExternalSemaphoreFeatureFlagBits { + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalSemaphoreFeatureFlagBits; +typedef VkFlags VkExternalSemaphoreFeatureFlags; + +typedef struct VkPhysicalDeviceSubgroupProperties { + VkStructureType sType; + void* pNext; + uint32_t subgroupSize; + VkShaderStageFlags supportedStages; + VkSubgroupFeatureFlags supportedOperations; + VkBool32 quadOperationsInAllStages; +} VkPhysicalDeviceSubgroupProperties; + +typedef struct VkBindBufferMemoryInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindBufferMemoryInfo; + +typedef struct VkBindImageMemoryInfo { + VkStructureType sType; + const void* pNext; + VkImage image; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindImageMemoryInfo; + +typedef struct VkPhysicalDevice16BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; +} VkPhysicalDevice16BitStorageFeatures; + +typedef struct VkMemoryDedicatedRequirements { + VkStructureType sType; + void* pNext; + VkBool32 prefersDedicatedAllocation; + VkBool32 requiresDedicatedAllocation; +} VkMemoryDedicatedRequirements; + +typedef struct VkMemoryDedicatedAllocateInfo { + VkStructureType sType; + const void* pNext; + VkImage image; + VkBuffer buffer; +} VkMemoryDedicatedAllocateInfo; + +typedef struct VkMemoryAllocateFlagsInfo { + VkStructureType sType; + const void* pNext; + VkMemoryAllocateFlags flags; + uint32_t deviceMask; +} VkMemoryAllocateFlagsInfo; + +typedef struct VkDeviceGroupRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceMask; + uint32_t deviceRenderAreaCount; + const VkRect2D* pDeviceRenderAreas; +} VkDeviceGroupRenderPassBeginInfo; + +typedef struct VkDeviceGroupCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceMask; +} VkDeviceGroupCommandBufferBeginInfo; + +typedef struct VkDeviceGroupSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const uint32_t* pWaitSemaphoreDeviceIndices; + uint32_t commandBufferCount; + const uint32_t* pCommandBufferDeviceMasks; + uint32_t signalSemaphoreCount; + const uint32_t* pSignalSemaphoreDeviceIndices; +} VkDeviceGroupSubmitInfo; + +typedef struct VkDeviceGroupBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t resourceDeviceIndex; + uint32_t memoryDeviceIndex; +} VkDeviceGroupBindSparseInfo; + +typedef struct VkBindBufferMemoryDeviceGroupInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; +} VkBindBufferMemoryDeviceGroupInfo; + +typedef struct VkBindImageMemoryDeviceGroupInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; + uint32_t splitInstanceBindRegionCount; + const VkRect2D* pSplitInstanceBindRegions; +} VkBindImageMemoryDeviceGroupInfo; + +typedef struct VkPhysicalDeviceGroupProperties { + VkStructureType sType; + void* pNext; + uint32_t physicalDeviceCount; + VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE]; + VkBool32 subsetAllocation; +} VkPhysicalDeviceGroupProperties; + +typedef struct VkDeviceGroupDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t physicalDeviceCount; + const VkPhysicalDevice* pPhysicalDevices; +} VkDeviceGroupDeviceCreateInfo; + +typedef struct VkBufferMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferMemoryRequirementsInfo2; + +typedef struct VkImageMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageMemoryRequirementsInfo2; + +typedef struct VkImageSparseMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageSparseMemoryRequirementsInfo2; + +typedef struct VkMemoryRequirements2 { + VkStructureType sType; + void* pNext; + VkMemoryRequirements memoryRequirements; +} VkMemoryRequirements2; + +typedef struct VkSparseImageMemoryRequirements2 { + VkStructureType sType; + void* pNext; + VkSparseImageMemoryRequirements memoryRequirements; +} VkSparseImageMemoryRequirements2; + +typedef struct VkPhysicalDeviceFeatures2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceFeatures features; +} VkPhysicalDeviceFeatures2; + +typedef struct VkPhysicalDeviceProperties2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceProperties properties; +} VkPhysicalDeviceProperties2; + +typedef struct VkFormatProperties2 { + VkStructureType sType; + void* pNext; + VkFormatProperties formatProperties; +} VkFormatProperties2; + +typedef struct VkImageFormatProperties2 { + VkStructureType sType; + void* pNext; + VkImageFormatProperties imageFormatProperties; +} VkImageFormatProperties2; + +typedef struct VkPhysicalDeviceImageFormatInfo2 { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkImageType type; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkImageCreateFlags flags; +} VkPhysicalDeviceImageFormatInfo2; + +typedef struct VkQueueFamilyProperties2 { + VkStructureType sType; + void* pNext; + VkQueueFamilyProperties queueFamilyProperties; +} VkQueueFamilyProperties2; + +typedef struct VkPhysicalDeviceMemoryProperties2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceMemoryProperties memoryProperties; +} VkPhysicalDeviceMemoryProperties2; + +typedef struct VkSparseImageFormatProperties2 { + VkStructureType sType; + void* pNext; + VkSparseImageFormatProperties properties; +} VkSparseImageFormatProperties2; + +typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkImageType type; + VkSampleCountFlagBits samples; + VkImageUsageFlags usage; + VkImageTiling tiling; +} VkPhysicalDeviceSparseImageFormatInfo2; + +typedef struct VkPhysicalDevicePointClippingProperties { + VkStructureType sType; + void* pNext; + VkPointClippingBehavior pointClippingBehavior; +} VkPhysicalDevicePointClippingProperties; + +typedef struct VkInputAttachmentAspectReference { + uint32_t subpass; + uint32_t inputAttachmentIndex; + VkImageAspectFlags aspectMask; +} VkInputAttachmentAspectReference; + +typedef struct VkRenderPassInputAttachmentAspectCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t aspectReferenceCount; + const VkInputAttachmentAspectReference* pAspectReferences; +} VkRenderPassInputAttachmentAspectCreateInfo; + +typedef struct VkImageViewUsageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags usage; +} VkImageViewUsageCreateInfo; + +typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkTessellationDomainOrigin domainOrigin; +} VkPipelineTessellationDomainOriginStateCreateInfo; + +typedef struct VkRenderPassMultiviewCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t subpassCount; + const uint32_t* pViewMasks; + uint32_t dependencyCount; + const int32_t* pViewOffsets; + uint32_t correlationMaskCount; + const uint32_t* pCorrelationMasks; +} VkRenderPassMultiviewCreateInfo; + +typedef struct VkPhysicalDeviceMultiviewFeatures { + VkStructureType sType; + void* pNext; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; +} VkPhysicalDeviceMultiviewFeatures; + +typedef struct VkPhysicalDeviceMultiviewProperties { + VkStructureType sType; + void* pNext; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; +} VkPhysicalDeviceMultiviewProperties; + +typedef struct VkPhysicalDeviceVariablePointerFeatures { + VkStructureType sType; + void* pNext; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; +} VkPhysicalDeviceVariablePointerFeatures; + +typedef struct VkPhysicalDeviceProtectedMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 protectedMemory; +} VkPhysicalDeviceProtectedMemoryFeatures; + +typedef struct VkPhysicalDeviceProtectedMemoryProperties { + VkStructureType sType; + void* pNext; + VkBool32 protectedNoFault; +} VkPhysicalDeviceProtectedMemoryProperties; + +typedef struct VkDeviceQueueInfo2 { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueIndex; +} VkDeviceQueueInfo2; + +typedef struct VkProtectedSubmitInfo { + VkStructureType sType; + const void* pNext; + VkBool32 protectedSubmit; +} VkProtectedSubmitInfo; + +typedef struct VkSamplerYcbcrConversionCreateInfo { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkSamplerYcbcrModelConversion ycbcrModel; + VkSamplerYcbcrRange ycbcrRange; + VkComponentMapping components; + VkChromaLocation xChromaOffset; + VkChromaLocation yChromaOffset; + VkFilter chromaFilter; + VkBool32 forceExplicitReconstruction; +} VkSamplerYcbcrConversionCreateInfo; + +typedef struct VkSamplerYcbcrConversionInfo { + VkStructureType sType; + const void* pNext; + VkSamplerYcbcrConversion conversion; +} VkSamplerYcbcrConversionInfo; + +typedef struct VkBindImagePlaneMemoryInfo { + VkStructureType sType; + const void* pNext; + VkImageAspectFlagBits planeAspect; +} VkBindImagePlaneMemoryInfo; + +typedef struct VkImagePlaneMemoryRequirementsInfo { + VkStructureType sType; + const void* pNext; + VkImageAspectFlagBits planeAspect; +} VkImagePlaneMemoryRequirementsInfo; + +typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { + VkStructureType sType; + void* pNext; + VkBool32 samplerYcbcrConversion; +} VkPhysicalDeviceSamplerYcbcrConversionFeatures; + +typedef struct VkSamplerYcbcrConversionImageFormatProperties { + VkStructureType sType; + void* pNext; + uint32_t combinedImageSamplerDescriptorCount; +} VkSamplerYcbcrConversionImageFormatProperties; + +typedef struct VkDescriptorUpdateTemplateEntry { + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + size_t offset; + size_t stride; +} VkDescriptorUpdateTemplateEntry; + +typedef struct VkDescriptorUpdateTemplateCreateInfo { + VkStructureType sType; + void* pNext; + VkDescriptorUpdateTemplateCreateFlags flags; + uint32_t descriptorUpdateEntryCount; + const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; + VkDescriptorUpdateTemplateType templateType; + VkDescriptorSetLayout descriptorSetLayout; + VkPipelineBindPoint pipelineBindPoint; + VkPipelineLayout pipelineLayout; + uint32_t set; +} VkDescriptorUpdateTemplateCreateInfo; + +typedef struct VkExternalMemoryProperties { + VkExternalMemoryFeatureFlags externalMemoryFeatures; + VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; + VkExternalMemoryHandleTypeFlags compatibleHandleTypes; +} VkExternalMemoryProperties; + +typedef struct VkPhysicalDeviceExternalImageFormatInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalImageFormatInfo; + +typedef struct VkExternalImageFormatProperties { + VkStructureType sType; + void* pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalImageFormatProperties; + +typedef struct VkPhysicalDeviceExternalBufferInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkBufferUsageFlags usage; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalBufferInfo; + +typedef struct VkExternalBufferProperties { + VkStructureType sType; + void* pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalBufferProperties; + +typedef struct VkPhysicalDeviceIDProperties { + VkStructureType sType; + void* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; +} VkPhysicalDeviceIDProperties; + +typedef struct VkExternalMemoryImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryImageCreateInfo; + +typedef struct VkExternalMemoryBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryBufferCreateInfo; + +typedef struct VkExportMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExportMemoryAllocateInfo; + +typedef struct VkPhysicalDeviceExternalFenceInfo { + VkStructureType sType; + const void* pNext; + VkExternalFenceHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalFenceInfo; + +typedef struct VkExternalFenceProperties { + VkStructureType sType; + void* pNext; + VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes; + VkExternalFenceHandleTypeFlags compatibleHandleTypes; + VkExternalFenceFeatureFlags externalFenceFeatures; +} VkExternalFenceProperties; + +typedef struct VkExportFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalFenceHandleTypeFlags handleTypes; +} VkExportFenceCreateInfo; + +typedef struct VkExportSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalSemaphoreHandleTypeFlags handleTypes; +} VkExportSemaphoreCreateInfo; + +typedef struct VkPhysicalDeviceExternalSemaphoreInfo { + VkStructureType sType; + const void* pNext; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalSemaphoreInfo; + +typedef struct VkExternalSemaphoreProperties { + VkStructureType sType; + void* pNext; + VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes; + VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; + VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; +} VkExternalSemaphoreProperties; + +typedef struct VkPhysicalDeviceMaintenance3Properties { + VkStructureType sType; + void* pNext; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceMaintenance3Properties; + +typedef struct VkDescriptorSetLayoutSupport { + VkStructureType sType; + void* pNext; + VkBool32 supported; +} VkDescriptorSetLayoutSupport; + +typedef struct VkPhysicalDeviceShaderDrawParameterFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceShaderDrawParameterFeatures; + + +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion( + uint32_t* pApiVersion); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2( + VkDevice device, + uint32_t bindInfoCount, + const VkBindBufferMemoryInfo* pBindInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2( + VkDevice device, + uint32_t bindInfoCount, + const VkBindImageMemoryInfo* pBindInfos); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures( + VkDevice device, + uint32_t heapIndex, + uint32_t localDeviceIndex, + uint32_t remoteDeviceIndex, + VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask( + VkCommandBuffer commandBuffer, + uint32_t deviceMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase( + VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( + VkInstance instance, + uint32_t* pPhysicalDeviceGroupCount, + VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2( + VkDevice device, + const VkImageMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2( + VkDevice device, + const VkBufferMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2( + VkDevice device, + const VkImageSparseMemoryRequirementsInfo2* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures2* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, + VkImageFormatProperties2* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties2* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2* pMemoryProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2( + VkDevice device, + const VkDeviceQueueInfo2* pQueueInfo, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( + VkDevice device, + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversion* pYcbcrConversion); + +VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( + VkDevice device, + VkSamplerYcbcrConversion ycbcrConversion, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate( + VkDevice device, + const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate( + VkDevice device, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate( + VkDevice device, + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const void* pData); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, + VkExternalBufferProperties* pExternalBufferProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, + VkExternalFenceProperties* pExternalFenceProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, + VkExternalSemaphoreProperties* pExternalSemaphoreProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + VkDescriptorSetLayoutSupport* pSupport); +#endif + +#define VK_KHR_surface 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#define VK_KHR_SURFACE_SPEC_VERSION 25 +#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" +#define VK_COLORSPACE_SRGB_NONLINEAR_KHR VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + + +typedef enum VkColorSpaceKHR { + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, + VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, + VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104003, + VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004, + VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005, + VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, + VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, + VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, + VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, + VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, + VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, + VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, + VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, + VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), + VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkColorSpaceKHR; + +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, + VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentModeKHR; + + +typedef enum VkSurfaceTransformFlagBitsKHR { + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, + VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSurfaceTransformFlagBitsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; + +typedef enum VkCompositeAlphaFlagBitsKHR { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, + VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCompositeAlphaFlagBitsKHR; +typedef VkFlags VkCompositeAlphaFlagsKHR; + +typedef struct VkSurfaceCapabilitiesKHR { + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkSurfaceFormatKHR { + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + + +typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( + VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32* pSupported); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormatKHR* pSurfaceFormats); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); +#endif + +#define VK_KHR_swapchain 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) + +#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 +#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" + + +typedef enum VkSwapchainCreateFlagBitsKHR { + VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, + VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSwapchainCreateFlagBitsKHR; +typedef VkFlags VkSwapchainCreateFlagsKHR; + +typedef enum VkDeviceGroupPresentModeFlagBitsKHR { + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001, + VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002, + VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004, + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008, + VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDeviceGroupPresentModeFlagBitsKHR; +typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; + +typedef struct VkSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR oldSwapchain; +} VkSwapchainCreateInfoKHR; + +typedef struct VkPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR* pSwapchains; + const uint32_t* pImageIndices; + VkResult* pResults; +} VkPresentInfoKHR; + +typedef struct VkImageSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; +} VkImageSwapchainCreateInfoKHR; + +typedef struct VkBindImageMemorySwapchainInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint32_t imageIndex; +} VkBindImageMemorySwapchainInfoKHR; + +typedef struct VkAcquireNextImageInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint64_t timeout; + VkSemaphore semaphore; + VkFence fence; + uint32_t deviceMask; +} VkAcquireNextImageInfoKHR; + +typedef struct VkDeviceGroupPresentCapabilitiesKHR { + VkStructureType sType; + const void* pNext; + uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupPresentCapabilitiesKHR; + +typedef struct VkDeviceGroupPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const uint32_t* pDeviceMasks; + VkDeviceGroupPresentModeFlagBitsKHR mode; +} VkDeviceGroupPresentInfoKHR; + +typedef struct VkDeviceGroupSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupSwapchainCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); +typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); +typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( + VkDevice device, + const VkSwapchainCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchain); + +VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( + VkDevice device, + VkSwapchainKHR swapchain, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pSwapchainImageCount, + VkImage* pSwapchainImages); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t timeout, + VkSemaphore semaphore, + VkFence fence, + uint32_t* pImageIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( + VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR( + VkDevice device, + VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR( + VkDevice device, + VkSurfaceKHR surface, + VkDeviceGroupPresentModeFlagsKHR* pModes); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pRectCount, + VkRect2D* pRects); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR( + VkDevice device, + const VkAcquireNextImageInfoKHR* pAcquireInfo, + uint32_t* pImageIndex); +#endif + +#define VK_KHR_display 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) + +#define VK_KHR_DISPLAY_SPEC_VERSION 21 +#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" + + +typedef enum VkDisplayPlaneAlphaFlagBitsKHR { + VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, + VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDisplayPlaneAlphaFlagBitsKHR; +typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; +typedef VkFlags VkDisplayModeCreateFlagsKHR; +typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; + +typedef struct VkDisplayPropertiesKHR { + VkDisplayKHR display; + const char* displayName; + VkExtent2D physicalDimensions; + VkExtent2D physicalResolution; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkBool32 planeReorderPossible; + VkBool32 persistentContent; +} VkDisplayPropertiesKHR; + +typedef struct VkDisplayModeParametersKHR { + VkExtent2D visibleRegion; + uint32_t refreshRate; +} VkDisplayModeParametersKHR; + +typedef struct VkDisplayModePropertiesKHR { + VkDisplayModeKHR displayMode; + VkDisplayModeParametersKHR parameters; +} VkDisplayModePropertiesKHR; + +typedef struct VkDisplayModeCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeCreateFlagsKHR flags; + VkDisplayModeParametersKHR parameters; +} VkDisplayModeCreateInfoKHR; + +typedef struct VkDisplayPlaneCapabilitiesKHR { + VkDisplayPlaneAlphaFlagsKHR supportedAlpha; + VkOffset2D minSrcPosition; + VkOffset2D maxSrcPosition; + VkExtent2D minSrcExtent; + VkExtent2D maxSrcExtent; + VkOffset2D minDstPosition; + VkOffset2D maxDstPosition; + VkExtent2D minDstExtent; + VkExtent2D maxDstExtent; +} VkDisplayPlaneCapabilitiesKHR; + +typedef struct VkDisplayPlanePropertiesKHR { + VkDisplayKHR currentDisplay; + uint32_t currentStackIndex; +} VkDisplayPlanePropertiesKHR; + +typedef struct VkDisplaySurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplaySurfaceCreateFlagsKHR flags; + VkDisplayModeKHR displayMode; + uint32_t planeIndex; + uint32_t planeStackIndex; + VkSurfaceTransformFlagBitsKHR transform; + float globalAlpha; + VkDisplayPlaneAlphaFlagBitsKHR alphaMode; + VkExtent2D imageExtent; +} VkDisplaySurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlanePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( + VkPhysicalDevice physicalDevice, + uint32_t planeIndex, + uint32_t* pDisplayCount, + VkDisplayKHR* pDisplays); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + const VkDisplayModeCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDisplayModeKHR* pMode); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayModeKHR mode, + uint32_t planeIndex, + VkDisplayPlaneCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( + VkInstance instance, + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#define VK_KHR_display_swapchain 1 +#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9 +#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" + +typedef struct VkDisplayPresentInfoKHR { + VkStructureType sType; + const void* pNext; + VkRect2D srcRect; + VkRect2D dstRect; + VkBool32 persistent; +} VkDisplayPresentInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchains); +#endif + +#define VK_KHR_sampler_mirror_clamp_to_edge 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" + + +#define VK_KHR_multiview 1 +#define VK_KHR_MULTIVIEW_SPEC_VERSION 1 +#define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" + +typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewCreateInfoKHR; + +typedef VkPhysicalDeviceMultiviewFeatures VkPhysicalDeviceMultiviewFeaturesKHR; + +typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMultiviewPropertiesKHR; + + + +#define VK_KHR_get_physical_device_properties2 1 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" + +typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR; + +typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR; + +typedef VkFormatProperties2 VkFormatProperties2KHR; + +typedef VkImageFormatProperties2 VkImageFormatProperties2KHR; + +typedef VkPhysicalDeviceImageFormatInfo2 VkPhysicalDeviceImageFormatInfo2KHR; + +typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR; + +typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemoryProperties2KHR; + +typedef VkSparseImageFormatProperties2 VkSparseImageFormatProperties2KHR; + +typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDeviceSparseImageFormatInfo2KHR; + + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures2* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, + VkImageFormatProperties2* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties2* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2* pMemoryProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties2* pProperties); +#endif + +#define VK_KHR_device_group 1 +#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 3 +#define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group" + +typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR; + +typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBitsKHR; + +typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR; + +typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR; + + +typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR; + +typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPassBeginInfoKHR; + +typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupCommandBufferBeginInfoKHR; + +typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR; + +typedef VkDeviceGroupBindSparseInfo VkDeviceGroupBindSparseInfoKHR; + +typedef VkBindBufferMemoryDeviceGroupInfo VkBindBufferMemoryDeviceGroupInfoKHR; + +typedef VkBindImageMemoryDeviceGroupInfo VkBindImageMemoryDeviceGroupInfoKHR; + + +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer commandBuffer, uint32_t deviceMask); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR( + VkDevice device, + uint32_t heapIndex, + uint32_t localDeviceIndex, + uint32_t remoteDeviceIndex, + VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHR( + VkCommandBuffer commandBuffer, + uint32_t deviceMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( + VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); +#endif + +#define VK_KHR_shader_draw_parameters 1 +#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1 +#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters" + + +#define VK_KHR_maintenance1 1 +#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" + +typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; + + +typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags); +#endif + +#define VK_KHR_device_group_creation 1 +#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1 +#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation" +#define VK_MAX_DEVICE_GROUP_SIZE_KHR VK_MAX_DEVICE_GROUP_SIZE + +typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR; + +typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR( + VkInstance instance, + uint32_t* pPhysicalDeviceGroupCount, + VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); +#endif + +#define VK_KHR_external_memory_capabilities 1 +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities" +#define VK_LUID_SIZE_KHR VK_LUID_SIZE + +typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandleTypeFlagsKHR; + +typedef VkExternalMemoryHandleTypeFlagBits VkExternalMemoryHandleTypeFlagBitsKHR; + +typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFlagsKHR; + +typedef VkExternalMemoryFeatureFlagBits VkExternalMemoryFeatureFlagBitsKHR; + + +typedef VkExternalMemoryProperties VkExternalMemoryPropertiesKHR; + +typedef VkPhysicalDeviceExternalImageFormatInfo VkPhysicalDeviceExternalImageFormatInfoKHR; + +typedef VkExternalImageFormatProperties VkExternalImageFormatPropertiesKHR; + +typedef VkPhysicalDeviceExternalBufferInfo VkPhysicalDeviceExternalBufferInfoKHR; + +typedef VkExternalBufferProperties VkExternalBufferPropertiesKHR; + +typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR; + + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, + VkExternalBufferProperties* pExternalBufferProperties); +#endif + +#define VK_KHR_external_memory 1 +#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory" +#define VK_QUEUE_FAMILY_EXTERNAL_KHR VK_QUEUE_FAMILY_EXTERNAL + +typedef VkExternalMemoryImageCreateInfo VkExternalMemoryImageCreateInfoKHR; + +typedef VkExternalMemoryBufferCreateInfo VkExternalMemoryBufferCreateInfoKHR; + +typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoKHR; + + + +#define VK_KHR_external_memory_fd 1 +#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd" + +typedef struct VkImportMemoryFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + int fd; +} VkImportMemoryFdInfoKHR; + +typedef struct VkMemoryFdPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryFdPropertiesKHR; + +typedef struct VkMemoryGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetFdInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR( + VkDevice device, + const VkMemoryGetFdInfoKHR* pGetFdInfo, + int* pFd); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR* pMemoryFdProperties); +#endif + +#define VK_KHR_external_semaphore_capabilities 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities" + +typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphoreHandleTypeFlagsKHR; + +typedef VkExternalSemaphoreHandleTypeFlagBits VkExternalSemaphoreHandleTypeFlagBitsKHR; + +typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFeatureFlagsKHR; + +typedef VkExternalSemaphoreFeatureFlagBits VkExternalSemaphoreFeatureFlagBitsKHR; + + +typedef VkPhysicalDeviceExternalSemaphoreInfo VkPhysicalDeviceExternalSemaphoreInfoKHR; + +typedef VkExternalSemaphoreProperties VkExternalSemaphorePropertiesKHR; + + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, + VkExternalSemaphoreProperties* pExternalSemaphoreProperties); +#endif + +#define VK_KHR_external_semaphore 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore" + +typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR; + +typedef VkSemaphoreImportFlagBits VkSemaphoreImportFlagBitsKHR; + + +typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInfoKHR; + + + +#define VK_KHR_external_semaphore_fd 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd" + +typedef struct VkImportSemaphoreFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkSemaphoreImportFlags flags; + VkExternalSemaphoreHandleTypeFlagBits handleType; + int fd; +} VkImportSemaphoreFdInfoKHR; + +typedef struct VkSemaphoreGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkSemaphoreGetFdInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR( + VkDevice device, + const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR( + VkDevice device, + const VkSemaphoreGetFdInfoKHR* pGetFdInfo, + int* pFd); +#endif + +#define VK_KHR_push_descriptor 1 +#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2 +#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" + +typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t maxPushDescriptors; +} VkPhysicalDevicePushDescriptorPropertiesKHR; + + +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t set, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( + VkCommandBuffer commandBuffer, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + VkPipelineLayout layout, + uint32_t set, + const void* pData); +#endif + +#define VK_KHR_16bit_storage 1 +#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" + +typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice16BitStorageFeaturesKHR; + + + +#define VK_KHR_incremental_present 1 +#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 +#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" + +typedef struct VkRectLayerKHR { + VkOffset2D offset; + VkExtent2D extent; + uint32_t layer; +} VkRectLayerKHR; + +typedef struct VkPresentRegionKHR { + uint32_t rectangleCount; + const VkRectLayerKHR* pRectangles; +} VkPresentRegionKHR; + +typedef struct VkPresentRegionsKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentRegionKHR* pRegions; +} VkPresentRegionsKHR; + + + +#define VK_KHR_descriptor_update_template 1 +typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR; + + +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template" + +typedef VkDescriptorUpdateTemplateType VkDescriptorUpdateTemplateTypeKHR; + + +typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR; + + +typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemplateEntryKHR; + +typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdateTemplateCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR( + VkDevice device, + const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR( + VkDevice device, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( + VkDevice device, + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const void* pData); +#endif + +#define VK_KHR_shared_presentable_image 1 +#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 +#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image" + +typedef struct VkSharedPresentSurfaceCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkImageUsageFlags sharedPresentSupportedUsageFlags; +} VkSharedPresentSurfaceCapabilitiesKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR( + VkDevice device, + VkSwapchainKHR swapchain); +#endif + +#define VK_KHR_external_fence_capabilities 1 +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities" + +typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTypeFlagsKHR; + +typedef VkExternalFenceHandleTypeFlagBits VkExternalFenceHandleTypeFlagBitsKHR; + +typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlagsKHR; + +typedef VkExternalFenceFeatureFlagBits VkExternalFenceFeatureFlagBitsKHR; + + +typedef VkPhysicalDeviceExternalFenceInfo VkPhysicalDeviceExternalFenceInfoKHR; + +typedef VkExternalFenceProperties VkExternalFencePropertiesKHR; + + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, + VkExternalFenceProperties* pExternalFenceProperties); +#endif + +#define VK_KHR_external_fence 1 +#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence" + +typedef VkFenceImportFlags VkFenceImportFlagsKHR; + +typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR; + + +typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR; + + + +#define VK_KHR_external_fence_fd 1 +#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd" + +typedef struct VkImportFenceFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkFenceImportFlags flags; + VkExternalFenceHandleTypeFlagBits handleType; + int fd; +} VkImportFenceFdInfoKHR; + +typedef struct VkFenceGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkExternalFenceHandleTypeFlagBits handleType; +} VkFenceGetFdInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR( + VkDevice device, + const VkImportFenceFdInfoKHR* pImportFenceFdInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( + VkDevice device, + const VkFenceGetFdInfoKHR* pGetFdInfo, + int* pFd); +#endif + +#define VK_KHR_maintenance2 1 +#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" + +typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; + +typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR; + + +typedef VkPhysicalDevicePointClippingProperties VkPhysicalDevicePointClippingPropertiesKHR; + +typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPassInputAttachmentAspectCreateInfoKHR; + +typedef VkInputAttachmentAspectReference VkInputAttachmentAspectReferenceKHR; + +typedef VkImageViewUsageCreateInfo VkImageViewUsageCreateInfoKHR; + +typedef VkPipelineTessellationDomainOriginStateCreateInfo VkPipelineTessellationDomainOriginStateCreateInfoKHR; + + + +#define VK_KHR_get_surface_capabilities2 1 +#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2" + +typedef struct VkPhysicalDeviceSurfaceInfo2KHR { + VkStructureType sType; + const void* pNext; + VkSurfaceKHR surface; +} VkPhysicalDeviceSurfaceInfo2KHR; + +typedef struct VkSurfaceCapabilities2KHR { + VkStructureType sType; + void* pNext; + VkSurfaceCapabilitiesKHR surfaceCapabilities; +} VkSurfaceCapabilities2KHR; + +typedef struct VkSurfaceFormat2KHR { + VkStructureType sType; + void* pNext; + VkSurfaceFormatKHR surfaceFormat; +} VkSurfaceFormat2KHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + VkSurfaceCapabilities2KHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormat2KHR* pSurfaceFormats); +#endif + +#define VK_KHR_variable_pointers 1 +#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1 +#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers" + +typedef VkPhysicalDeviceVariablePointerFeatures VkPhysicalDeviceVariablePointerFeaturesKHR; + + + +#define VK_KHR_dedicated_allocation 1 +#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 +#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" + +typedef VkMemoryDedicatedRequirements VkMemoryDedicatedRequirementsKHR; + +typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR; + + + +#define VK_KHR_storage_buffer_storage_class 1 +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1 +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" + + +#define VK_KHR_relaxed_block_layout 1 +#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout" + + +#define VK_KHR_get_memory_requirements2 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" + +typedef VkBufferMemoryRequirementsInfo2 VkBufferMemoryRequirementsInfo2KHR; + +typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR; + +typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR; + +typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; + +typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR; + + +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR( + VkDevice device, + const VkImageMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR( + VkDevice device, + const VkBufferMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( + VkDevice device, + const VkImageSparseMemoryRequirementsInfo2* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + +#define VK_KHR_image_format_list 1 +#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 +#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" + +typedef struct VkImageFormatListCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkImageFormatListCreateInfoKHR; + + + +#define VK_KHR_sampler_ycbcr_conversion 1 +typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR; + + +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" + +typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConversionKHR; + +typedef VkSamplerYcbcrRange VkSamplerYcbcrRangeKHR; + +typedef VkChromaLocation VkChromaLocationKHR; + + +typedef VkSamplerYcbcrConversionCreateInfo VkSamplerYcbcrConversionCreateInfoKHR; + +typedef VkSamplerYcbcrConversionInfo VkSamplerYcbcrConversionInfoKHR; + +typedef VkBindImagePlaneMemoryInfo VkBindImagePlaneMemoryInfoKHR; + +typedef VkImagePlaneMemoryRequirementsInfo VkImagePlaneMemoryRequirementsInfoKHR; + +typedef VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR; + +typedef VkSamplerYcbcrConversionImageFormatProperties VkSamplerYcbcrConversionImageFormatPropertiesKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR( + VkDevice device, + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversion* pYcbcrConversion); + +VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR( + VkDevice device, + VkSamplerYcbcrConversion ycbcrConversion, + const VkAllocationCallbacks* pAllocator); +#endif + +#define VK_KHR_bind_memory2 1 +#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1 +#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2" + +typedef VkBindBufferMemoryInfo VkBindBufferMemoryInfoKHR; + +typedef VkBindImageMemoryInfo VkBindImageMemoryInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR( + VkDevice device, + uint32_t bindInfoCount, + const VkBindBufferMemoryInfo* pBindInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( + VkDevice device, + uint32_t bindInfoCount, + const VkBindImageMemoryInfo* pBindInfos); +#endif + +#define VK_KHR_maintenance3 1 +#define VK_KHR_MAINTENANCE3_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3" + +typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; + +typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; + + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + VkDescriptorSetLayoutSupport* pSupport); +#endif + +#define VK_EXT_debug_report 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) + +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9 +#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" +#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT +#define VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT + + +typedef enum VkDebugReportObjectTypeEXT { + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, + VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, + VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, + VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, + VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, + VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, + VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, + VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, + VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, + VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, + VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, + VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, + VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, + VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31, + VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32, + VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1), + VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportObjectTypeEXT; + + +typedef enum VkDebugReportFlagBitsEXT { + VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, + VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, + VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, + VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportFlagBitsEXT; +typedef VkFlags VkDebugReportFlagsEXT; + +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData); + +typedef struct VkDebugReportCallbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportFlagsEXT flags; + PFN_vkDebugReportCallbackEXT pfnCallback; + void* pUserData; +} VkDebugReportCallbackCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugReportCallbackEXT* pCallback); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( + VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage); +#endif + +#define VK_NV_glsl_shader 1 +#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 +#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" + + +#define VK_EXT_depth_range_unrestricted 1 +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1 +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted" + + +#define VK_IMG_filter_cubic 1 +#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 +#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" + + +#define VK_AMD_rasterization_order 1 +#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 +#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" + + +typedef enum VkRasterizationOrderAMD { + VK_RASTERIZATION_ORDER_STRICT_AMD = 0, + VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, + VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD, + VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD, + VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1), + VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF +} VkRasterizationOrderAMD; + +typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { + VkStructureType sType; + const void* pNext; + VkRasterizationOrderAMD rasterizationOrder; +} VkPipelineRasterizationStateRasterizationOrderAMD; + + + +#define VK_AMD_shader_trinary_minmax 1 +#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1 +#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax" + + +#define VK_AMD_shader_explicit_vertex_parameter 1 +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1 +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter" + + +#define VK_EXT_debug_marker 1 +#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4 +#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker" + +typedef struct VkDebugMarkerObjectNameInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + const char* pObjectName; +} VkDebugMarkerObjectNameInfoEXT; + +typedef struct VkDebugMarkerObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugMarkerObjectTagInfoEXT; + +typedef struct VkDebugMarkerMarkerInfoEXT { + VkStructureType sType; + const void* pNext; + const char* pMarkerName; + float color[4]; +} VkDebugMarkerMarkerInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo); +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( + VkDevice device, + const VkDebugMarkerObjectTagInfoEXT* pTagInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( + VkDevice device, + const VkDebugMarkerObjectNameInfoEXT* pNameInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( + VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( + VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +#endif + +#define VK_AMD_gcn_shader 1 +#define VK_AMD_GCN_SHADER_SPEC_VERSION 1 +#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader" + + +#define VK_NV_dedicated_allocation 1 +#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1 +#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation" + +typedef struct VkDedicatedAllocationImageCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationImageCreateInfoNV; + +typedef struct VkDedicatedAllocationBufferCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationBufferCreateInfoNV; + +typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { + VkStructureType sType; + const void* pNext; + VkImage image; + VkBuffer buffer; +} VkDedicatedAllocationMemoryAllocateInfoNV; + + + +#define VK_AMD_draw_indirect_count 1 +#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" + +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + +#define VK_AMD_negative_viewport_height 1 +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1 +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height" + + +#define VK_AMD_gpu_shader_half_float 1 +#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1 +#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float" + + +#define VK_AMD_shader_ballot 1 +#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1 +#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot" + + +#define VK_AMD_texture_gather_bias_lod 1 +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1 +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod" + +typedef struct VkTextureLODGatherFormatPropertiesAMD { + VkStructureType sType; + void* pNext; + VkBool32 supportsTextureGatherLODBiasAMD; +} VkTextureLODGatherFormatPropertiesAMD; + + + +#define VK_AMD_shader_info 1 +#define VK_AMD_SHADER_INFO_SPEC_VERSION 1 +#define VK_AMD_SHADER_INFO_EXTENSION_NAME "VK_AMD_shader_info" + + +typedef enum VkShaderInfoTypeAMD { + VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, + VK_SHADER_INFO_TYPE_BINARY_AMD = 1, + VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, + VK_SHADER_INFO_TYPE_BEGIN_RANGE_AMD = VK_SHADER_INFO_TYPE_STATISTICS_AMD, + VK_SHADER_INFO_TYPE_END_RANGE_AMD = VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, + VK_SHADER_INFO_TYPE_RANGE_SIZE_AMD = (VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD - VK_SHADER_INFO_TYPE_STATISTICS_AMD + 1), + VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkShaderInfoTypeAMD; + +typedef struct VkShaderResourceUsageAMD { + uint32_t numUsedVgprs; + uint32_t numUsedSgprs; + uint32_t ldsSizePerLocalWorkGroup; + size_t ldsUsageSizeInBytes; + size_t scratchMemUsageInBytes; +} VkShaderResourceUsageAMD; + +typedef struct VkShaderStatisticsInfoAMD { + VkShaderStageFlags shaderStageMask; + VkShaderResourceUsageAMD resourceUsage; + uint32_t numPhysicalVgprs; + uint32_t numPhysicalSgprs; + uint32_t numAvailableVgprs; + uint32_t numAvailableSgprs; + uint32_t computeWorkGroupSize[3]; +} VkShaderStatisticsInfoAMD; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( + VkDevice device, + VkPipeline pipeline, + VkShaderStageFlagBits shaderStage, + VkShaderInfoTypeAMD infoType, + size_t* pInfoSize, + void* pInfo); +#endif + +#define VK_AMD_shader_image_load_store_lod 1 +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1 +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod" + + +#define VK_IMG_format_pvrtc 1 +#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 +#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" + + +#define VK_NV_external_memory_capabilities 1 +#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities" + + +typedef enum VkExternalMemoryHandleTypeFlagBitsNV { + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkExternalMemoryHandleTypeFlagBitsNV; +typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; + +typedef enum VkExternalMemoryFeatureFlagBitsNV { + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkExternalMemoryFeatureFlagBitsNV; +typedef VkFlags VkExternalMemoryFeatureFlagsNV; + +typedef struct VkExternalImageFormatPropertiesNV { + VkImageFormatProperties imageFormatProperties; + VkExternalMemoryFeatureFlagsNV externalMemoryFeatures; + VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes; + VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes; +} VkExternalImageFormatPropertiesNV; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkExternalMemoryHandleTypeFlagsNV externalHandleType, + VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); +#endif + +#define VK_NV_external_memory 1 +#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory" + +typedef struct VkExternalMemoryImageCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagsNV handleTypes; +} VkExternalMemoryImageCreateInfoNV; + +typedef struct VkExportMemoryAllocateInfoNV { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagsNV handleTypes; +} VkExportMemoryAllocateInfoNV; + + + +#define VK_EXT_validation_flags 1 +#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags" + + +typedef enum VkValidationCheckEXT { + VK_VALIDATION_CHECK_ALL_EXT = 0, + VK_VALIDATION_CHECK_SHADERS_EXT = 1, + VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT, + VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_SHADERS_EXT, + VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_SHADERS_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1), + VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationCheckEXT; + +typedef struct VkValidationFlagsEXT { + VkStructureType sType; + const void* pNext; + uint32_t disabledValidationCheckCount; + VkValidationCheckEXT* pDisabledValidationChecks; +} VkValidationFlagsEXT; + + + +#define VK_EXT_shader_subgroup_ballot 1 +#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot" + + +#define VK_EXT_shader_subgroup_vote 1 +#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" + + +#define VK_NVX_device_generated_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX) + +#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 +#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands" + + +typedef enum VkIndirectCommandsTokenTypeNVX { + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX = 0, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX = 1, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX = 2, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX = 3, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX = 4, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX = 5, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX = 6, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX + 1), + VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF +} VkIndirectCommandsTokenTypeNVX; + +typedef enum VkObjectEntryTypeNVX { + VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX = 0, + VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX = 1, + VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX = 2, + VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX = 3, + VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX = 4, + VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX, + VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX, + VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX + 1), + VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF +} VkObjectEntryTypeNVX; + + +typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX { + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF +} VkIndirectCommandsLayoutUsageFlagBitsNVX; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX; + +typedef enum VkObjectEntryUsageFlagBitsNVX { + VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001, + VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002, + VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF +} VkObjectEntryUsageFlagBitsNVX; +typedef VkFlags VkObjectEntryUsageFlagsNVX; + +typedef struct VkDeviceGeneratedCommandsFeaturesNVX { + VkStructureType sType; + const void* pNext; + VkBool32 computeBindingPointSupport; +} VkDeviceGeneratedCommandsFeaturesNVX; + +typedef struct VkDeviceGeneratedCommandsLimitsNVX { + VkStructureType sType; + const void* pNext; + uint32_t maxIndirectCommandsLayoutTokenCount; + uint32_t maxObjectEntryCounts; + uint32_t minSequenceCountBufferOffsetAlignment; + uint32_t minSequenceIndexBufferOffsetAlignment; + uint32_t minCommandsTokenBufferOffsetAlignment; +} VkDeviceGeneratedCommandsLimitsNVX; + +typedef struct VkIndirectCommandsTokenNVX { + VkIndirectCommandsTokenTypeNVX tokenType; + VkBuffer buffer; + VkDeviceSize offset; +} VkIndirectCommandsTokenNVX; + +typedef struct VkIndirectCommandsLayoutTokenNVX { + VkIndirectCommandsTokenTypeNVX tokenType; + uint32_t bindingUnit; + uint32_t dynamicCount; + uint32_t divisor; +} VkIndirectCommandsLayoutTokenNVX; + +typedef struct VkIndirectCommandsLayoutCreateInfoNVX { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkIndirectCommandsLayoutUsageFlagsNVX flags; + uint32_t tokenCount; + const VkIndirectCommandsLayoutTokenNVX* pTokens; +} VkIndirectCommandsLayoutCreateInfoNVX; + +typedef struct VkCmdProcessCommandsInfoNVX { + VkStructureType sType; + const void* pNext; + VkObjectTableNVX objectTable; + VkIndirectCommandsLayoutNVX indirectCommandsLayout; + uint32_t indirectCommandsTokenCount; + const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens; + uint32_t maxSequencesCount; + VkCommandBuffer targetCommandBuffer; + VkBuffer sequencesCountBuffer; + VkDeviceSize sequencesCountOffset; + VkBuffer sequencesIndexBuffer; + VkDeviceSize sequencesIndexOffset; +} VkCmdProcessCommandsInfoNVX; + +typedef struct VkCmdReserveSpaceForCommandsInfoNVX { + VkStructureType sType; + const void* pNext; + VkObjectTableNVX objectTable; + VkIndirectCommandsLayoutNVX indirectCommandsLayout; + uint32_t maxSequencesCount; +} VkCmdReserveSpaceForCommandsInfoNVX; + +typedef struct VkObjectTableCreateInfoNVX { + VkStructureType sType; + const void* pNext; + uint32_t objectCount; + const VkObjectEntryTypeNVX* pObjectEntryTypes; + const uint32_t* pObjectEntryCounts; + const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags; + uint32_t maxUniformBuffersPerDescriptor; + uint32_t maxStorageBuffersPerDescriptor; + uint32_t maxStorageImagesPerDescriptor; + uint32_t maxSampledImagesPerDescriptor; + uint32_t maxPipelineLayouts; +} VkObjectTableCreateInfoNVX; + +typedef struct VkObjectTableEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; +} VkObjectTableEntryNVX; + +typedef struct VkObjectTablePipelineEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; + VkPipeline pipeline; +} VkObjectTablePipelineEntryNVX; + +typedef struct VkObjectTableDescriptorSetEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; + VkPipelineLayout pipelineLayout; + VkDescriptorSet descriptorSet; +} VkObjectTableDescriptorSetEntryNVX; + +typedef struct VkObjectTableVertexBufferEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; + VkBuffer buffer; +} VkObjectTableVertexBufferEntryNVX; + +typedef struct VkObjectTableIndexBufferEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; + VkBuffer buffer; + VkIndexType indexType; +} VkObjectTableIndexBufferEntryNVX; + +typedef struct VkObjectTablePushConstantEntryNVX { + VkObjectEntryTypeNVX type; + VkObjectEntryUsageFlagsNVX flags; + VkPipelineLayout pipelineLayout; + VkShaderStageFlags stageFlags; +} VkObjectTablePushConstantEntryNVX; + + +typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable); +typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices); +typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX( + VkCommandBuffer commandBuffer, + const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX( + VkCommandBuffer commandBuffer, + const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX( + VkDevice device, + const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX( + VkDevice device, + VkIndirectCommandsLayoutNVX indirectCommandsLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX( + VkDevice device, + const VkObjectTableCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkObjectTableNVX* pObjectTable); + +VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX( + VkDevice device, + VkObjectTableNVX objectTable, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX( + VkDevice device, + VkObjectTableNVX objectTable, + uint32_t objectCount, + const VkObjectTableEntryNVX* const* ppObjectTableEntries, + const uint32_t* pObjectIndices); + +VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX( + VkDevice device, + VkObjectTableNVX objectTable, + uint32_t objectCount, + const VkObjectEntryTypeNVX* pObjectEntryTypes, + const uint32_t* pObjectIndices); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX( + VkPhysicalDevice physicalDevice, + VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, + VkDeviceGeneratedCommandsLimitsNVX* pLimits); +#endif + +#define VK_NV_clip_space_w_scaling 1 +#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 +#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" + +typedef struct VkViewportWScalingNV { + float xcoeff; + float ycoeff; +} VkViewportWScalingNV; + +typedef struct VkPipelineViewportWScalingStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 viewportWScalingEnable; + uint32_t viewportCount; + const VkViewportWScalingNV* pViewportWScalings; +} VkPipelineViewportWScalingStateCreateInfoNV; + + +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewportWScalingNV* pViewportWScalings); +#endif + +#define VK_EXT_direct_mode_display 1 +#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1 +#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display" + +typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display); +#endif + +#define VK_EXT_display_surface_counter 1 +#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1 +#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" +#define VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT + + +typedef enum VkSurfaceCounterFlagBitsEXT { + VK_SURFACE_COUNTER_VBLANK_EXT = 0x00000001, + VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSurfaceCounterFlagBitsEXT; +typedef VkFlags VkSurfaceCounterFlagsEXT; + +typedef struct VkSurfaceCapabilities2EXT { + VkStructureType sType; + void* pNext; + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; + VkSurfaceCounterFlagsEXT supportedSurfaceCounters; +} VkSurfaceCapabilities2EXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT* pSurfaceCapabilities); +#endif + +#define VK_EXT_display_control 1 +#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control" + + +typedef enum VkDisplayPowerStateEXT { + VK_DISPLAY_POWER_STATE_OFF_EXT = 0, + VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, + VK_DISPLAY_POWER_STATE_ON_EXT = 2, + VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT, + VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT, + VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1), + VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDisplayPowerStateEXT; + +typedef enum VkDeviceEventTypeEXT { + VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, + VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, + VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, + VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1), + VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceEventTypeEXT; + +typedef enum VkDisplayEventTypeEXT { + VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, + VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, + VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, + VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1), + VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDisplayEventTypeEXT; + +typedef struct VkDisplayPowerInfoEXT { + VkStructureType sType; + const void* pNext; + VkDisplayPowerStateEXT powerState; +} VkDisplayPowerInfoEXT; + +typedef struct VkDeviceEventInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceEventTypeEXT deviceEvent; +} VkDeviceEventInfoEXT; + +typedef struct VkDisplayEventInfoEXT { + VkStructureType sType; + const void* pNext; + VkDisplayEventTypeEXT displayEvent; +} VkDisplayEventInfoEXT; + +typedef struct VkSwapchainCounterCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkSurfaceCounterFlagsEXT surfaceCounters; +} VkSwapchainCounterCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT( + VkDevice device, + VkDisplayKHR display, + const VkDisplayPowerInfoEXT* pDisplayPowerInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT( + VkDevice device, + const VkDeviceEventInfoEXT* pDeviceEventInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT( + VkDevice device, + VkDisplayKHR display, + const VkDisplayEventInfoEXT* pDisplayEventInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT( + VkDevice device, + VkSwapchainKHR swapchain, + VkSurfaceCounterFlagBitsEXT counter, + uint64_t* pCounterValue); +#endif + +#define VK_GOOGLE_display_timing 1 +#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 +#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing" + +typedef struct VkRefreshCycleDurationGOOGLE { + uint64_t refreshDuration; +} VkRefreshCycleDurationGOOGLE; + +typedef struct VkPastPresentationTimingGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; + uint64_t actualPresentTime; + uint64_t earliestPresentTime; + uint64_t presentMargin; +} VkPastPresentationTimingGOOGLE; + +typedef struct VkPresentTimeGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; +} VkPresentTimeGOOGLE; + +typedef struct VkPresentTimesInfoGOOGLE { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentTimeGOOGLE* pTimes; +} VkPresentTimesInfoGOOGLE; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pPresentationTimingCount, + VkPastPresentationTimingGOOGLE* pPresentationTimings); +#endif + +#define VK_NV_sample_mask_override_coverage 1 +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1 +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage" + + +#define VK_NV_geometry_shader_passthrough 1 +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1 +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough" + + +#define VK_NV_viewport_array2 1 +#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2" + + +#define VK_NVX_multiview_per_view_attributes 1 +#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1 +#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes" + +typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX { + VkStructureType sType; + void* pNext; + VkBool32 perViewPositionAllComponents; +} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX; + + + +#define VK_NV_viewport_swizzle 1 +#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle" + + +typedef enum VkViewportCoordinateSwizzleNV { + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, + VK_VIEWPORT_COORDINATE_SWIZZLE_BEGIN_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, + VK_VIEWPORT_COORDINATE_SWIZZLE_END_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV, + VK_VIEWPORT_COORDINATE_SWIZZLE_RANGE_SIZE_NV = (VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV + 1), + VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF +} VkViewportCoordinateSwizzleNV; + +typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; + +typedef struct VkViewportSwizzleNV { + VkViewportCoordinateSwizzleNV x; + VkViewportCoordinateSwizzleNV y; + VkViewportCoordinateSwizzleNV z; + VkViewportCoordinateSwizzleNV w; +} VkViewportSwizzleNV; + +typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineViewportSwizzleStateCreateFlagsNV flags; + uint32_t viewportCount; + const VkViewportSwizzleNV* pViewportSwizzles; +} VkPipelineViewportSwizzleStateCreateInfoNV; + + + +#define VK_EXT_discard_rectangles 1 +#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1 +#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles" + + +typedef enum VkDiscardRectangleModeEXT { + VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, + VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, + VK_DISCARD_RECTANGLE_MODE_BEGIN_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT, + VK_DISCARD_RECTANGLE_MODE_END_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT, + VK_DISCARD_RECTANGLE_MODE_RANGE_SIZE_EXT = (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT + 1), + VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDiscardRectangleModeEXT; + +typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; + +typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxDiscardRectangles; +} VkPhysicalDeviceDiscardRectanglePropertiesEXT; + +typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineDiscardRectangleStateCreateFlagsEXT flags; + VkDiscardRectangleModeEXT discardRectangleMode; + uint32_t discardRectangleCount; + const VkRect2D* pDiscardRectangles; +} VkPipelineDiscardRectangleStateCreateInfoEXT; + + +typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( + VkCommandBuffer commandBuffer, + uint32_t firstDiscardRectangle, + uint32_t discardRectangleCount, + const VkRect2D* pDiscardRectangles); +#endif + +#define VK_EXT_conservative_rasterization 1 +#define VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION 1 +#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization" + + +typedef enum VkConservativeRasterizationModeEXT { + VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, + VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, + VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, + VK_CONSERVATIVE_RASTERIZATION_MODE_BEGIN_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, + VK_CONSERVATIVE_RASTERIZATION_MODE_END_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, + VK_CONSERVATIVE_RASTERIZATION_MODE_RANGE_SIZE_EXT = (VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT + 1), + VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkConservativeRasterizationModeEXT; + +typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; + +typedef struct VkPhysicalDeviceConservativeRasterizationPropertiesEXT { + VkStructureType sType; + void* pNext; + float primitiveOverestimationSize; + float maxExtraPrimitiveOverestimationSize; + float extraPrimitiveOverestimationSizeGranularity; + VkBool32 primitiveUnderestimation; + VkBool32 conservativePointAndLineRasterization; + VkBool32 degenerateTrianglesRasterized; + VkBool32 degenerateLinesRasterized; + VkBool32 fullyCoveredFragmentShaderInputVariable; + VkBool32 conservativeRasterizationPostDepthCoverage; +} VkPhysicalDeviceConservativeRasterizationPropertiesEXT; + +typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationConservativeStateCreateFlagsEXT flags; + VkConservativeRasterizationModeEXT conservativeRasterizationMode; + float extraPrimitiveOverestimationSize; +} VkPipelineRasterizationConservativeStateCreateInfoEXT; + + + +#define VK_EXT_swapchain_colorspace 1 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 3 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" + + +#define VK_EXT_hdr_metadata 1 +#define VK_EXT_HDR_METADATA_SPEC_VERSION 1 +#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" + +typedef struct VkXYColorEXT { + float x; + float y; +} VkXYColorEXT; + +typedef struct VkHdrMetadataEXT { + VkStructureType sType; + const void* pNext; + VkXYColorEXT displayPrimaryRed; + VkXYColorEXT displayPrimaryGreen; + VkXYColorEXT displayPrimaryBlue; + VkXYColorEXT whitePoint; + float maxLuminance; + float minLuminance; + float maxContentLightLevel; + float maxFrameAverageLightLevel; +} VkHdrMetadataEXT; + + +typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainKHR* pSwapchains, + const VkHdrMetadataEXT* pMetadata); +#endif + +#define VK_EXT_external_memory_dma_buf 1 +#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME "VK_EXT_external_memory_dma_buf" + + +#define VK_EXT_queue_family_foreign 1 +#define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1 +#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign" +#define VK_QUEUE_FAMILY_FOREIGN_EXT (~0U-2) + + +#define VK_EXT_debug_utils 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) + +#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 1 +#define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils" + +typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; + +typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { + VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugUtilsMessageSeverityFlagBitsEXT; +typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; + +typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001, + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002, + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004, + VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugUtilsMessageTypeFlagBitsEXT; +typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; + +typedef struct VkDebugUtilsObjectNameInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + const char* pObjectName; +} VkDebugUtilsObjectNameInfoEXT; + +typedef struct VkDebugUtilsObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugUtilsObjectTagInfoEXT; + +typedef struct VkDebugUtilsLabelEXT { + VkStructureType sType; + const void* pNext; + const char* pLabelName; + float color[4]; +} VkDebugUtilsLabelEXT; + +typedef struct VkDebugUtilsMessengerCallbackDataEXT { + VkStructureType sType; + const void* pNext; + VkDebugUtilsMessengerCallbackDataFlagsEXT flags; + const char* pMessageIdName; + int32_t messageIdNumber; + const char* pMessage; + uint32_t queueLabelCount; + VkDebugUtilsLabelEXT* pQueueLabels; + uint32_t cmdBufLabelCount; + VkDebugUtilsLabelEXT* pCmdBufLabels; + uint32_t objectCount; + VkDebugUtilsObjectNameInfoEXT* pObjects; +} VkDebugUtilsMessengerCallbackDataEXT; + +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData); + +typedef struct VkDebugUtilsMessengerCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugUtilsMessengerCreateFlagsEXT flags; + VkDebugUtilsMessageSeverityFlagsEXT messageSeverity; + VkDebugUtilsMessageTypeFlagsEXT messageType; + PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback; + void* pUserData; +} VkDebugUtilsMessengerCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectNameEXT)(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo); +typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectTagEXT)(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo); +typedef void (VKAPI_PTR *PFN_vkQueueBeginDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkQueueEndDebugUtilsLabelEXT)(VkQueue queue); +typedef void (VKAPI_PTR *PFN_vkQueueInsertDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdInsertDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugUtilsMessengerEXT)(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkSubmitDebugUtilsMessageEXT)(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectNameEXT( + VkDevice device, + const VkDebugUtilsObjectNameInfoEXT* pNameInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectTagEXT( + VkDevice device, + const VkDebugUtilsObjectTagInfoEXT* pTagInfo); + +VKAPI_ATTR void VKAPI_CALL vkQueueBeginDebugUtilsLabelEXT( + VkQueue queue, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkQueueEndDebugUtilsLabelEXT( + VkQueue queue); + +VKAPI_ATTR void VKAPI_CALL vkQueueInsertDebugUtilsLabelEXT( + VkQueue queue, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdInsertDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( + VkInstance instance, + const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugUtilsMessengerEXT* pMessenger); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT( + VkInstance instance, + VkDebugUtilsMessengerEXT messenger, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( + VkInstance instance, + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); +#endif + +#define VK_EXT_sampler_filter_minmax 1 +#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 1 +#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" + + +typedef enum VkSamplerReductionModeEXT { + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0, + VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1, + VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2, + VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, + VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT, + VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1), + VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSamplerReductionModeEXT; + +typedef struct VkSamplerReductionModeCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkSamplerReductionModeEXT reductionMode; +} VkSamplerReductionModeCreateInfoEXT; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; + + + +#define VK_AMD_gpu_shader_int16 1 +#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 1 +#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" + + +#define VK_AMD_mixed_attachment_samples 1 +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" + + +#define VK_AMD_shader_fragment_mask 1 +#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1 +#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" + + +#define VK_EXT_shader_stencil_export 1 +#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 +#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" + + +#define VK_EXT_sample_locations 1 +#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1 +#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations" + +typedef struct VkSampleLocationEXT { + float x; + float y; +} VkSampleLocationEXT; + +typedef struct VkSampleLocationsInfoEXT { + VkStructureType sType; + const void* pNext; + VkSampleCountFlagBits sampleLocationsPerPixel; + VkExtent2D sampleLocationGridSize; + uint32_t sampleLocationsCount; + const VkSampleLocationEXT* pSampleLocations; +} VkSampleLocationsInfoEXT; + +typedef struct VkAttachmentSampleLocationsEXT { + uint32_t attachmentIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkAttachmentSampleLocationsEXT; + +typedef struct VkSubpassSampleLocationsEXT { + uint32_t subpassIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkSubpassSampleLocationsEXT; + +typedef struct VkRenderPassSampleLocationsBeginInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t attachmentInitialSampleLocationsCount; + const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations; + uint32_t postSubpassSampleLocationsCount; + const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations; +} VkRenderPassSampleLocationsBeginInfoEXT; + +typedef struct VkPipelineSampleLocationsStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 sampleLocationsEnable; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkPipelineSampleLocationsStateCreateInfoEXT; + +typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT { + VkStructureType sType; + void* pNext; + VkSampleCountFlags sampleLocationSampleCounts; + VkExtent2D maxSampleLocationGridSize; + float sampleLocationCoordinateRange[2]; + uint32_t sampleLocationSubPixelBits; + VkBool32 variableSampleLocations; +} VkPhysicalDeviceSampleLocationsPropertiesEXT; + +typedef struct VkMultisamplePropertiesEXT { + VkStructureType sType; + void* pNext; + VkExtent2D maxSampleLocationGridSize; +} VkMultisamplePropertiesEXT; + + +typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT( + VkCommandBuffer commandBuffer, + const VkSampleLocationsInfoEXT* pSampleLocationsInfo); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT( + VkPhysicalDevice physicalDevice, + VkSampleCountFlagBits samples, + VkMultisamplePropertiesEXT* pMultisampleProperties); +#endif + +#define VK_EXT_blend_operation_advanced 1 +#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2 +#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" + + +typedef enum VkBlendOverlapEXT { + VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, + VK_BLEND_OVERLAP_DISJOINT_EXT = 1, + VK_BLEND_OVERLAP_CONJOINT_EXT = 2, + VK_BLEND_OVERLAP_BEGIN_RANGE_EXT = VK_BLEND_OVERLAP_UNCORRELATED_EXT, + VK_BLEND_OVERLAP_END_RANGE_EXT = VK_BLEND_OVERLAP_CONJOINT_EXT, + VK_BLEND_OVERLAP_RANGE_SIZE_EXT = (VK_BLEND_OVERLAP_CONJOINT_EXT - VK_BLEND_OVERLAP_UNCORRELATED_EXT + 1), + VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF +} VkBlendOverlapEXT; + +typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 advancedBlendCoherentOperations; +} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT; + +typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t advancedBlendMaxColorAttachments; + VkBool32 advancedBlendIndependentBlend; + VkBool32 advancedBlendNonPremultipliedSrcColor; + VkBool32 advancedBlendNonPremultipliedDstColor; + VkBool32 advancedBlendCorrelatedOverlap; + VkBool32 advancedBlendAllOperations; +} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT; + +typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 srcPremultiplied; + VkBool32 dstPremultiplied; + VkBlendOverlapEXT blendOverlap; +} VkPipelineColorBlendAdvancedStateCreateInfoEXT; + + + +#define VK_NV_fragment_coverage_to_color 1 +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" + +typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; + +typedef struct VkPipelineCoverageToColorStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCoverageToColorStateCreateFlagsNV flags; + VkBool32 coverageToColorEnable; + uint32_t coverageToColorLocation; +} VkPipelineCoverageToColorStateCreateInfoNV; + + + +#define VK_NV_framebuffer_mixed_samples 1 +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" + + +typedef enum VkCoverageModulationModeNV { + VK_COVERAGE_MODULATION_MODE_NONE_NV = 0, + VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, + VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, + VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, + VK_COVERAGE_MODULATION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_MODULATION_MODE_NONE_NV, + VK_COVERAGE_MODULATION_MODE_END_RANGE_NV = VK_COVERAGE_MODULATION_MODE_RGBA_NV, + VK_COVERAGE_MODULATION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_MODULATION_MODE_RGBA_NV - VK_COVERAGE_MODULATION_MODE_NONE_NV + 1), + VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCoverageModulationModeNV; + +typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; + +typedef struct VkPipelineCoverageModulationStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCoverageModulationStateCreateFlagsNV flags; + VkCoverageModulationModeNV coverageModulationMode; + VkBool32 coverageModulationTableEnable; + uint32_t coverageModulationTableCount; + const float* pCoverageModulationTable; +} VkPipelineCoverageModulationStateCreateInfoNV; + + + +#define VK_NV_fill_rectangle 1 +#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 +#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle" + + +#define VK_EXT_post_depth_coverage 1 +#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1 +#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" + + +#define VK_EXT_validation_cache 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) + +#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" +#define VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT + + +typedef enum VkValidationCacheHeaderVersionEXT { + VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, + VK_VALIDATION_CACHE_HEADER_VERSION_BEGIN_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, + VK_VALIDATION_CACHE_HEADER_VERSION_END_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, + VK_VALIDATION_CACHE_HEADER_VERSION_RANGE_SIZE_EXT = (VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT + 1), + VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationCacheHeaderVersionEXT; + +typedef VkFlags VkValidationCacheCreateFlagsEXT; + +typedef struct VkValidationCacheCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkValidationCacheCreateFlagsEXT flags; + size_t initialDataSize; + const void* pInitialData; +} VkValidationCacheCreateInfoEXT; + +typedef struct VkShaderModuleValidationCacheCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkValidationCacheEXT validationCache; +} VkShaderModuleValidationCacheCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache); +typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT( + VkDevice device, + const VkValidationCacheCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkValidationCacheEXT* pValidationCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT( + VkDevice device, + VkValidationCacheEXT validationCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT( + VkDevice device, + VkValidationCacheEXT dstCache, + uint32_t srcCacheCount, + const VkValidationCacheEXT* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( + VkDevice device, + VkValidationCacheEXT validationCache, + size_t* pDataSize, + void* pData); +#endif + +#define VK_EXT_shader_viewport_index_layer 1 +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" + + +#define VK_EXT_global_priority 1 +#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 +#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" + + +typedef enum VkQueueGlobalPriorityEXT { + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, + VK_QUEUE_GLOBAL_PRIORITY_BEGIN_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, + VK_QUEUE_GLOBAL_PRIORITY_END_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT, + VK_QUEUE_GLOBAL_PRIORITY_RANGE_SIZE_EXT = (VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT + 1), + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF +} VkQueueGlobalPriorityEXT; + +typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriorityEXT globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoEXT; + + + +#define VK_EXT_external_memory_host 1 +#define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host" + +typedef struct VkImportMemoryHostPointerInfoEXT { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + void* pHostPointer; +} VkImportMemoryHostPointerInfoEXT; + +typedef struct VkMemoryHostPointerPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryHostPointerPropertiesEXT; + +typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize minImportedHostPointerAlignment; +} VkPhysicalDeviceExternalMemoryHostPropertiesEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + const void* pHostPointer, + VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); +#endif + +#define VK_AMD_buffer_marker 1 +#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1 +#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker" + +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + uint32_t marker); +#endif + +#define VK_EXT_vertex_attribute_divisor 1 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 1 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor" + +typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxVertexAttribDivisor; +} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT; + +typedef struct VkVertexInputBindingDivisorDescriptionEXT { + uint32_t binding; + uint32_t divisor; +} VkVertexInputBindingDivisorDescriptionEXT; + +typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t vertexBindingDivisorCount; + const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors; +} VkPipelineVertexInputDivisorStateCreateInfoEXT; + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_ios.h b/ext/vulkan/vulkan_ios.h new file mode 100644 index 0000000000..a0924816d5 --- /dev/null +++ b/ext/vulkan/vulkan_ios.h @@ -0,0 +1,58 @@ +#ifndef VULKAN_IOS_H_ +#define VULKAN_IOS_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_MVK_ios_surface 1 +#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" + +typedef VkFlags VkIOSSurfaceCreateFlagsMVK; + +typedef struct VkIOSSurfaceCreateInfoMVK { + VkStructureType sType; + const void* pNext; + VkIOSSurfaceCreateFlagsMVK flags; + const void* pView; +} VkIOSSurfaceCreateInfoMVK; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK( + VkInstance instance, + const VkIOSSurfaceCreateInfoMVK* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_macos.h b/ext/vulkan/vulkan_macos.h new file mode 100644 index 0000000000..ff0b701801 --- /dev/null +++ b/ext/vulkan/vulkan_macos.h @@ -0,0 +1,58 @@ +#ifndef VULKAN_MACOS_H_ +#define VULKAN_MACOS_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_MVK_macos_surface 1 +#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" + +typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; + +typedef struct VkMacOSSurfaceCreateInfoMVK { + VkStructureType sType; + const void* pNext; + VkMacOSSurfaceCreateFlagsMVK flags; + const void* pView; +} VkMacOSSurfaceCreateInfoMVK; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK( + VkInstance instance, + const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_mir.h b/ext/vulkan/vulkan_mir.h new file mode 100644 index 0000000000..7d24ed27a3 --- /dev/null +++ b/ext/vulkan/vulkan_mir.h @@ -0,0 +1,65 @@ +#ifndef VULKAN_MIR_H_ +#define VULKAN_MIR_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_mir_surface 1 +#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4 +#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface" + +typedef VkFlags VkMirSurfaceCreateFlagsKHR; + +typedef struct VkMirSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkMirSurfaceCreateFlagsKHR flags; + MirConnection* connection; + MirSurface* mirSurface; +} VkMirSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( + VkInstance instance, + const VkMirSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + MirConnection* connection); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_vi.h b/ext/vulkan/vulkan_vi.h new file mode 100644 index 0000000000..015166bfc6 --- /dev/null +++ b/ext/vulkan/vulkan_vi.h @@ -0,0 +1,58 @@ +#ifndef VULKAN_VI_H_ +#define VULKAN_VI_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_NN_vi_surface 1 +#define VK_NN_VI_SURFACE_SPEC_VERSION 1 +#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" + +typedef VkFlags VkViSurfaceCreateFlagsNN; + +typedef struct VkViSurfaceCreateInfoNN { + VkStructureType sType; + const void* pNext; + VkViSurfaceCreateFlagsNN flags; + void* window; +} VkViSurfaceCreateInfoNN; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN( + VkInstance instance, + const VkViSurfaceCreateInfoNN* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_wayland.h b/ext/vulkan/vulkan_wayland.h new file mode 100644 index 0000000000..5ba0827aa3 --- /dev/null +++ b/ext/vulkan/vulkan_wayland.h @@ -0,0 +1,65 @@ +#ifndef VULKAN_WAYLAND_H_ +#define VULKAN_WAYLAND_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_wayland_surface 1 +#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 +#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" + +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; + +typedef struct VkWaylandSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkWaylandSurfaceCreateFlagsKHR flags; + struct wl_display* display; + struct wl_surface* surface; +} VkWaylandSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( + VkInstance instance, + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct wl_display* display); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_win32.h b/ext/vulkan/vulkan_win32.h new file mode 100644 index 0000000000..6a85409ebe --- /dev/null +++ b/ext/vulkan/vulkan_win32.h @@ -0,0 +1,276 @@ +#ifndef VULKAN_WIN32_H_ +#define VULKAN_WIN32_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_win32_surface 1 +#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 +#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" + +typedef VkFlags VkWin32SurfaceCreateFlagsKHR; + +typedef struct VkWin32SurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkWin32SurfaceCreateFlagsKHR flags; + HINSTANCE hinstance; + HWND hwnd; +} VkWin32SurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( + VkInstance instance, + const VkWin32SurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex); +#endif + +#define VK_KHR_external_memory_win32 1 +#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32" + +typedef struct VkImportMemoryWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + HANDLE handle; + LPCWSTR name; +} VkImportMemoryWin32HandleInfoKHR; + +typedef struct VkExportMemoryWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + const SECURITY_ATTRIBUTES* pAttributes; + DWORD dwAccess; + LPCWSTR name; +} VkExportMemoryWin32HandleInfoKHR; + +typedef struct VkMemoryWin32HandlePropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryWin32HandlePropertiesKHR; + +typedef struct VkMemoryGetWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetWin32HandleInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR( + VkDevice device, + const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, + HANDLE* pHandle); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + HANDLE handle, + VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); +#endif + +#define VK_KHR_win32_keyed_mutex 1 +#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1 +#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex" + +typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t acquireCount; + const VkDeviceMemory* pAcquireSyncs; + const uint64_t* pAcquireKeys; + const uint32_t* pAcquireTimeouts; + uint32_t releaseCount; + const VkDeviceMemory* pReleaseSyncs; + const uint64_t* pReleaseKeys; +} VkWin32KeyedMutexAcquireReleaseInfoKHR; + + + +#define VK_KHR_external_semaphore_win32 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32" + +typedef struct VkImportSemaphoreWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkSemaphoreImportFlags flags; + VkExternalSemaphoreHandleTypeFlagBits handleType; + HANDLE handle; + LPCWSTR name; +} VkImportSemaphoreWin32HandleInfoKHR; + +typedef struct VkExportSemaphoreWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + const SECURITY_ATTRIBUTES* pAttributes; + DWORD dwAccess; + LPCWSTR name; +} VkExportSemaphoreWin32HandleInfoKHR; + +typedef struct VkD3D12FenceSubmitInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreValuesCount; + const uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValuesCount; + const uint64_t* pSignalSemaphoreValues; +} VkD3D12FenceSubmitInfoKHR; + +typedef struct VkSemaphoreGetWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkSemaphoreGetWin32HandleInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR( + VkDevice device, + const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( + VkDevice device, + const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, + HANDLE* pHandle); +#endif + +#define VK_KHR_external_fence_win32 1 +#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32" + +typedef struct VkImportFenceWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkFenceImportFlags flags; + VkExternalFenceHandleTypeFlagBits handleType; + HANDLE handle; + LPCWSTR name; +} VkImportFenceWin32HandleInfoKHR; + +typedef struct VkExportFenceWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + const SECURITY_ATTRIBUTES* pAttributes; + DWORD dwAccess; + LPCWSTR name; +} VkExportFenceWin32HandleInfoKHR; + +typedef struct VkFenceGetWin32HandleInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkExternalFenceHandleTypeFlagBits handleType; +} VkFenceGetWin32HandleInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR( + VkDevice device, + const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( + VkDevice device, + const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, + HANDLE* pHandle); +#endif + +#define VK_NV_external_memory_win32 1 +#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32" + +typedef struct VkImportMemoryWin32HandleInfoNV { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagsNV handleType; + HANDLE handle; +} VkImportMemoryWin32HandleInfoNV; + +typedef struct VkExportMemoryWin32HandleInfoNV { + VkStructureType sType; + const void* pNext; + const SECURITY_ATTRIBUTES* pAttributes; + DWORD dwAccess; +} VkExportMemoryWin32HandleInfoNV; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( + VkDevice device, + VkDeviceMemory memory, + VkExternalMemoryHandleTypeFlagsNV handleType, + HANDLE* pHandle); +#endif + +#define VK_NV_win32_keyed_mutex 1 +#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1 +#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" + +typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t acquireCount; + const VkDeviceMemory* pAcquireSyncs; + const uint64_t* pAcquireKeys; + const uint32_t* pAcquireTimeoutMilliseconds; + uint32_t releaseCount; + const VkDeviceMemory* pReleaseSyncs; + const uint64_t* pReleaseKeys; +} VkWin32KeyedMutexAcquireReleaseInfoNV; + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_xcb.h b/ext/vulkan/vulkan_xcb.h new file mode 100644 index 0000000000..ba03600602 --- /dev/null +++ b/ext/vulkan/vulkan_xcb.h @@ -0,0 +1,66 @@ +#ifndef VULKAN_XCB_H_ +#define VULKAN_XCB_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_xcb_surface 1 +#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 +#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" + +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; + +typedef struct VkXcbSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkXcbSurfaceCreateFlagsKHR flags; + xcb_connection_t* connection; + xcb_window_t window; +} VkXcbSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( + VkInstance instance, + const VkXcbSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t* connection, + xcb_visualid_t visual_id); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_xlib.h b/ext/vulkan/vulkan_xlib.h new file mode 100644 index 0000000000..e1d967e018 --- /dev/null +++ b/ext/vulkan/vulkan_xlib.h @@ -0,0 +1,66 @@ +#ifndef VULKAN_XLIB_H_ +#define VULKAN_XLIB_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_KHR_xlib_surface 1 +#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 +#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" + +typedef VkFlags VkXlibSurfaceCreateFlagsKHR; + +typedef struct VkXlibSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display* dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( + VkInstance instance, + const VkXlibSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + Display* dpy, + VisualID visualID); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_xlib_xrandr.h b/ext/vulkan/vulkan_xlib_xrandr.h new file mode 100644 index 0000000000..117d01799e --- /dev/null +++ b/ext/vulkan/vulkan_xlib_xrandr.h @@ -0,0 +1,54 @@ +#ifndef VULKAN_XLIB_XRANDR_H_ +#define VULKAN_XLIB_XRANDR_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2018 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_EXT_acquire_xlib_display 1 +#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 +#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" + +typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); +typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT( + VkPhysicalDevice physicalDevice, + Display* dpy, + VkDisplayKHR display); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT( + VkPhysicalDevice physicalDevice, + Display* dpy, + RROutput rrOutput, + VkDisplayKHR* pDisplay); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/headless/Headless.cpp b/headless/Headless.cpp index cf86f8f923..e280e25b5d 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -371,7 +371,6 @@ int main(int argc, const char* argv[]) g_Config.iNumWorkerThreads = 1; g_Config.iATRACMP3Volume = MAX_CONFIG_VOLUME; g_Config.iSASVolume = MAX_CONFIG_VOLUME; - g_Config.bSoftwareSkinning = true; g_Config.bVertexDecoderJit = true; g_Config.bBlockTransferGPU = true; g_Config.iSplineBezierQuality = 2; diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index 17026f7fca..ed60e409d9 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -36,6 +36,7 @@ #include "gfx_es2/gpu_features.h" #include "file/vfs.h" #include "file/zip_read.h" +#include "thin3d/thin3d_create.h" const bool WINDOW_VISIBLE = false; const int WINDOW_WIDTH = 480; diff --git a/ios/ViewController.h b/ios/ViewController.h index eda8722ec2..4eedd89e7c 100644 --- a/ios/ViewController.h +++ b/ios/ViewController.h @@ -9,4 +9,8 @@ @interface ViewController : GLKViewController +- (void)shutdown; + @end + +extern __unsafe_unretained ViewController* sharedViewController; diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 2ec8d7e7a7..4f7dcaad16 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -16,6 +16,8 @@ #include "net/resolve.h" #include "ui/screen.h" #include "thin3d/thin3d.h" +#include "thin3d/thin3d_create.h" +#include "thin3d/GLRenderManager.h" #include "input/keycodes.h" #include "gfx_es2/gpu_features.h" @@ -30,23 +32,41 @@ #define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) #define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) -class IOSDummyGraphicsContext : public DummyGraphicsContext { +class IOSGraphicsContext : public DummyGraphicsContext { public: - IOSDummyGraphicsContext() { + IOSGraphicsContext() { CheckGLExtensions(); draw_ = Draw::T3DCreateGLContext(); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); assert(success); } - ~IOSDummyGraphicsContext() { + ~IOSGraphicsContext() { delete draw_; } Draw::DrawContext *GetDrawContext() override { return draw_; } + void ThreadStart() override { + renderManager_->ThreadStart(); + } + + bool ThreadFrame() override { + return renderManager_->ThreadFrame(); + } + + void ThreadEnd() override { + renderManager_->ThreadEnd(); + } + + void StopThread() override { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); + } private: Draw::DrawContext *draw_; + GLRenderManager *renderManager_; }; static float dp_xscale = 1.0f; @@ -55,8 +75,10 @@ static float dp_yscale = 1.0f; static double lastSelectPress = 0.0f; static double lastStartPress = 0.0f; static bool simulateAnalog = false; +static bool threadEnabled = true; +static bool threadStopped = false; -__unsafe_unretained static ViewController* sharedViewController; +__unsafe_unretained ViewController* sharedViewController; static GraphicsContext *graphicsContext; @interface ViewController () @@ -94,6 +116,8 @@ static GraphicsContext *graphicsContext; iCadeToKeyMap[iCadeButtonG] = NKCODE_BUTTON_1; // Triangle iCadeToKeyMap[iCadeButtonH] = NKCODE_BUTTON_3; // Circle + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil]; + #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1 if ([GCController class]) // Checking the availability of a GameController framework { @@ -153,9 +177,9 @@ static GraphicsContext *graphicsContext; pixel_in_dps_x = (float)pixel_xres / (float)dp_xres; pixel_in_dps_y = (float)pixel_yres / (float)dp_yres; - graphicsContext = new IOSDummyGraphicsContext(); - - NativeInitGraphics(graphicsContext); + graphicsContext = new IOSGraphicsContext(); + + graphicsContext->ThreadStart(); dp_xscale = (float)dp_xres / (float)pixel_xres; dp_yscale = (float)dp_yres / (float)pixel_yres; @@ -172,6 +196,26 @@ static GraphicsContext *graphicsContext; } } #endif + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + NativeInitGraphics(graphicsContext); + + ILOG("Emulation thread starting\n"); + while (threadEnabled) { + NativeUpdate(); + NativeRender(graphicsContext); + time_update(); + } + + threadStopped = true; + + ILOG("Emulation thread shutting down\n"); + NativeShutdownGraphics(); + + // Also ask the main thread to stop, so it doesn't hang waiting for a new frame. + ILOG("Emulation thread stopping\n"); + graphicsContext->StopThread(); + }); } - (void)didReceiveMemoryWarning @@ -179,29 +223,60 @@ static GraphicsContext *graphicsContext; [super didReceiveMemoryWarning]; } -- (void)dealloc +- (void)appWillTerminate:(NSNotification *)notification { - sharedViewController = nil; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; + [self shutdown]; +} + +- (void)shutdown +{ + if (sharedViewController == nil) { + return; } - self.context = nil; + + Audio_Shutdown(); + + if (threadEnabled) { + threadEnabled = false; + while (graphicsContext->ThreadFrame()) { + continue; + } + while (!threadStopped) {} + graphicsContext->ThreadEnd(); + } + + sharedViewController = nil; + + if (self.context) { + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + [[NSNotificationCenter defaultCenter] removeObserver:self]; #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1 if ([GCController class]) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:GCControllerDidConnectNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:GCControllerDidDisconnectNotification object:nil]; self.gameController = nil; } #endif - NativeShutdownGraphics(); + graphicsContext->Shutdown(); - delete graphicsContext; - graphicsContext = NULL; + + if (graphicsContext) { + delete graphicsContext; + graphicsContext = NULL; + } + NativeShutdown(); } +- (void)dealloc +{ + [self shutdown]; +} + // For iOS before 6.0 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { @@ -216,9 +291,8 @@ static GraphicsContext *graphicsContext; - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { - NativeUpdate(); - NativeRender(graphicsContext); - time_update(); + if (sharedViewController) + graphicsContext->ThreadFrame(); } - (void)touchX:(float)x y:(float)y code:(int)code pointerId:(int)pointerId diff --git a/ios/main.mm b/ios/main.mm index 8a5817982a..7e614bce38 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -9,6 +9,7 @@ #import "AppDelegate.h" #import "PPSSPPUIApplication.h" +#import "ViewController.h" #include "base/NativeApp.h" #include "profiler/profiler.h" @@ -24,6 +25,8 @@ @implementation UIApplication (SpringBoardAnimatedExit) -(void) animatedExit { + [sharedViewController shutdown]; + BOOL multitaskingSupported = NO; if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { multitaskingSupported = [UIDevice currentDevice].multitaskingSupported; @@ -40,6 +43,8 @@ } -(void) exit { + [sharedViewController shutdown]; + if ([self respondsToSelector:@selector(terminateWithSuccess)]) { [self terminateWithSuccess]; } else { @@ -89,7 +94,9 @@ bool System_GetPropertyBool(SystemProperty prop) { void System_SendMessage(const char *command, const char *parameter) { if (!strcmp(command, "finish")) { - [[UIApplication sharedApplication] animatedExit]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[UIApplication sharedApplication] animatedExit]; + }); } } diff --git a/unittest/TestVertexJit.cpp b/unittest/TestVertexJit.cpp index 40dd640c8b..dc964c4564 100644 --- a/unittest/TestVertexJit.cpp +++ b/unittest/TestVertexJit.cpp @@ -543,7 +543,6 @@ static bool TestVertexColor565() { static bool TestVertex8Skin() { VertexDecoderTestHarness dec; - g_Config.bSoftwareSkinning = true; for (int i = 0; i < 8 * 12; ++i) { gstate.boneMatrix[i] = 0.0f; } @@ -573,7 +572,6 @@ static bool TestVertex8Skin() { static bool TestVertex16Skin() { VertexDecoderTestHarness dec; - g_Config.bSoftwareSkinning = true; for (int i = 0; i < 8 * 12; ++i) { gstate.boneMatrix[i] = 0.0f; } @@ -603,7 +601,6 @@ static bool TestVertex16Skin() { static bool TestVertexFloatSkin() { VertexDecoderTestHarness dec; - g_Config.bSoftwareSkinning = true; for (int i = 0; i < 8 * 12; ++i) { gstate.boneMatrix[i] = 0.0f; }