diff options
| author | Yong He <yonghe@outlook.com> | 2021-03-10 10:58:15 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-10 10:58:15 -0800 |
| commit | 6ef4054f8a8aea4ec61481057fa7e16aaecde6d7 (patch) | |
| tree | 66edcae112faff7276c2595865463698bde277fd /tools/gfx/vulkan/render-vk.cpp | |
| parent | 2765861cdc104e6104a31cf9e20800b8d1dfae26 (diff) | |
Swapchain resize and rename to `IDevice` (#1741)
* Swapchain resize
* Fix.
Diffstat (limited to 'tools/gfx/vulkan/render-vk.cpp')
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 484 |
1 files changed, 380 insertions, 104 deletions
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<VkAttachmentDescription, kMaxAttachments> m_attachmentDescs; Array<VkAttachmentReference, kMaxRenderTargets> 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<IResourceView> depthStencilView; uint32_t m_width; uint32_t m_height; - VKRenderer* m_renderer; + VKDevice* m_renderer; VkClearValue m_clearValues[kMaxAttachments]; RefPtr<FramebufferLayoutImpl> 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<DescriptorSetLayoutImpl> 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<PipelineLayoutImpl*>(pipeline->m_pipelineLayout.get()); auto vkPipelineLayout = pipelineLayoutImpl->m_pipelineLayout; @@ -1656,7 +1655,7 @@ public: public: Desc m_desc; uint32_t m_poolIndex; - RefPtr<VKRenderer> m_renderer; + RefPtr<VKDevice> 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<CommandQueueImpl> m_queue; ShortList<RefPtr<TextureResourceImpl>> m_images; - RefPtr<VKRenderer> m_renderer; + RefPtr<VKDevice> 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<XPlatformDesc>(); + + 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<VkPresentModeKHR> 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<VkImage> 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<TextureResourceImpl> 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<VkSurfaceFormatKHR>& 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<CommandQueueImpl*>(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<CommandQueueImpl*>(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<CommandQueueImpl*>(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<VkSurfaceFormatKHR> 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<VkFormat> 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<TextureResourceImpl> 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<VKRenderer> result = new VKRenderer(); + RefPtr<VKDevice> 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<char>& 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<const char*> 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<SwapchainImpl> 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<FramebufferLayoutImpl> 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<FramebufferImpl> 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<TextureResourceImpl*>(texture); RefPtr<TextureResourceViewImpl> 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<InputLayoutImpl> 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> 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<RefObject*>(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<RefObject*>(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<RefObject*>(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<RefObject*>(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); |
