diff --git a/base/vulkanMeshLoader.hpp b/base/vulkanMeshLoader.hpp index b4b5593c..271cf0a6 100644 --- a/base/vulkanMeshLoader.hpp +++ b/base/vulkanMeshLoader.hpp @@ -289,7 +289,7 @@ public: // Loads the mesh with some default flags bool LoadMesh(const std::string& filename) { - int flags = aiProcess_FlipWindingOrder | aiProcess_Triangulate | aiProcess_PreTransformVertices | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals; + int flags = aiProcess_FlipWindingOrder | aiProcess_Triangulate/* | aiProcess_PreTransformVertices*/ | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals; return LoadMesh(filename, flags); } @@ -615,10 +615,10 @@ public: VK_CHECK_RESULT(vkQueueSubmit(copyQueue, 1, &submitInfo, VK_NULL_HANDLE)); VK_CHECK_RESULT(vkQueueWaitIdle(copyQueue)); - vkDestroyBuffer(vulkanDevice->device, vertexStaging.buffer, nullptr); - vkFreeMemory(vulkanDevice->device, vertexStaging.memory, nullptr); - vkDestroyBuffer(vulkanDevice->device, indexStaging.buffer, nullptr); - vkFreeMemory(vulkanDevice->device, indexStaging.memory, nullptr); + vkDestroyBuffer(vulkanDevice->logicalDevice, vertexStaging.buffer, nullptr); + vkFreeMemory(vulkanDevice->logicalDevice, vertexStaging.memory, nullptr); + vkDestroyBuffer(vulkanDevice->logicalDevice, indexStaging.buffer, nullptr); + vkFreeMemory(vulkanDevice->logicalDevice, indexStaging.memory, nullptr); } else { diff --git a/base/vulkandevice.hpp b/base/vulkandevice.hpp index 5231087a..f03d859b 100644 --- a/base/vulkandevice.hpp +++ b/base/vulkandevice.hpp @@ -22,7 +22,7 @@ namespace vk /** @brief Physical device representation */ VkPhysicalDevice physicalDevice; /** @brief Logical device representation (application's view of the device) */ - VkDevice device; + VkDevice logicalDevice; /** @brief Properties of the physical device including limits that the application can check against */ VkPhysicalDeviceProperties properties; /** @brief Features of the physical device that an application can use to check if a feature is supported */ @@ -34,7 +34,39 @@ namespace vk bool enableDebugMarkers = false; /** - * Return the index of a memory type that has all the requested property bits set + * Default constructor + * + * @param physicalDevice Phyiscal device that is to be used + */ + VulkanDevice(VkPhysicalDevice physicalDevice) + { + assert(physicalDevice); + this->physicalDevice = physicalDevice; + + // Store Properties features, limits and properties of the physical device for later use + // Device properties also contain limits and sparse properties + vkGetPhysicalDeviceProperties(physicalDevice, &properties); + // Features should be checked by the examples before using them + vkGetPhysicalDeviceFeatures(physicalDevice, &features); + // Memory properties are used regularly for creating all kinds of buffer + vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); + } + + /** + * Default destructor + * + * @note Frees the logical device + */ + ~VulkanDevice() + { + if (logicalDevice) + { + vkDestroyDevice(logicalDevice, nullptr); + } + } + + /** + * Get the index of a memory type that has all the requested property bits set * * @param typeBits Bitmask with bits set for each memory type supported by the resource to request for (from VkMemoryRequirements) * @param properties Bitmask of properties for the memory type to request @@ -61,32 +93,21 @@ namespace vk //todo : Exceptions are disabled by default on Android (need to add LOCAL_CPP_FEATURES += exceptions to Android.mk), so for now just return zero return 0; #else - throw "Could not find a memory type for the passed properties"; + throw std::runtime_error("Could not find a matching memory type"); #endif } /** - * Create the logical device based on the passed physical device + * Create the logical device based on the assigned physical device * - * @param physicalDevice The physical device for which the logical reprenstation is to be created * @param queueCreateInfos A vector containing queue create infos for all queues to be requested on the device * @param enabledFeatures Can be used to enable certain features upon device creation * @param useSwapChain Set to false for headless rendering to omit the swapchain device extensions * * @return VkResult of the device creation call */ - VkResult create(VkPhysicalDevice physicalDevice, std::vector &queueCreateInfos, VkPhysicalDeviceFeatures enabledFeatures, bool useSwapChain = true) + VkResult createLogicalDevice(std::vector &queueCreateInfos, VkPhysicalDeviceFeatures enabledFeatures, bool useSwapChain = true) { - this->physicalDevice = physicalDevice; - - // Store Properties features, limits and properties of the physical device for later use - // Device properties also contain limits and sparse properties - vkGetPhysicalDeviceProperties(physicalDevice, &properties); - // Features should be checked by the examples before using them - vkGetPhysicalDeviceFeatures(physicalDevice, &features); - // Memory properties are used regularly for creating all kinds of buffer - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); - // Create the logical device representation std::vector deviceExtensions; if (useSwapChain) @@ -115,7 +136,7 @@ namespace vk deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data(); } - return vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device); + return vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &logicalDevice); } /** @@ -134,28 +155,28 @@ namespace vk { // Create the buffer handle VkBufferCreateInfo bufferCreateInfo = vkTools::initializers::bufferCreateInfo(usageFlags, size); - VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, buffer)); + VK_CHECK_RESULT(vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, buffer)); // Create the memory backing up the buffer handle VkMemoryRequirements memReqs; VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); - vkGetBufferMemoryRequirements(device, *buffer, &memReqs); + vkGetBufferMemoryRequirements(logicalDevice, *buffer, &memReqs); memAlloc.allocationSize = memReqs.size; // Find a memory type index that fits the properties of the buffer memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags); - VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, memory)); + VK_CHECK_RESULT(vkAllocateMemory(logicalDevice, &memAlloc, nullptr, memory)); // If a pointer to the buffer data has been passed, map the buffer and copy over the data if (data != nullptr) { void *mapped; - VK_CHECK_RESULT(vkMapMemory(device, *memory, 0, size, 0, &mapped)); + VK_CHECK_RESULT(vkMapMemory(logicalDevice, *memory, 0, size, 0, &mapped)); memcpy(mapped, data, size); - vkUnmapMemory(device, *memory); + vkUnmapMemory(logicalDevice, *memory); } // Attach the memory to the buffer object - VK_CHECK_RESULT(vkBindBufferMemory(device, *buffer, *memory, 0)); + VK_CHECK_RESULT(vkBindBufferMemory(logicalDevice, *buffer, *memory, 0)); return VK_SUCCESS; } @@ -173,20 +194,20 @@ namespace vk */ VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, vk::Buffer *buffer, VkDeviceSize size, void *data = nullptr) { - buffer->device = device; + buffer->device = logicalDevice; // Create the buffer handle VkBufferCreateInfo bufferCreateInfo = vkTools::initializers::bufferCreateInfo(usageFlags, size); - VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &buffer->buffer)); + VK_CHECK_RESULT(vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, &buffer->buffer)); // Create the memory backing up the buffer handle VkMemoryRequirements memReqs; VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); - vkGetBufferMemoryRequirements(device, buffer->buffer, &memReqs); + vkGetBufferMemoryRequirements(logicalDevice, buffer->buffer, &memReqs); memAlloc.allocationSize = memReqs.size; // Find a memory type index that fits the properties of the buffer memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags); - VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &buffer->memory)); + VK_CHECK_RESULT(vkAllocateMemory(logicalDevice, &memAlloc, nullptr, &buffer->memory)); buffer->alignment = memReqs.alignment; buffer->size = memAlloc.allocationSize; diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 713c7719..8cfd583e 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -346,7 +346,7 @@ void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer * meshBuffer, std::vector vertexLayout, vkMeshLoader::MeshCreateInfo *meshCreateInfo) { - VulkanMeshLoader *mesh = new VulkanMeshLoader(&vulkanDevice); + VulkanMeshLoader *mesh = new VulkanMeshLoader(vulkanDevice); #if defined(__ANDROID__) mesh->assetManager = androidApp->activity->assetManager; @@ -759,7 +759,7 @@ VulkanExampleBase::~VulkanExampleBase() delete textOverlay; } - vkDestroyDevice(device, nullptr); + delete vulkanDevice; if (enableValidation) { @@ -812,6 +812,8 @@ void VulkanExampleBase::initVulkan(bool enableValidation) // and want to use another one physicalDevice = physicalDevices[0]; + vulkanDevice = new vk::VulkanDevice(physicalDevice); + // Find a queue that supports graphics operations uint32_t graphicsQueueIndex = 0; uint32_t queueCount; @@ -841,10 +843,10 @@ void VulkanExampleBase::initVulkan(bool enableValidation) queueCreateInfos[0].queueCount = 1; queueCreateInfos[0].pQueuePriorities = queuePriorities.data(); - VK_CHECK_RESULT(vulkanDevice.create(physicalDevice, queueCreateInfos, enabledFeatures)); + VK_CHECK_RESULT(vulkanDevice->createLogicalDevice(queueCreateInfos, enabledFeatures)); // Assign device to base class context - device = vulkanDevice.device; + device = vulkanDevice->logicalDevice; // Store properties (including limits) and features of the phyiscal device // So examples can check against them and see if a feature is actually supported diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index e336e3bc..1365e05c 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -97,7 +97,7 @@ protected: // todo: getter? should always point to VulkanDevice->device VkDevice device; /** @brief Encapsulated physical and logical vulkan device */ - vk::VulkanDevice vulkanDevice; + vk::VulkanDevice *vulkanDevice; // Handle to the device graphics queue that command buffers are submitted to VkQueue queue; // Color buffer format diff --git a/base/vulkanframebuffer.hpp b/base/vulkanframebuffer.hpp index b61e6d6f..9c1c561c 100644 --- a/base/vulkanframebuffer.hpp +++ b/base/vulkanframebuffer.hpp @@ -116,13 +116,13 @@ namespace vk assert(vulkanDevice); for (auto attachment : attachments) { - vkDestroyImage(vulkanDevice->device, attachment.image, nullptr); - vkDestroyImageView(vulkanDevice->device, attachment.view, nullptr); - vkFreeMemory(vulkanDevice->device, attachment.memory, nullptr); + vkDestroyImage(vulkanDevice->logicalDevice, attachment.image, nullptr); + vkDestroyImageView(vulkanDevice->logicalDevice, attachment.view, nullptr); + vkFreeMemory(vulkanDevice->logicalDevice, attachment.memory, nullptr); } - vkDestroySampler(vulkanDevice->device, sampler, nullptr); - vkDestroyRenderPass(vulkanDevice->device, renderPass, nullptr); - vkDestroyFramebuffer(vulkanDevice->device, framebuffer, nullptr); + vkDestroySampler(vulkanDevice->logicalDevice, sampler, nullptr); + vkDestroyRenderPass(vulkanDevice->logicalDevice, renderPass, nullptr); + vkDestroyFramebuffer(vulkanDevice->logicalDevice, framebuffer, nullptr); } /** @@ -185,12 +185,12 @@ namespace vk VkMemoryRequirements memReqs; // Create image for this attachment - VK_CHECK_RESULT(vkCreateImage(vulkanDevice->device, &image, nullptr, &attachment.image)); - vkGetImageMemoryRequirements(vulkanDevice->device, attachment.image, &memReqs); + VK_CHECK_RESULT(vkCreateImage(vulkanDevice->logicalDevice, &image, nullptr, &attachment.image)); + vkGetImageMemoryRequirements(vulkanDevice->logicalDevice, attachment.image, &memReqs); memAlloc.allocationSize = memReqs.size; memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(vulkanDevice->device, &memAlloc, nullptr, &attachment.memory)); - VK_CHECK_RESULT(vkBindImageMemory(vulkanDevice->device, attachment.image, attachment.memory, 0)); + VK_CHECK_RESULT(vkAllocateMemory(vulkanDevice->logicalDevice, &memAlloc, nullptr, &attachment.memory)); + VK_CHECK_RESULT(vkBindImageMemory(vulkanDevice->logicalDevice, attachment.image, attachment.memory, 0)); attachment.subresourceRange = {}; attachment.subresourceRange.aspectMask = aspectMask; @@ -214,7 +214,7 @@ namespace vk //todo: workaround for depth+stencil attachments imageView.subresourceRange.aspectMask = (attachment.hasDepth()) ? VK_IMAGE_ASPECT_DEPTH_BIT : aspectMask; imageView.image = attachment.image; - VK_CHECK_RESULT(vkCreateImageView(vulkanDevice->device, &imageView, nullptr, &attachment.view)); + VK_CHECK_RESULT(vkCreateImageView(vulkanDevice->logicalDevice, &imageView, nullptr, &attachment.view)); // Fill attachment description attachment.description = {}; @@ -264,7 +264,7 @@ namespace vk samplerInfo.minLod = 0.0f; samplerInfo.maxLod = 1.0f; samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - return vkCreateSampler(vulkanDevice->device, &samplerInfo, nullptr, &sampler); + return vkCreateSampler(vulkanDevice->logicalDevice, &samplerInfo, nullptr, &sampler); } /** @@ -326,7 +326,7 @@ namespace vk renderPassInfo.attachmentCount = static_cast(attachmentDescriptions.size()); renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = &subpass; - VK_CHECK_RESULT(vkCreateRenderPass(vulkanDevice->device, &renderPassInfo, nullptr, &renderPass)); + VK_CHECK_RESULT(vkCreateRenderPass(vulkanDevice->logicalDevice, &renderPassInfo, nullptr, &renderPass)); std::vector attachmentViews; for (auto attachment : attachments) @@ -352,7 +352,7 @@ namespace vk framebufferInfo.width = width; framebufferInfo.height = height; framebufferInfo.layers = maxLayers; - VK_CHECK_RESULT(vkCreateFramebuffer(vulkanDevice->device, &framebufferInfo, nullptr, &framebuffer)); + VK_CHECK_RESULT(vkCreateFramebuffer(vulkanDevice->logicalDevice, &framebufferInfo, nullptr, &framebuffer)); return VK_SUCCESS; } diff --git a/debugmarker/debugmarker.cpp b/debugmarker/debugmarker.cpp index b2b9a92e..d126f3f6 100644 --- a/debugmarker/debugmarker.cpp +++ b/debugmarker/debugmarker.cpp @@ -585,7 +585,7 @@ public: // Load a model file as separate meshes into a scene void loadModel(std::string filename, Scene *scene) { - VulkanMeshLoader *meshLoader = new VulkanMeshLoader(&vulkanDevice); + VulkanMeshLoader *meshLoader = new VulkanMeshLoader(vulkanDevice); #if defined(__ANDROID__) meshLoader->assetManager = androidApp->activity->assetManager; #endif diff --git a/deferredshadows/deferredshadows.cpp b/deferredshadows/deferredshadows.cpp index 96dab7a0..a2f97f9a 100644 --- a/deferredshadows/deferredshadows.cpp +++ b/deferredshadows/deferredshadows.cpp @@ -247,7 +247,7 @@ public: { VkCommandBuffer layoutCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - frameBuffers.shadow = new vk::Framebuffer(&vulkanDevice); + frameBuffers.shadow = new vk::Framebuffer(vulkanDevice); frameBuffers.shadow->width = SHADOWMAP_DIM; frameBuffers.shadow->height = SHADOWMAP_DIM; @@ -279,7 +279,7 @@ public: { VkCommandBuffer layoutCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - frameBuffers.deferred = new vk::Framebuffer(&vulkanDevice); + frameBuffers.deferred = new vk::Framebuffer(vulkanDevice); frameBuffers.deferred->width = FB_DIM; frameBuffers.deferred->height = FB_DIM; diff --git a/mesh/mesh.cpp b/mesh/mesh.cpp index 9d9e90c7..b02aa90c 100644 --- a/mesh/mesh.cpp +++ b/mesh/mesh.cpp @@ -175,7 +175,7 @@ public: // The other example will use the VulkanMesh loader which has some additional functionality for loading meshes void loadMesh() { - VulkanMeshLoader *meshLoader = new VulkanMeshLoader(&vulkanDevice); + VulkanMeshLoader *meshLoader = new VulkanMeshLoader(vulkanDevice); #if defined(__ANDROID__) meshLoader->assetManager = androidApp->activity->assetManager; #endif diff --git a/skeletalanimation/skeletalanimation.cpp b/skeletalanimation/skeletalanimation.cpp index 7714b48b..4df86a84 100644 --- a/skeletalanimation/skeletalanimation.cpp +++ b/skeletalanimation/skeletalanimation.cpp @@ -482,7 +482,7 @@ public: void loadMesh() { skinnedMesh = new SkinnedMesh(); - skinnedMesh->meshLoader = new VulkanMeshLoader(&vulkanDevice); + skinnedMesh->meshLoader = new VulkanMeshLoader(vulkanDevice); #if defined(__ANDROID__) skinnedMesh->meshLoader->assetManager = androidApp->activity->assetManager; #endif diff --git a/vulkanscene/vulkanscene.cpp b/vulkanscene/vulkanscene.cpp index d778994b..0eb9cd63 100644 --- a/vulkanscene/vulkanscene.cpp +++ b/vulkanscene/vulkanscene.cpp @@ -182,10 +182,10 @@ public: }; // Load meshes for demos scene - demoMeshes.logos = new VulkanMeshLoader(&vulkanDevice); - demoMeshes.background = new VulkanMeshLoader(&vulkanDevice); - demoMeshes.models = new VulkanMeshLoader(&vulkanDevice); - demoMeshes.skybox = new VulkanMeshLoader(&vulkanDevice); + demoMeshes.logos = new VulkanMeshLoader(vulkanDevice); + demoMeshes.background = new VulkanMeshLoader(vulkanDevice); + demoMeshes.models = new VulkanMeshLoader(vulkanDevice); + demoMeshes.skybox = new VulkanMeshLoader(vulkanDevice); #if defined(__ANDROID__) demoMeshes.logos->assetManager = androidApp->activity->assetManager;