From 6ef4054f8a8aea4ec61481057fa7e16aaecde6d7 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 10 Mar 2021 10:58:15 -0800 Subject: Swapchain resize and rename to `IDevice` (#1741) * Swapchain resize * Fix. --- tools/gfx/vulkan/render-vk.cpp | 484 +++++++++++++++++++++++++++++-------- tools/gfx/vulkan/render-vk.h | 2 +- tools/gfx/vulkan/vk-swap-chain.cpp | 283 ---------------------- tools/gfx/vulkan/vk-swap-chain.h | 135 ----------- 4 files changed, 381 insertions(+), 523 deletions(-) delete mode 100644 tools/gfx/vulkan/vk-swap-chain.cpp delete mode 100644 tools/gfx/vulkan/vk-swap-chain.h (limited to 'tools/gfx/vulkan') diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 859519c6d..c0ece3e2f 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -11,7 +11,6 @@ #include "vk-api.h" #include "vk-util.h" #include "vk-device-queue.h" -#include "vk-swap-chain.h" // Vulkan has a different coordinate system to ogl // http://anki3d.org/vulkan-coordinate-system/ @@ -34,7 +33,7 @@ namespace gfx { using namespace Slang; -class VKRenderer : public GraphicsAPIRenderer +class VKDevice : public GraphicsAPIRenderer { public: enum @@ -111,12 +110,12 @@ public: size_t size, ISlangBlob** outBlob) override; void waitForGpu(); - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::Vulkan; + return m_info; } /// Dtor - ~VKRenderer(); + ~VKDevice(); class Buffer { @@ -167,7 +166,7 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(IResource::Usage initialUsage, const IBufferResource::Desc& desc, VKRenderer* renderer): + BufferResourceImpl(IResource::Usage initialUsage, const IBufferResource::Desc& desc, VKDevice* renderer): Parent(desc), m_renderer(renderer), m_initialUsage(initialUsage) @@ -176,7 +175,7 @@ public: } IResource::Usage m_initialUsage; - VKRenderer* m_renderer; + VKDevice* m_renderer; Buffer m_buffer; Buffer m_uploadBuffer; }; @@ -322,7 +321,7 @@ public: public: VkRenderPass m_renderPass; - VKRenderer* m_renderer; + VKDevice* m_renderer; Array m_attachmentDescs; Array m_colorReferences; VkAttachmentReference m_depthReference; @@ -333,7 +332,7 @@ public: { m_renderer->m_api.vkDestroyRenderPass(m_renderer->m_api.m_device, m_renderPass, nullptr); } - Result init(VKRenderer* renderer, const IFramebufferLayout::Desc& desc) + Result init(VKDevice* renderer, const IFramebufferLayout::Desc& desc) { m_renderer = renderer; m_renderTargetCount = desc.renderTargetCount; @@ -435,7 +434,7 @@ public: public: VkRenderPass m_renderPass; - VKRenderer* m_renderer; + VKDevice* m_renderer; ~RenderPassLayoutImpl() { @@ -467,7 +466,7 @@ public: } } - Result init(VKRenderer* renderer, const IRenderPassLayout::Desc& desc) + Result init(VKDevice* renderer, const IRenderPassLayout::Desc& desc) { m_renderer = renderer; @@ -548,7 +547,7 @@ public: ComPtr depthStencilView; uint32_t m_width; uint32_t m_height; - VKRenderer* m_renderer; + VKDevice* m_renderer; VkClearValue m_clearValues[kMaxAttachments]; RefPtr m_layout; public: @@ -556,7 +555,7 @@ public: { m_renderer->m_api.vkDestroyFramebuffer(m_renderer->m_api.m_device, m_handle, nullptr); } - Result init(VKRenderer* renderer, const IFramebuffer::Desc& desc) + Result init(VKDevice* renderer, const IFramebuffer::Desc& desc) { m_renderer = renderer; auto dsv = desc.depthStencilView @@ -791,7 +790,7 @@ public: return nullptr; } public: - DescriptorSetImpl(VKRenderer* renderer) + DescriptorSetImpl(VKDevice* renderer) : m_renderer(renderer) { } @@ -818,7 +817,7 @@ public: UInt size, void const* data) override; - VKRenderer* m_renderer = nullptr; ///< Weak pointer, can't be strong, because if set will become circular reference + VKDevice* m_renderer = nullptr; ///< Weak pointer, can't be strong, because if set will become circular reference RefPtr m_layout; VulkanDescriptorSet m_descriptorSet = {}; @@ -892,14 +891,14 @@ public: VkCommandBuffer m_commandBuffer; VkCommandBuffer m_preCommandBuffer = VK_NULL_HANDLE; VkCommandPool m_pool; - VKRenderer* m_renderer; + VKDevice* m_renderer; DescriptorSetAllocator* m_transientDescSetAllocator; // Command buffers are deallocated by its command pool, // so no need to free individually. ~CommandBufferImpl() = default; Result init( - VKRenderer* renderer, + VKDevice* renderer, VkCommandPool pool, DescriptorSetAllocator* transientDescSetAllocator) { @@ -1107,7 +1106,7 @@ public: m_boundPipelines[pipelineBindPointId] = pipeline->m_pipeline; } - // Next we bind all the descriptor sets that were set in the `VKRenderer`. + // Next we bind all the descriptor sets that were set in the `VKDevice`. // auto pipelineLayoutImpl = static_cast(pipeline->m_pipelineLayout.get()); auto vkPipelineLayout = pipelineLayoutImpl->m_pipelineLayout; @@ -1656,7 +1655,7 @@ public: public: Desc m_desc; uint32_t m_poolIndex; - RefPtr m_renderer; + RefPtr m_renderer; VkQueue m_queue; uint32_t m_queueFamilyIndex; VkSemaphore m_pendingWaitSemaphore = VK_NULL_HANDLE; @@ -1682,7 +1681,7 @@ public: } } - void init(VKRenderer* renderer, VkQueue queue, uint32_t queueFamilyIndex) + void init(VKDevice* renderer, VkQueue queue, uint32_t queueFamilyIndex) { m_renderer = renderer; m_poolIndex = 0; @@ -1803,94 +1802,347 @@ public: } public: - VulkanSwapChain m_swapChain; + struct PlatformDesc + {}; + +#if SLANG_WINDOWS_FAMILY + struct WinPlatformDesc : public PlatformDesc + { + HINSTANCE m_hinstance; + HWND m_hwnd; + }; +#else + struct XPlatformDesc : public PlatformDesc + { + Display* m_display; + Window m_window; + }; +#endif + public: + VkSwapchainKHR m_swapChain; + VkSurfaceKHR m_surface; VkSemaphore m_nextImageSemaphore; // Semaphore to signal after `acquireNextImage`. ISwapchain::Desc m_desc; + VkFormat m_vkformat; RefPtr m_queue; ShortList> m_images; - RefPtr m_renderer; + RefPtr m_renderer; + VulkanApi* m_api; uint32_t m_currentImageIndex = 0; + WindowHandle m_windowHandle; + void destroySwapchainAndImages() + { + m_api->vkQueueWaitIdle(m_queue->m_queue); + if (m_swapChain != VK_NULL_HANDLE) + { + m_api->vkDestroySwapchainKHR(m_api->m_device, m_swapChain, nullptr); + m_swapChain = VK_NULL_HANDLE; + } + + // Mark that it is no longer used + m_images.clear(); + } + + void getWindowSize(int* widthOut, int* heightOut) const + { +#if SLANG_WINDOWS_FAMILY + RECT rc; + ::GetClientRect((HWND)m_windowHandle.handleValues[0], &rc); + *widthOut = rc.right - rc.left; + *heightOut = rc.bottom - rc.top; +#else + auto platformDesc = _getPlatformDesc(); + + XWindowAttributes winAttr = {}; + XGetWindowAttributes( + (Display*)m_windowHandle.handleValues[0], + (Window)m_windowHandle.handleValues[1], + &winAttr); + + *widthOut = winAttr.width; + *heightOut = winAttr.height; +#endif + } + + Result createSwapchainAndImages() + { + int width, height; + getWindowSize(&width, &height); + + VkExtent2D imageExtent = {}; + imageExtent.width = width; + imageExtent.height = height; + + m_desc.width = width; + m_desc.height = height; + + // catch this before throwing error + if (width == 0 || height == 0) + { + return SLANG_FAIL; + } + + // It is necessary to query the caps -> otherwise the LunarG verification layer will + // issue an error + { + VkSurfaceCapabilitiesKHR surfaceCaps; + + SLANG_VK_RETURN_ON_FAIL(m_api->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + m_api->m_physicalDevice, m_surface, &surfaceCaps)); + } + + VkPresentModeKHR presentMode; + List presentModes; + uint32_t numPresentModes = 0; + m_api->vkGetPhysicalDeviceSurfacePresentModesKHR( + m_api->m_physicalDevice, m_surface, &numPresentModes, nullptr); + presentModes.setCount(numPresentModes); + m_api->vkGetPhysicalDeviceSurfacePresentModesKHR( + m_api->m_physicalDevice, m_surface, &numPresentModes, presentModes.getBuffer()); + { + int numCheckPresentOptions = 3; + VkPresentModeKHR presentOptions[] = { + VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_MAILBOX_KHR, + VK_PRESENT_MODE_FIFO_KHR}; + if (m_desc.enableVSync) + { + presentOptions[0] = VK_PRESENT_MODE_FIFO_KHR; + presentOptions[1] = VK_PRESENT_MODE_IMMEDIATE_KHR; + presentOptions[2] = VK_PRESENT_MODE_MAILBOX_KHR; + } + + presentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; // Invalid + + // Find the first option that's available on the device + for (int j = 0; j < numCheckPresentOptions; j++) + { + if (presentModes.indexOf(presentOptions[j]) != Index(-1)) + { + presentMode = presentOptions[j]; + break; + } + } + + if (presentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) + { + return SLANG_FAIL; + } + } + + VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE; + + VkSwapchainCreateInfoKHR swapchainDesc = {}; + swapchainDesc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainDesc.surface = m_surface; + swapchainDesc.minImageCount = m_desc.imageCount; + swapchainDesc.imageFormat = m_vkformat; + swapchainDesc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + swapchainDesc.imageExtent = imageExtent; + swapchainDesc.imageArrayLayers = 1; + swapchainDesc.imageUsage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + swapchainDesc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchainDesc.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + swapchainDesc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainDesc.presentMode = presentMode; + swapchainDesc.clipped = VK_TRUE; + swapchainDesc.oldSwapchain = oldSwapchain; + + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateSwapchainKHR( + m_api->m_device, &swapchainDesc, nullptr, &m_swapChain)); + + uint32_t numSwapChainImages = 0; + m_api->vkGetSwapchainImagesKHR( + m_api->m_device, m_swapChain, &numSwapChainImages, nullptr); + List vkImages; + { + vkImages.setCount(numSwapChainImages); + m_api->vkGetSwapchainImagesKHR( + m_api->m_device, m_swapChain, &numSwapChainImages, vkImages.getBuffer()); + } + + for (uint32_t i = 0; i < m_desc.imageCount; i++) + { + ITextureResource::Desc imageDesc = {}; + + imageDesc.init2D( + IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 1); + RefPtr image = new TextureResourceImpl( + imageDesc, gfx::IResource::Usage::RenderTarget, m_api); + image->m_image = vkImages[i]; + image->m_imageMemory = 0; + image->m_vkformat = m_vkformat; + image->m_isWeakImageReference = true; + m_images.add(image); + } + return SLANG_OK; + } public: ~SwapchainImpl() { - m_swapChain.destroy(); + destroySwapchainAndImages(); + if (m_surface) + { + m_api->vkDestroySurfaceKHR(m_api->m_instance, m_surface, nullptr); + m_surface = VK_NULL_HANDLE; + } m_renderer->m_api.vkDestroySemaphore( m_renderer->m_api.m_device, m_nextImageSemaphore, nullptr); } - Result init(VKRenderer* renderer, const ISwapchain::Desc& desc, WindowHandle window) + + static Index _indexOfFormat(List& formatsIn, VkFormat format) + { + const Index numFormats = formatsIn.getCount(); + const VkSurfaceFormatKHR* formats = formatsIn.getBuffer(); + + for (Index i = 0; i < numFormats; ++i) + { + if (formats[i].format == format) + { + return i; + } + } + return -1; + } + + Result init(VKDevice* renderer, const ISwapchain::Desc& desc, WindowHandle window) { m_desc = desc; m_renderer = renderer; + m_api = &renderer->m_api; m_queue = static_cast(desc.queue); + m_windowHandle = window; VkSemaphoreCreateInfo semaphoreCreateInfo = {}; semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; SLANG_VK_RETURN_ON_FAIL(renderer->m_api.vkCreateSemaphore( renderer->m_api.m_device, &semaphoreCreateInfo, nullptr, &m_nextImageSemaphore)); - VulkanSwapChain::Desc swapchainDesc; - VulkanSwapChain::PlatformDesc* platformDesc = nullptr; - swapchainDesc.m_imageCount = desc.imageCount; - swapchainDesc.init(); - swapchainDesc.m_format = desc.format; - swapchainDesc.m_vsync = desc.enableVSync; + m_queue = static_cast(desc.queue); + + // Make sure it's not set initially + m_vkformat = VK_FORMAT_UNDEFINED; + #if SLANG_WINDOWS_FAMILY - VulkanSwapChain::WinPlatformDesc winPlatformDesc; - winPlatformDesc.m_hinstance = ::GetModuleHandle(nullptr); - winPlatformDesc.m_hwnd = (HWND)window.handleValues[0]; - platformDesc = &winPlatformDesc; + VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.hinstance = ::GetModuleHandle(nullptr); + surfaceCreateInfo.hwnd = (HWND)window.handleValues[0]; + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateWin32SurfaceKHR( + m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); +#else + VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.dpy = (Display*)window.handleValues[0]; + surfaceCreateInfo.window = (Window)window.handleValues[1]; + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateXlibSurfaceKHR( + m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); #endif - m_queue = static_cast(desc.queue); - SLANG_RETURN_ON_FAIL(m_swapChain.init( - &renderer->m_api, - m_queue->m_queue, - m_queue->m_queueFamilyIndex, - swapchainDesc, - platformDesc)); - m_desc.format = m_swapChain.getDesc().m_format; - m_desc.width = m_swapChain.getWidth(); - m_desc.height = m_swapChain.getHeight(); - m_desc.imageCount = m_swapChain.getDesc().m_imageCount; - auto& images = m_swapChain.getImages(); - for (uint32_t i = 0; i < desc.imageCount; i++) + VkBool32 supported = false; + m_api->vkGetPhysicalDeviceSurfaceSupportKHR( + m_api->m_physicalDevice, renderer->m_queueFamilyIndex, m_surface, &supported); + + uint32_t numSurfaceFormats = 0; + List surfaceFormats; + m_api->vkGetPhysicalDeviceSurfaceFormatsKHR( + m_api->m_physicalDevice, m_surface, &numSurfaceFormats, nullptr); + surfaceFormats.setCount(int(numSurfaceFormats)); + m_api->vkGetPhysicalDeviceSurfaceFormatsKHR( + m_api->m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.getBuffer()); + + // Look for a suitable format + List formats; + formats.add(VulkanUtil::getVkFormat(desc.format)); + // HACK! To check for a different format if couldn't be found + if (desc.format == Format::RGBA_Unorm_UInt8) { - ITextureResource::Desc imageDesc = {}; + formats.add(VK_FORMAT_B8G8R8A8_UNORM); + } - imageDesc.init2D( - IResource::Type::Texture2D, - m_swapChain.getDesc().m_format, - m_swapChain.getWidth(), - m_swapChain.getHeight(), - 1); - RefPtr image = new TextureResourceImpl( - imageDesc, gfx::IResource::Usage::RenderTarget, &renderer->m_api); - image->m_image = images[i]; - image->m_imageMemory = 0; - image->m_vkformat = m_swapChain.getVkFormat(); - image->m_isWeakImageReference = true; - m_images.add(image); + for (Index i = 0; i < formats.getCount(); ++i) + { + VkFormat format = formats[i]; + if (_indexOfFormat(surfaceFormats, format) >= 0) + { + m_vkformat = format; + } + } + + if (m_vkformat == VK_FORMAT_UNDEFINED) + { + return SLANG_FAIL; } + + // Save the desc + m_desc = desc; + if (m_desc.format == Format::RGBA_Unorm_UInt8 && + m_vkformat == VK_FORMAT_B8G8R8A8_UNORM) + { + m_desc.format = Format::BGRA_Unorm_UInt8; + } + + SLANG_RETURN_ON_FAIL(createSwapchainAndImages()); return SLANG_OK; } virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() { return m_desc; } - virtual SLANG_NO_THROW Result getImage(uint32_t index, ITextureResource** outResource) + virtual SLANG_NO_THROW Result + SLANG_MCALL getImage(uint32_t index, ITextureResource** outResource) { + if (m_images.getCount() <= (Index)index) + return SLANG_FAIL; *outResource = m_images[index]; m_images[index]->addRef(); return SLANG_OK; } - virtual SLANG_NO_THROW Result present() + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) + { + SLANG_UNUSED(width); + SLANG_UNUSED(height); + destroySwapchainAndImages(); + return createSwapchainAndImages(); + } + virtual SLANG_NO_THROW Result SLANG_MCALL present() { - m_swapChain.present(m_queue->m_pendingWaitSemaphore); + uint32_t swapChainIndices[] = {uint32_t(m_currentImageIndex)}; + + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &m_swapChain; + presentInfo.pImageIndices = swapChainIndices; + if (m_queue->m_pendingWaitSemaphore != VK_NULL_HANDLE) + { + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &m_queue->m_pendingWaitSemaphore; + } + m_api->vkQueuePresentKHR(m_queue->m_queue, &presentInfo); m_queue->m_pendingWaitSemaphore = VK_NULL_HANDLE; return SLANG_OK; } - virtual SLANG_NO_THROW uint32_t acquireNextImage() + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() { - m_currentImageIndex = (uint32_t)m_swapChain.nextFrontImageIndex(m_nextImageSemaphore); + if (!m_images.getCount()) + return -1; + + m_currentImageIndex = -1; + VkResult result = m_api->vkAcquireNextImageKHR( + m_api->m_device, + m_swapChain, + UINT64_MAX, + m_nextImageSemaphore, + VK_NULL_HANDLE, + (uint32_t*)&m_currentImageIndex); + + if (result != VK_SUCCESS) + { + m_currentImageIndex = -1; + destroySwapchainAndImages(); + return m_currentImageIndex; + } // Make the queue's next submit wait on `m_nextImageSemaphore`. m_queue->m_pendingWaitSemaphore = m_nextImageSemaphore; return m_currentImageIndex; @@ -1913,6 +2165,12 @@ public: void _transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout); +public: + // VKDevice members. + + DeviceInfo m_info; + String m_adapterName; + VkDebugReportCallbackEXT m_debugReportCallback; VkDevice m_device = VK_NULL_HANDLE; @@ -1930,9 +2188,9 @@ public: uint32_t m_queueAllocCount; }; -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VkRenderer::Buffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VKDevice::Buffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -Result VKRenderer::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferUsageFlags usage, VkMemoryPropertyFlags reqMemoryProperties) +Result VKDevice::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferUsageFlags usage, VkMemoryPropertyFlags reqMemoryProperties) { assert(!isInitialized()); @@ -1964,17 +2222,17 @@ Result VKRenderer::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBuffe return SLANG_OK; } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VkRenderer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VKDevice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -Result SLANG_MCALL createVKRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer) { - RefPtr result = new VKRenderer(); + RefPtr result = new VKDevice(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); *outRenderer = result.detach(); return SLANG_OK; } -VKRenderer::~VKRenderer() +VKDevice::~VKDevice() { // Check the device queue is valid else, we can't wait on it.. if (m_deviceQueue.isValid()) @@ -1999,7 +2257,7 @@ VKRenderer::~VKRenderer() } -VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, +VkBool32 VKDevice::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg) { char const* severity = "message"; @@ -2031,13 +2289,13 @@ VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugRepo return VK_FALSE; } -/* static */VKAPI_ATTR VkBool32 VKAPI_CALL VKRenderer::debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, +/* static */VKAPI_ATTR VkBool32 VKAPI_CALL VKDevice::debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData) { - return ((VKRenderer*)pUserData)->handleDebugMessage(flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg); + return ((VKDevice*)pUserData)->handleDebugMessage(flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg); } -VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( +VkPipelineShaderStageCreateInfo VKDevice::compileEntryPoint( IShaderProgram::KernelDesc const& kernelDesc, VkShaderStageFlagBits stage, List& outBuffer, @@ -2073,7 +2331,7 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!! -Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) +Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer) { m_queueAllocCount = 0; @@ -2212,6 +2470,14 @@ Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) SLANG_RETURN_ON_FAIL(m_api.initPhysicalDevice(physicalDevices[selectedDeviceIndex])); + // Obtain the name of the selected adapter. + { + VkPhysicalDeviceProperties basicProps = {}; + m_api.vkGetPhysicalDeviceProperties(physicalDevices[selectedDeviceIndex], &basicProps); + m_adapterName = basicProps.deviceName; + m_info.adapterName = m_adapterName.begin(); + } + List deviceExtensions; deviceExtensions.add(VK_KHR_SWAPCHAIN_EXTENSION_NAME); @@ -2354,8 +2620,18 @@ Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) return SLANG_OK; } -SlangResult VKRenderer::initialize(const Desc& desc) +SlangResult VKDevice::initialize(const Desc& desc) { + // Initialize device info. + { + m_info.apiName = "Vulkan"; + m_info.bindingStyle = BindingStyle::Vulkan; + m_info.projectionStyle = ProjectionStyle::Vulkan; + m_info.deviceType = DeviceType::Vulkan; + static const float kIdentity[] = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + } + m_desc = desc; SLANG_RETURN_ON_FAIL(GraphicsAPIRenderer::initialize(desc)); @@ -2374,12 +2650,12 @@ SlangResult VKRenderer::initialize(const Desc& desc) return SLANG_OK; } -void VKRenderer::waitForGpu() +void VKDevice::waitForGpu() { m_deviceQueue.flushAndWait(); } -Result VKRenderer::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) +Result VKDevice::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) { // Only support one queue for now. if (m_queueAllocCount != 0) @@ -2394,7 +2670,7 @@ Result VKRenderer::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQ return SLANG_OK; } -Result VKRenderer::createSwapchain( +Result VKDevice::createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr sc = new SwapchainImpl(); @@ -2403,7 +2679,7 @@ Result VKRenderer::createSwapchain( return SLANG_OK; } -Result VKRenderer::createFramebufferLayout(const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) +Result VKDevice::createFramebufferLayout(const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) { RefPtr layout = new FramebufferLayoutImpl(); SLANG_RETURN_ON_FAIL(layout->init(this, desc)); @@ -2411,7 +2687,7 @@ Result VKRenderer::createFramebufferLayout(const IFramebufferLayout::Desc& desc, return SLANG_OK; } -Result VKRenderer::createRenderPassLayout( +Result VKDevice::createRenderPassLayout( const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) { @@ -2421,7 +2697,7 @@ Result VKRenderer::createRenderPassLayout( return SLANG_OK; } -Result VKRenderer::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) +Result VKDevice::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) { RefPtr fb = new FramebufferImpl(); SLANG_RETURN_ON_FAIL(fb->init(this, desc)); @@ -2429,7 +2705,7 @@ Result VKRenderer::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffe return SLANG_OK; } -SlangResult VKRenderer::readTextureResource( +SlangResult VKDevice::readTextureResource( ITextureResource* texture, ResourceState state, ISlangBlob** outBlob, @@ -2443,7 +2719,7 @@ SlangResult VKRenderer::readTextureResource( return SLANG_FAIL; } -SlangResult VKRenderer::readBufferResource( +SlangResult VKDevice::readBufferResource( IBufferResource* inBuffer, size_t offset, size_t size, @@ -2616,7 +2892,7 @@ bool isStencilFormat(VkFormat format) return false; } -void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) +void VKDevice::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) { VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -2724,7 +3000,7 @@ size_t calcNumRows(Format format, int height) return (size_t)height; } -Result VKRenderer::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) +Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) { TextureResource::Desc desc(descIn); desc.setDefaults(initialUsage); @@ -2958,7 +3234,7 @@ Result VKRenderer::createTextureResource(IResource::Usage initialUsage, const IT return SLANG_OK; } -Result VKRenderer::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result VKDevice::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { BufferResource::Desc desc(descIn); desc.setDefaults(initialUsage); @@ -3126,7 +3402,7 @@ static VkStencilOpState translateStencilState(DepthStencilOpDesc desc) return rs; } -Result VKRenderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) +Result VKDevice::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) { VkSamplerCreateInfo samplerInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; @@ -3157,7 +3433,7 @@ Result VKRenderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerS return SLANG_OK; } -Result VKRenderer::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) +Result VKDevice::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = static_cast(texture); RefPtr view = new TextureResourceViewImpl(&m_api); @@ -3234,7 +3510,7 @@ Result VKRenderer::createTextureView(ITextureResource* texture, IResourceView::D return SLANG_OK; } -Result VKRenderer::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) +Result VKDevice::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (BufferResourceImpl*) buffer; @@ -3308,7 +3584,7 @@ Result VKRenderer::createBufferView(IBufferResource* buffer, IResourceView::Desc } } -Result VKRenderer::createInputLayout(const InputElementDesc* elements, UInt numElements, IInputLayout** outLayout) +Result VKDevice::createInputLayout(const InputElementDesc* elements, UInt numElements, IInputLayout** outLayout) { RefPtr layout(new InputLayoutImpl); @@ -3395,7 +3671,7 @@ static VkDescriptorType translateDescriptorType(DescriptorSlotType type) } } -Result VKRenderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) +Result VKDevice::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) { RefPtr descriptorSetLayoutImpl = new DescriptorSetLayoutImpl(m_api); @@ -3507,7 +3783,7 @@ Result VKRenderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& d return SLANG_OK; } -Result VKRenderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) +Result VKDevice::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) { UInt descriptorSetCount = desc.descriptorSetCount; @@ -3569,7 +3845,7 @@ Result VKRenderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipe return SLANG_OK; } -Result VKRenderer::createDescriptorSet( +Result VKDevice::createDescriptorSet( IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) @@ -3588,7 +3864,7 @@ Result VKRenderer::createDescriptorSet( return SLANG_OK; } -void VKRenderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) +void VKDevice::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) { auto bufferImpl = (BufferResourceImpl*)buffer; @@ -3614,7 +3890,7 @@ void VKRenderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IB m_boundObjects[boundObjectIndex] = dynamic_cast(buffer); } -void VKRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) +void VKDevice::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) { SLANG_ASSERT(range < UInt(m_layout->m_ranges.getCount())); auto& rangeInfo = m_layout->m_ranges[range]; @@ -3685,7 +3961,7 @@ void VKRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourc m_boundObjects[boundObjectIndex] = dynamic_cast(view); } -void VKRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) +void VKDevice::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) { SLANG_ASSERT(range < UInt(m_layout->m_ranges.getCount())); auto& rangeInfo = m_layout->m_ranges[range]; @@ -3708,7 +3984,7 @@ void VKRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerS m_boundObjects[boundObjectIndex] = dynamic_cast(sampler); } -void VKRenderer::DescriptorSetImpl::setCombinedTextureSampler( +void VKDevice::DescriptorSetImpl::setCombinedTextureSampler( UInt range, UInt index, IResourceView* textureView, @@ -3731,7 +4007,7 @@ void VKRenderer::DescriptorSetImpl::setCombinedTextureSampler( m_boundObjects[boundObjectIndex + 1] = dynamic_cast(sampler); } -void VKRenderer::DescriptorSetImpl::setRootConstants( +void VKDevice::DescriptorSetImpl::setRootConstants( UInt range, UInt offset, UInt size, @@ -3756,7 +4032,7 @@ void VKRenderer::DescriptorSetImpl::setRootConstants( memcpy(m_rootConstantData.getBuffer() + rootConstantRangeInfo.offset + offset, data, size); } -Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) +Result VKDevice::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) { @@ -3791,7 +4067,7 @@ Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgra return SLANG_OK; } -Result VKRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) +Result VKDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -3965,7 +4241,7 @@ Result VKRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& return SLANG_OK; } -Result VKRenderer::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) +Result VKDevice::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) { ComputePipelineStateDesc desc = inDesc; preparePipelineDesc(desc); diff --git a/tools/gfx/vulkan/render-vk.h b/tools/gfx/vulkan/render-vk.h index b2bceb31c..b980653c7 100644 --- a/tools/gfx/vulkan/render-vk.h +++ b/tools/gfx/vulkan/render-vk.h @@ -6,6 +6,6 @@ namespace gfx { -SlangResult SLANG_MCALL createVKRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outDevice); } // gfx diff --git a/tools/gfx/vulkan/vk-swap-chain.cpp b/tools/gfx/vulkan/vk-swap-chain.cpp deleted file mode 100644 index 3a62ccfe2..000000000 --- a/tools/gfx/vulkan/vk-swap-chain.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// vk-swap-chain.cpp -#include "vk-swap-chain.h" - -#include "vk-util.h" - -#include "core/slang-list.h" - -#include -#include - -namespace gfx { -using namespace Slang; - -static Index _indexOfFormat(List& formatsIn, VkFormat format) -{ - const Index numFormats = formatsIn.getCount(); - const VkSurfaceFormatKHR* formats = formatsIn.getBuffer(); - - for (Index i = 0; i < numFormats; ++i) - { - if (formats[i].format == format) - { - return i; - } - } - return -1; -} - -SlangResult VulkanSwapChain::init( - VulkanApi* vkapi, - VkQueue queue, - uint32_t queueFamilyIndex, - const Desc& descIn, - const PlatformDesc* platformDescIn) -{ - assert(platformDescIn); - - m_queue = queue; - m_api = vkapi; - - // Make sure it's not set initially - m_format = VK_FORMAT_UNDEFINED; - - Desc desc(descIn); - -#if SLANG_WINDOWS_FAMILY - const WinPlatformDesc* platformDesc = static_cast(platformDescIn); - _setPlatformDesc(*platformDesc); - - VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = {}; - surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.hinstance = platformDesc->m_hinstance; - surfaceCreateInfo.hwnd = platformDesc->m_hwnd; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateWin32SurfaceKHR(m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); -#else - const XPlatformDesc* platformDesc = static_cast(platformDescIn); - _setPlatformDesc(*platformDesc); - - VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; - surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.dpy = platformDesc->m_display; - surfaceCreateInfo.window = platformDesc->m_window; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateXlibSurfaceKHR(m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); -#endif - - VkBool32 supported = false; - m_api->vkGetPhysicalDeviceSurfaceSupportKHR(m_api->m_physicalDevice, queueFamilyIndex, m_surface, &supported); - - uint32_t numSurfaceFormats = 0; - List surfaceFormats; - m_api->vkGetPhysicalDeviceSurfaceFormatsKHR(m_api->m_physicalDevice, m_surface, &numSurfaceFormats, nullptr); - surfaceFormats.setCount(int(numSurfaceFormats)); - m_api->vkGetPhysicalDeviceSurfaceFormatsKHR(m_api->m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.getBuffer()); - - // Look for a suitable format - List formats; - formats.add(VulkanUtil::getVkFormat(desc.m_format)); - // HACK! To check for a different format if couldn't be found - if (descIn.m_format == Format::RGBA_Unorm_UInt8) - { - formats.add(VK_FORMAT_B8G8R8A8_UNORM); - } - - for(Index i = 0; i < formats.getCount(); ++i) - { - VkFormat format = formats[i]; - if (_indexOfFormat(surfaceFormats, format) >= 0) - { - m_format = format; - } - } - - if (m_format == VK_FORMAT_UNDEFINED) - { - return SLANG_FAIL; - } - - // Save the desc - m_desc = desc; - - if (descIn.m_format == Format::RGBA_Unorm_UInt8 && m_format == VK_FORMAT_B8G8R8A8_UNORM) - { - m_desc.m_format = Format::BGRA_Unorm_UInt8; - } - - SLANG_RETURN_ON_FAIL(_createSwapChain()); - return SLANG_OK; -} - -void VulkanSwapChain::getWindowSize(int* widthOut, int* heightOut) const -{ -#if SLANG_WINDOWS_FAMILY - auto platformDesc = _getPlatformDesc(); - - RECT rc; - ::GetClientRect(platformDesc->m_hwnd, &rc); - *widthOut = rc.right - rc.left; - *heightOut = rc.bottom - rc.top; -#else - auto platformDesc = _getPlatformDesc(); - - XWindowAttributes winAttr = {}; - XGetWindowAttributes(platformDesc->m_display, platformDesc->m_window, &winAttr); - - *widthOut = winAttr.width; - *heightOut = winAttr.height; -#endif -} - -SlangResult VulkanSwapChain::_createSwapChain() -{ - int width, height; - getWindowSize(&width, &height); - - VkExtent2D imageExtent = {}; - imageExtent.width = width; - imageExtent.height = height; - - m_width = width; - m_height = height; - - // catch this before throwing error - if (m_width == 0 || m_height == 0) - { - return SLANG_FAIL; - } - - // It is necessary to query the caps -> otherwise the LunarG verification layer will issue an error - { - VkSurfaceCapabilitiesKHR surfaceCaps; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_api->m_physicalDevice, m_surface, &surfaceCaps)); - } - - List presentModes; - uint32_t numPresentModes = 0; - m_api->vkGetPhysicalDeviceSurfacePresentModesKHR(m_api->m_physicalDevice, m_surface, &numPresentModes, nullptr); - presentModes.setCount(numPresentModes); - m_api->vkGetPhysicalDeviceSurfacePresentModesKHR(m_api->m_physicalDevice, m_surface, &numPresentModes, presentModes.getBuffer()); - - { - int numCheckPresentOptions = 3; - VkPresentModeKHR presentOptions[] = { VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR }; - if (m_desc.m_vsync) - { - presentOptions[0] = VK_PRESENT_MODE_FIFO_KHR; - presentOptions[1] = VK_PRESENT_MODE_IMMEDIATE_KHR; - presentOptions[2] = VK_PRESENT_MODE_MAILBOX_KHR; - } - - m_presentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; // Invalid - - // Find the first option that's available on the device - for (int j = 0; j < numCheckPresentOptions; j++) - { - if (presentModes.indexOf(presentOptions[j]) != Index(-1)) - { - m_presentMode = presentOptions[j]; - break; - } - } - - if (m_presentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) - { - return SLANG_FAIL; - } - } - - VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE; - - VkSwapchainCreateInfoKHR swapchainDesc = {}; - swapchainDesc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapchainDesc.surface = m_surface; - swapchainDesc.minImageCount = m_desc.m_imageCount; - swapchainDesc.imageFormat = m_format; - swapchainDesc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; - swapchainDesc.imageExtent = imageExtent; - swapchainDesc.imageArrayLayers = 1; - swapchainDesc.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - swapchainDesc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapchainDesc.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - swapchainDesc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapchainDesc.presentMode = m_presentMode; - swapchainDesc.clipped = VK_TRUE; - swapchainDesc.oldSwapchain = oldSwapchain; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateSwapchainKHR(m_api->m_device, &swapchainDesc, nullptr, &m_swapChain)); - - uint32_t numSwapChainImages = 0; - m_api->vkGetSwapchainImagesKHR(m_api->m_device, m_swapChain, &numSwapChainImages, nullptr); - m_desc.m_imageCount = numSwapChainImages; - { - m_images.setCount(numSwapChainImages); - m_api->vkGetSwapchainImagesKHR( - m_api->m_device, m_swapChain, &numSwapChainImages, m_images.getBuffer()); - } - return SLANG_OK; -} - -void VulkanSwapChain::_destroySwapChain() -{ - if (m_swapChain != VK_NULL_HANDLE) - { - m_api->vkDestroySwapchainKHR(m_api->m_device, m_swapChain, nullptr); - m_swapChain = VK_NULL_HANDLE; - } - - // Mark that it is no longer used - m_images.clear(); -} - -void VulkanSwapChain::destroy() -{ - _destroySwapChain(); - - if (m_surface) - { - m_api->vkDestroySurfaceKHR(m_api->m_instance, m_surface, nullptr); - m_surface = VK_NULL_HANDLE; - } -} - - -VulkanSwapChain::~VulkanSwapChain() -{ - destroy(); -} - -int VulkanSwapChain::nextFrontImageIndex(VkSemaphore signalSemaphore) -{ - uint32_t swapChainIndex = 0; - VkResult result = m_api->vkAcquireNextImageKHR( - m_api->m_device, m_swapChain, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &swapChainIndex); - - if (result != VK_SUCCESS) - { - _destroySwapChain(); - return -1; - } - m_currentSwapChainIndex = int(swapChainIndex); - return swapChainIndex; -} - -void VulkanSwapChain::present(VkSemaphore waitSemaphore) -{ - uint32_t swapChainIndices[] = { uint32_t(m_currentSwapChainIndex) }; - - VkPresentInfoKHR presentInfo = {}; - presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &m_swapChain; - presentInfo.pImageIndices = swapChainIndices; - if (waitSemaphore != VK_NULL_HANDLE) - { - presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &waitSemaphore; - } - m_api->vkQueuePresentKHR(m_queue, &presentInfo); -} - -} // renderer_test diff --git a/tools/gfx/vulkan/vk-swap-chain.h b/tools/gfx/vulkan/vk-swap-chain.h deleted file mode 100644 index 0ddc6f7f5..000000000 --- a/tools/gfx/vulkan/vk-swap-chain.h +++ /dev/null @@ -1,135 +0,0 @@ -// vk-swap-chain.h -#pragma once - -#include "vk-api.h" -#include "vk-device-queue.h" - -#include "slang-gfx.h" - -#include "core/slang-list.h" - -namespace gfx { - -struct VulkanSwapChain -{ - /* enum - { - kMaxImages = 8, - }; */ - - /// Base class for platform specific information - struct PlatformDesc - { - }; - -#if SLANG_WINDOWS_FAMILY - struct WinPlatformDesc: public PlatformDesc - { - HINSTANCE m_hinstance; - HWND m_hwnd; - }; -#else - struct XPlatformDesc : public PlatformDesc - { - Display* m_display; - Window m_window; - }; -#endif - - struct Desc - { - void init() - { - m_format = Format::Unknown; - m_depthFormatTypeless = Format::Unknown; - m_depthFormat = Format::Unknown; - m_textureDepthFormat = Format::Unknown; - m_imageCount = 2; - m_vsync = false; - } - - Format m_format; - Format m_depthFormatTypeless; - Format m_depthFormat; - Format m_textureDepthFormat; - uint32_t m_imageCount; - bool m_vsync; - }; - - /// Must be called before the swap chain can be used - SlangResult init( - VulkanApi* vkapi, - VkQueue queue, - uint32_t queueFamilyIndex, - const Desc& desc, - const PlatformDesc* platformDesc); - - /// Returned the desc used to construct the swap chain. - /// Is invalid if init hasn't returned with successful result. - const Desc& getDesc() const { return m_desc; } - - /// True if the swap chain is available - bool hasValidSwapChain() const { return m_images.getCount() > 0; } - - /// Present to the display - void present(VkSemaphore waitSemaphore); - - /// Get the current size of the window (in pixels written to widthOut, heightOut) - void getWindowSize(int* widthOut, int* heightOut) const; - - /// Get the VkFormat for the back buffer - VkFormat getVkFormat() const { return m_format; } - - /// Get width of the back buffers - int getWidth() const { return m_width; } - /// Get the height of the back buffer - int getHeight() const { return m_height; } - - /// Get the detail about the images - const Slang::List& getImages() const { return m_images; } - - /// Get the next front render image index. Returns -1, if image couldn't be found - int nextFrontImageIndex(VkSemaphore signalSemaphore); - - void destroy(); - - /// Dtor - ~VulkanSwapChain(); - - protected: - - - template - void _setPlatformDesc(const T& desc) - { - const PlatformDesc* check = &desc; - int size = (sizeof(T) + sizeof(void*) - 1) / sizeof(void*); - m_platformDescBuffer.setCount(size); - *(T*)m_platformDescBuffer.getBuffer() = desc; - } - template - const T* _getPlatformDesc() const { return static_cast((const PlatformDesc*)m_platformDescBuffer.getBuffer()); } - SlangResult _createSwapChain(); - void _destroySwapChain(); - - int m_width = 0; - int m_height = 0; - - VkPresentModeKHR m_presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; - VkFormat m_format = VK_FORMAT_UNDEFINED; ///< The format used for backbuffer. Valid after successful init. - - VkSurfaceKHR m_surface = VK_NULL_HANDLE; - VkSwapchainKHR m_swapChain = VK_NULL_HANDLE; - - int m_currentSwapChainIndex = 0; - - Slang::List m_images; - - VkQueue m_queue; - const VulkanApi* m_api = nullptr; - - Desc m_desc; ///< The desc used to init this swap chain - Slang::List m_platformDescBuffer; ///< Buffer to hold the platform specific description parameters (as passed in platformDesc) -}; - -} // renderer_test -- cgit v1.2.3