| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsVulkanRenderAPI.h"
- #include "CoreThread/BsCoreThread.h"
- #include "Profiling/BsRenderStats.h"
- #include "RenderAPI/BsGpuParamDesc.h"
- #include "BsVulkanDevice.h"
- #include "Managers/BsVulkanTextureManager.h"
- #include "Managers/BsVulkanRenderWindowManager.h"
- #include "Managers/BsVulkanHardwareBufferManager.h"
- #include "Managers/BsVulkanRenderStateManager.h"
- #include "Managers/BsGpuProgramManager.h"
- #include "Managers/BsVulkanQueryManager.h"
- #include "Managers/BsVulkanGLSLProgramFactory.h"
- #include "Managers/BsVulkanCommandBufferManager.h"
- #include "BsVulkanCommandBuffer.h"
- #include "BsVulkanGpuParams.h"
- #include "Managers/BsVulkanVertexInputManager.h"
- #include "BsVulkanGpuParamBlockBuffer.h"
- #include <vulkan/vulkan.h>
- #include "BsVulkanUtility.h"
- #if BS_PLATFORM == BS_PLATFORM_WIN32
- #include "Win32/BsWin32VideoModeInfo.h"
- #elif BS_PLATFORM == BS_PLATFORM_LINUX
- #include "Linux/BsLinuxVideoModeInfo.h"
- #else
- static_assert(false, "Other platform includes go here.");
- #endif
- #define USE_VALIDATION_LAYERS 1
- namespace bs { namespace ct
- {
- VkAllocationCallbacks* gVulkanAllocator = nullptr;
- PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;
- PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;
- PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
- PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
- PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
- PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
- PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
- PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr;
- PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr;
- PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = nullptr;
- PFN_vkQueuePresentKHR vkQueuePresentKHR = nullptr;
- VkBool32 debugMsgCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
- size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData)
- {
- StringStream message;
- // Determine prefix
- if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
- message << "ERROR";
- if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
- message << "WARNING";
- if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
- message << "PERFORMANCE";
- if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
- message << "INFO";
- if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
- message << "DEBUG";
- message << ": [" << pLayerPrefix << "] Code " << msgCode << ": " << pMsg << std::endl;
- if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
- BS_EXCEPT(RenderingAPIException, message.str())
- else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT || flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
- LOGWRN(message.str())
- else
- LOGDBG(message.str())
- // Don't abort calls that caused a validation message
- return VK_FALSE;
- }
- VulkanRenderAPI::VulkanRenderAPI()
- :mInstance(nullptr)
- {
- #if BS_DEBUG_MODE
- mDebugCallback = nullptr;
- #endif
- }
- VulkanRenderAPI::~VulkanRenderAPI()
- {
- }
- const StringID& VulkanRenderAPI::getName() const
- {
- static StringID strName("VulkanRenderAPI");
- return strName;
- }
- const String& VulkanRenderAPI::getShadingLanguageName() const
- {
- static String strName("vksl");
- return strName;
- }
- void VulkanRenderAPI::initialize()
- {
- THROW_IF_NOT_CORE_THREAD;
- // Create instance
- VkApplicationInfo appInfo;
- appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
- appInfo.pNext = nullptr;
- appInfo.pApplicationName = "Banshee3D App";
- appInfo.applicationVersion = 1;
- appInfo.pEngineName = "Banshee3D";
- appInfo.engineVersion = (0 << 24) | (4 << 16) | 0;
- appInfo.apiVersion = VK_API_VERSION_1_0;
- #if BS_DEBUG_MODE && USE_VALIDATION_LAYERS
- const char* layers[] =
- {
- "VK_LAYER_LUNARG_standard_validation"
- };
- const char* extensions[] =
- {
- nullptr, /** Surface extension */
- nullptr, /** OS specific surface extension */
- VK_EXT_DEBUG_REPORT_EXTENSION_NAME
- };
- uint32_t numLayers = sizeof(layers) / sizeof(layers[0]);
- #else
- const char** layers = nullptr;
- const char* extensions[] =
- {
- nullptr, /** Surface extension */
- nullptr, /** OS specific surface extension */
- };
- uint32_t numLayers = 0;
- #endif
- extensions[0] = VK_KHR_SURFACE_EXTENSION_NAME;
- #if BS_PLATFORM == BS_PLATFORM_WIN32
- extensions[1] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
- #elif BS_PLATFORM == BS_PLATFORM_ANDROID
- extensions[1] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
- #else
- extensions[1] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
- #endif
- uint32_t numExtensions = sizeof(extensions) / sizeof(extensions[0]);
- VkInstanceCreateInfo instanceInfo;
- instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- instanceInfo.pNext = nullptr;
- instanceInfo.flags = 0;
- instanceInfo.pApplicationInfo = &appInfo;
- instanceInfo.enabledLayerCount = numLayers;
- instanceInfo.ppEnabledLayerNames = layers;
- instanceInfo.enabledExtensionCount = numExtensions;
- instanceInfo.ppEnabledExtensionNames = extensions;
- VkResult result = vkCreateInstance(&instanceInfo, gVulkanAllocator, &mInstance);
- assert(result == VK_SUCCESS);
- // Set up debugging
- #if BS_DEBUG_MODE && USE_VALIDATION_LAYERS
- VkDebugReportFlagsEXT debugFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
- VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
- GET_INSTANCE_PROC_ADDR(mInstance, CreateDebugReportCallbackEXT);
- GET_INSTANCE_PROC_ADDR(mInstance, DestroyDebugReportCallbackEXT);
- VkDebugReportCallbackCreateInfoEXT debugInfo;
- debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
- debugInfo.pNext = nullptr;
- debugInfo.flags = 0;
- debugInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugMsgCallback;
- debugInfo.flags = debugFlags;
- result = vkCreateDebugReportCallbackEXT(mInstance, &debugInfo, nullptr, &mDebugCallback);
- assert(result == VK_SUCCESS);
- #endif
- // Enumerate all devices
- result = vkEnumeratePhysicalDevices(mInstance, &mNumDevices, nullptr);
- assert(result == VK_SUCCESS);
- Vector<VkPhysicalDevice> physicalDevices(mNumDevices);
- result = vkEnumeratePhysicalDevices(mInstance, &mNumDevices, physicalDevices.data());
- assert(result == VK_SUCCESS);
- mDevices.resize(mNumDevices);
- for(uint32_t i = 0; i < mNumDevices; i++)
- mDevices[i] = bs_shared_ptr_new<VulkanDevice>(physicalDevices[i], i);
- // Find primary device
- // Note: MULTIGPU - Detect multiple similar devices here if supporting multi-GPU
- for (uint32_t i = 0; i < mNumDevices; i++)
- {
- bool isPrimary = mDevices[i]->getDeviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
- if (isPrimary)
- {
- mDevices[i]->setIsPrimary();
- mPrimaryDevices.push_back(mDevices[i]);
- break;
- }
- }
- if (mPrimaryDevices.size() == 0)
- mPrimaryDevices.push_back(mDevices[0]);
- #if BS_PLATFORM == BS_PLATFORM_WIN32
- mVideoModeInfo = bs_shared_ptr_new<Win32VideoModeInfo>();
- #elif BS_PLATFORM == BS_PLATFORM_LINUX
- mVideoModeInfo = bs_shared_ptr_new<LinuxVideoModeInfo>();
- #else
- static_assert(false, "mVideoModeInfo needs to be created.");
- #endif
- GPUInfo gpuInfo;
- gpuInfo.numGPUs = std::min(5U, mNumDevices);
- for(UINT32 i = 0; i < gpuInfo.numGPUs; i++)
- gpuInfo.names[i] = mDevices[i]->getDeviceProperties().deviceName;
- PlatformUtility::_setGPUInfo(gpuInfo);
- // Get required extension functions
- GET_INSTANCE_PROC_ADDR(mInstance, GetPhysicalDeviceSurfaceSupportKHR);
- GET_INSTANCE_PROC_ADDR(mInstance, GetPhysicalDeviceSurfaceFormatsKHR);
- GET_INSTANCE_PROC_ADDR(mInstance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
- GET_INSTANCE_PROC_ADDR(mInstance, GetPhysicalDeviceSurfacePresentModesKHR);
- VkDevice presentDevice = _getPresentDevice()->getLogical();
- GET_DEVICE_PROC_ADDR(presentDevice, CreateSwapchainKHR);
- GET_DEVICE_PROC_ADDR(presentDevice, DestroySwapchainKHR);
- GET_DEVICE_PROC_ADDR(presentDevice, GetSwapchainImagesKHR);
- GET_DEVICE_PROC_ADDR(presentDevice, AcquireNextImageKHR);
- GET_DEVICE_PROC_ADDR(presentDevice, QueuePresentKHR);
- // Create command buffer manager
- CommandBufferManager::startUp<VulkanCommandBufferManager>(*this);
- // Create main command buffer
- mMainCommandBuffer = std::static_pointer_cast<VulkanCommandBuffer>(CommandBuffer::create(GQT_GRAPHICS));
- // Create the texture manager for use by others
- bs::TextureManager::startUp<bs::VulkanTextureManager>();
- TextureManager::startUp<VulkanTextureManager>();
- // Create hardware buffer manager
- bs::HardwareBufferManager::startUp();
- HardwareBufferManager::startUp<VulkanHardwareBufferManager>();
- // Create render window manager
- bs::RenderWindowManager::startUp<bs::VulkanRenderWindowManager>();
- RenderWindowManager::startUp<VulkanRenderWindowManager>(*this);
- // Create query manager
- QueryManager::startUp<VulkanQueryManager>(*this);
- // Create vertex input manager
- VulkanVertexInputManager::startUp();
- // Create & register HLSL factory
- mGLSLFactory = bs_new<VulkanGLSLProgramFactory>();
- // Create render state manager
- RenderStateManager::startUp<VulkanRenderStateManager>();
- GpuProgramManager::instance().addFactory(mGLSLFactory);
- initCapabilites();
-
- RenderAPI::initialize();
- }
- void VulkanRenderAPI::destroyCore()
- {
- THROW_IF_NOT_CORE_THREAD;
- if (mGLSLFactory != nullptr)
- {
- bs_delete(mGLSLFactory);
- mGLSLFactory = nullptr;
- }
- VulkanVertexInputManager::shutDown();
- QueryManager::shutDown();
- RenderStateManager::shutDown();
- RenderWindowManager::shutDown();
- bs::RenderWindowManager::shutDown();
- HardwareBufferManager::shutDown();
- bs::HardwareBufferManager::shutDown();
- TextureManager::shutDown();
- bs::TextureManager::shutDown();
- mMainCommandBuffer = nullptr;
- // Make sure everything finishes and all resources get freed
- VulkanCommandBufferManager& cmdBufManager = static_cast<VulkanCommandBufferManager&>(CommandBufferManager::instance());
- for (UINT32 i = 0; i < (UINT32)mDevices.size(); i++)
- {
- mDevices[i]->waitIdle();
- cmdBufManager.refreshStates(i);
- }
- CommandBufferManager::shutDown();
- mPrimaryDevices.clear();
- mDevices.clear();
- #if BS_DEBUG_MODE
- if (mDebugCallback != nullptr)
- vkDestroyDebugReportCallbackEXT(mInstance, mDebugCallback, gVulkanAllocator);
- #endif
- vkDestroyInstance(mInstance, gVulkanAllocator);
- RenderAPI::destroyCore();
- }
- void VulkanRenderAPI::setGraphicsPipeline(const SPtr<GraphicsPipelineState>& pipelineState,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setPipelineState(pipelineState);
- BS_INC_RENDER_STAT(NumPipelineStateChanges);
- }
- void VulkanRenderAPI::setComputePipeline(const SPtr<ComputePipelineState>& pipelineState,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setPipelineState(pipelineState);
- BS_INC_RENDER_STAT(NumPipelineStateChanges);
- }
- void VulkanRenderAPI::setGpuParams(const SPtr<GpuParams>& gpuParams, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- UINT32 globalQueueIdx = CommandSyncMask::getGlobalQueueIdx(cb->getType(), cb->getQueueIdx());
- for (UINT32 i = 0; i < GPT_COUNT; i++)
- {
- SPtr<GpuParamDesc> paramDesc = gpuParams->getParamDesc((GpuProgramType)i);
- if (paramDesc == nullptr)
- continue;
- // Flush all param block buffers
- for (auto iter = paramDesc->paramBlocks.begin(); iter != paramDesc->paramBlocks.end(); ++iter)
- {
- SPtr<GpuParamBlockBuffer> buffer = gpuParams->getParamBlockBuffer(iter->second.set, iter->second.slot);
- if (buffer != nullptr)
- buffer->flushToGPU(globalQueueIdx);
- }
- }
- vkCB->setGpuParams(gpuParams);
- BS_INC_RENDER_STAT(NumGpuParamBinds);
- }
- void VulkanRenderAPI::setViewport(const Rect2& vp, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setViewport(vp);
- }
- void VulkanRenderAPI::setVertexBuffers(UINT32 index, SPtr<VertexBuffer>* buffers, UINT32 numBuffers,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setVertexBuffers(index, buffers, numBuffers);
- BS_INC_RENDER_STAT(NumVertexBufferBinds);
- }
- void VulkanRenderAPI::setIndexBuffer(const SPtr<IndexBuffer>& buffer, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setIndexBuffer(buffer);
- BS_INC_RENDER_STAT(NumIndexBufferBinds);
- }
- void VulkanRenderAPI::setVertexDeclaration(const SPtr<VertexDeclaration>& vertexDeclaration,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setVertexDeclaration(vertexDeclaration);
- }
- void VulkanRenderAPI::setDrawOperation(DrawOperationType op, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setDrawOp(op);
- }
- void VulkanRenderAPI::draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- UINT32 primCount = 0;
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->draw(vertexOffset, vertexCount, instanceCount);
- BS_INC_RENDER_STAT(NumDrawCalls);
- BS_ADD_RENDER_STAT(NumVertices, vertexCount);
- BS_ADD_RENDER_STAT(NumPrimitives, primCount);
- }
- void VulkanRenderAPI::drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount,
- UINT32 instanceCount, const SPtr<CommandBuffer>& commandBuffer)
- {
- UINT32 primCount = 0;
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->drawIndexed(startIndex, indexCount, vertexOffset, instanceCount);
- BS_INC_RENDER_STAT(NumDrawCalls);
- BS_ADD_RENDER_STAT(NumVertices, vertexCount);
- BS_ADD_RENDER_STAT(NumPrimitives, primCount);
- }
- void VulkanRenderAPI::dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY, UINT32 numGroupsZ,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->dispatch(numGroupsX, numGroupsY, numGroupsZ);
- BS_INC_RENDER_STAT(NumComputeCalls);
- }
- void VulkanRenderAPI::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- Rect2I area(left, top, right - left, bottom - top);
- vkCB->setScissorRect(area);
- }
- void VulkanRenderAPI::setStencilRef(UINT32 value, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setStencilRef(value);
- }
- void VulkanRenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask,
- const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->clearViewport(buffers, color, depth, stencil, targetMask);
- BS_INC_RENDER_STAT(NumClears);
- }
- void VulkanRenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil,
- UINT8 targetMask, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->clearRenderTarget(buffers, color, depth, stencil, targetMask);
- BS_INC_RENDER_STAT(NumClears);
- }
- void VulkanRenderAPI::setRenderTarget(const SPtr<RenderTarget>& target, UINT32 readOnlyFlags,
- RenderSurfaceMask loadMask, const SPtr<CommandBuffer>& commandBuffer)
- {
- VulkanCommandBuffer* cb = getCB(commandBuffer);
- VulkanCmdBuffer* vkCB = cb->getInternal();
- vkCB->setRenderTarget(target, readOnlyFlags, loadMask);
-
- BS_INC_RENDER_STAT(NumRenderTargetChanges);
- }
- void VulkanRenderAPI::swapBuffers(const SPtr<RenderTarget>& target, UINT32 syncMask)
- {
- THROW_IF_NOT_CORE_THREAD;
- submitCommandBuffer(mMainCommandBuffer, syncMask);
- target->swapBuffers(syncMask);
- // See if any command buffers finished executing
- VulkanCommandBufferManager& cbm = static_cast<VulkanCommandBufferManager&>(CommandBufferManager::instance());
-
- for (UINT32 i = 0; i < (UINT32)mDevices.size(); i++)
- cbm.refreshStates(i);
- BS_INC_RENDER_STAT(NumPresents);
- }
- void VulkanRenderAPI::addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary)
- {
- BS_EXCEPT(NotImplementedException, "Secondary command buffers not implemented");
- }
- void VulkanRenderAPI::submitCommandBuffer(const SPtr<CommandBuffer>& commandBuffer, UINT32 syncMask)
- {
- THROW_IF_NOT_CORE_THREAD;
- VulkanCommandBuffer* cmdBuffer = getCB(commandBuffer);
- // Submit all transfer buffers first
- VulkanCommandBufferManager& cbm = static_cast<VulkanCommandBufferManager&>(CommandBufferManager::instance());
- cbm.flushTransferBuffers(cmdBuffer->getDeviceIdx());
- cmdBuffer->submit(syncMask);
- }
- void VulkanRenderAPI::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
- {
- dest = matrix;
- // Flip Y axis
- dest[1][1] = -dest[1][1];
- // Convert depth range from [-1,1] to [0,1]
- dest[2][0] = (dest[2][0] + dest[3][0]) / 2;
- dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
- dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
- dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
- }
- const RenderAPIInfo& VulkanRenderAPI::getAPIInfo() const
- {
- RenderAPIFeatures featureFlags =
- RenderAPIFeatureFlag::NDCYAxisDown |
- RenderAPIFeatureFlag::ColumnMajorMatrices |
- RenderAPIFeatureFlag::MultiThreadedCB |
- RenderAPIFeatureFlag::MSAAImageStores |
- RenderAPIFeatureFlag::TextureViews |
- RenderAPIFeatureFlag::Compute |
- RenderAPIFeatureFlag::LoadStore;
- static RenderAPIInfo info(0.0f, 0.0f, 0.0f, 1.0f, VET_COLOR_ABGR, featureFlags);
- return info;
- }
- GpuParamBlockDesc VulkanRenderAPI::generateParamBlockDesc(const String& name, Vector<GpuParamDataDesc>& params)
- {
- GpuParamBlockDesc block;
- block.blockSize = 0;
- block.isShareable = true;
- block.name = name;
- block.slot = 0;
- block.set = 0;
- for (auto& param : params)
- {
- UINT32 size = VulkanUtility::calcInterfaceBlockElementSizeAndOffset(param.type, param.arraySize, block.blockSize);
- if (param.arraySize > 1)
- {
- param.elementSize = size;
- param.arrayElementStride = size;
- param.cpuMemOffset = block.blockSize;
- param.gpuMemOffset = 0;
- block.blockSize += size * param.arraySize;
- }
- else
- {
- param.elementSize = size;
- param.arrayElementStride = size;
- param.cpuMemOffset = block.blockSize;
- param.gpuMemOffset = 0;
- block.blockSize += size;
- }
- param.paramBlockSlot = 0;
- param.paramBlockSet = 0;
- }
- // Constant buffer size must always be a multiple of 16
- if (block.blockSize % 4 != 0)
- block.blockSize += (4 - (block.blockSize % 4));
- return block;
- }
- void VulkanRenderAPI::initCapabilites()
- {
- mNumDevices = (UINT32)mDevices.size();
- mCurrentCapabilities = bs_newN<RenderAPICapabilities>(mNumDevices);
- UINT32 deviceIdx = 0;
- for (auto& device : mDevices)
- {
- RenderAPICapabilities& caps = mCurrentCapabilities[deviceIdx];
- const VkPhysicalDeviceProperties& deviceProps = device->getDeviceProperties();
- const VkPhysicalDeviceFeatures& deviceFeatures = device->getDeviceFeatures();
- const VkPhysicalDeviceLimits& deviceLimits = deviceProps.limits;
- DriverVersion driverVersion;
- driverVersion.major = ((uint32_t)(deviceProps.apiVersion) >> 22);
- driverVersion.minor = ((uint32_t)(deviceProps.apiVersion) >> 12) & 0x3ff;
- driverVersion.release = (uint32_t)(deviceProps.apiVersion) & 0xfff;
- driverVersion.build = 0;
- caps.setDriverVersion(driverVersion);
- caps.setDeviceName(deviceProps.deviceName);
-
- // Determine vendor
- switch (deviceProps.vendorID)
- {
- case 0x10DE:
- caps.setVendor(GPU_NVIDIA);
- break;
- case 0x1002:
- caps.setVendor(GPU_AMD);
- break;
- case 0x163C:
- case 0x8086:
- caps.setVendor(GPU_INTEL);
- break;
- default:
- caps.setVendor(GPU_UNKNOWN);
- break;
- };
-
- caps.setRenderAPIName(getName());
- if(deviceFeatures.textureCompressionBC)
- caps.setCapability(RSC_TEXTURE_COMPRESSION_BC);
- if (deviceFeatures.textureCompressionETC2)
- caps.setCapability(RSC_TEXTURE_COMPRESSION_ETC2);
- if (deviceFeatures.textureCompressionASTC_LDR)
- caps.setCapability(RSC_TEXTURE_COMPRESSION_ASTC);
- caps.setMaxBoundVertexBuffers(deviceLimits.maxVertexInputBindings);
- caps.setNumMultiRenderTargets(deviceLimits.maxColorAttachments);
- caps.setCapability(RSC_COMPUTE_PROGRAM);
- caps.setNumTextureUnits(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
- caps.setNumTextureUnits(GPT_VERTEX_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
- caps.setNumTextureUnits(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
- caps.setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- caps.setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- caps.setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- caps.setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorStorageImages);
- caps.setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorStorageImages);
- if(deviceFeatures.geometryShader)
- {
- caps.setCapability(RSC_GEOMETRY_PROGRAM);
- caps.addShaderProfile("gs_5_0");
- caps.setNumTextureUnits(GPT_GEOMETRY_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
- caps.setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- caps.setGeometryProgramNumOutputVertices(deviceLimits.maxGeometryOutputVertices);
- }
- if (deviceFeatures.tessellationShader)
- {
- caps.setCapability(RSC_TESSELLATION_PROGRAM);
- caps.setNumTextureUnits(GPT_HULL_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
- caps.setNumTextureUnits(GPT_DOMAIN_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
-
- caps.setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- caps.setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
- }
- caps.setNumCombinedTextureUnits(caps.getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
- + caps.getNumTextureUnits(GPT_VERTEX_PROGRAM) + caps.getNumTextureUnits(GPT_GEOMETRY_PROGRAM)
- + caps.getNumTextureUnits(GPT_HULL_PROGRAM) + caps.getNumTextureUnits(GPT_DOMAIN_PROGRAM)
- + caps.getNumTextureUnits(GPT_COMPUTE_PROGRAM));
- caps.setNumCombinedGpuParamBlockBuffers(caps.getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
- + caps.getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM)
- + caps.getNumGpuParamBlockBuffers(GPT_HULL_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM)
- + caps.getNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM));
- caps.setNumCombinedLoadStoreTextureUnits(caps.getNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM)
- + caps.getNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM));
- caps.addShaderProfile("glsl");
- deviceIdx++;
- }
- }
- VulkanCommandBuffer* VulkanRenderAPI::getCB(const SPtr<CommandBuffer>& buffer)
- {
- if (buffer != nullptr)
- return static_cast<VulkanCommandBuffer*>(buffer.get());
- return static_cast<VulkanCommandBuffer*>(mMainCommandBuffer.get());
- }
- VulkanRenderAPI& gVulkanRenderAPI()
- {
- return static_cast<VulkanRenderAPI&>(RenderAPI::instance());
- }
- }}
|