3#define VMA_IMPLEMENTATION
4#include "VulkanMemoryAllocator/include/vk_mem_alloc.h"
25 uint32_t queueFamilyCount;
27 assert(queueFamilyCount > 0);
32 uint32_t extCount = 0;
33 vkEnumerateDeviceExtensionProperties(
physicalDevice,
nullptr, &extCount,
nullptr);
36 std::vector<VkExtensionProperties> extensions(extCount);
37 if (vkEnumerateDeviceExtensionProperties(
physicalDevice,
nullptr, &extCount, &extensions.front()) == VK_SUCCESS)
39 for (
auto ext : extensions)
54 for (
const auto &pool :
poolMap)
91 if ((typeBits & 1) == 1)
107 *memTypeFound =
false;
112 throw std::runtime_error(
"Could not find a matching memory type");
129 if (queueFlags & VK_QUEUE_COMPUTE_BIT)
142 if (queueFlags & VK_QUEUE_TRANSFER_BIT)
162 throw std::runtime_error(
"Could not find a matching queue family index");
181 std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
186 const float defaultQueuePriority(0.0f);
189 if (requestedQueueTypes & VK_QUEUE_GRAPHICS_BIT)
192 VkDeviceQueueCreateInfo queueInfo{};
193 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
195 queueInfo.queueCount = 1;
196 queueInfo.pQueuePriorities = &defaultQueuePriority;
197 queueCreateInfos.push_back(queueInfo);
205 if (requestedQueueTypes & VK_QUEUE_COMPUTE_BIT)
211 VkDeviceQueueCreateInfo queueInfo{};
212 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
214 queueInfo.queueCount = 1;
215 queueInfo.pQueuePriorities = &defaultQueuePriority;
216 queueCreateInfos.push_back(queueInfo);
226 if (requestedQueueTypes & VK_QUEUE_TRANSFER_BIT)
232 VkDeviceQueueCreateInfo queueInfo{};
233 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
235 queueInfo.queueCount = 1;
236 queueInfo.pQueuePriorities = &defaultQueuePriority;
237 queueCreateInfos.push_back(queueInfo);
247 std::vector<const char*> deviceExtensions(enabledExtensions);
251 deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
254 VkDeviceCreateInfo deviceCreateInfo = {};
255 deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
256 deviceCreateInfo.queueCreateInfoCount =
static_cast<uint32_t
>(queueCreateInfos.size());;
257 deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
260 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT physicalDeviceShaderAtomicFloatFeaturesEXT{};
261 physicalDeviceShaderAtomicFloatFeaturesEXT.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
262 physicalDeviceShaderAtomicFloatFeaturesEXT.shaderBufferFloat32AtomicAdd =
true;
263 deviceCreateInfo.pNext = &physicalDeviceShaderAtomicFloatFeaturesEXT;
266 VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
268 physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
270 physicalDeviceFeatures2.pNext = pNextChain;
271 deviceCreateInfo.pEnabledFeatures =
nullptr;
272 deviceCreateInfo.pNext = &physicalDeviceFeatures2;
278 deviceExtensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
283 deviceExtensions.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);
287 deviceExtensions.push_back(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME);
290 if (deviceExtensions.size() > 0)
292 for (
const char* enabledExtension : deviceExtensions)
295 std::cerr <<
"Enabled device extension \"" << enabledExtension <<
"\" is not present at device level\n";
299 deviceCreateInfo.enabledExtensionCount = (uint32_t)deviceExtensions.size();
300 deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
306 if (result != VK_SUCCESS)
329 VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
330 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
346 VkResult
VkContext::createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size, VkBuffer *buffer, VkDeviceMemory *memory,
void *data)
350 bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
354 VkMemoryRequirements memReqs;
356 vkGetBufferMemoryRequirements(
logicalDevice, *buffer, &memReqs);
357 memAlloc.allocationSize = memReqs.size;
359 memAlloc.memoryTypeIndex =
getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
361 VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
362 if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
363 allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
364 allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
365 memAlloc.pNext = &allocFlagsInfo;
374 memcpy(mapped, data, size);
376 if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
379 mappedRange.memory = *memory;
380 mappedRange.offset = 0;
381 mappedRange.size = size;
404 VkResult
VkContext::createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::shared_ptr<vks::Buffer> &buffer, VkDeviceSize size,
const void *data)
413 VkMemoryRequirements memReqs;
415 vkGetBufferMemoryRequirements(
logicalDevice, buffer->buffer, &memReqs);
416 memAlloc.allocationSize = memReqs.size;
418 memAlloc.memoryTypeIndex =
getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
420 VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
421 if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
422 allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
423 allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
424 memAlloc.pNext = &allocFlagsInfo;
428 buffer->usePool = VK_FALSE;
429 buffer->alignment = memReqs.alignment;
431 buffer->usageFlags = usageFlags;
432 buffer->memoryPropertyFlags = memoryPropertyFlags;
438 memcpy(buffer->mapped, data, size);
439 if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
446 buffer->setupDescriptor();
449 return buffer->bind();
463 VkBufferCreateInfo bufferCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
464 bufferCreateInfo.size = buffer->size;
465 bufferCreateInfo.usage = buffer->usageFlags;
467 VmaAllocationCreateInfo allocationCreateInfo = {};
468 allocationCreateInfo.usage =
static_cast<VmaMemoryUsage
>(
poolMap[poolType].usage);
469 allocationCreateInfo.pool =
poolMap[poolType].pool;
471 VmaAllocationInfo allocationInfo;
472 VkResult ret = vmaCreateBuffer(
g_Allocator, &bufferCreateInfo, &allocationCreateInfo, &buffer->buffer, &buffer->allocation, &allocationInfo);
475 buffer->usePool = VK_TRUE;
476 buffer->memory = allocationInfo.deviceMemory;
477 buffer->offset = allocationInfo.offset;
481 if (data !=
nullptr) {
482 ret = vmaMapMemory(buffer->allocator, buffer->allocation, (
void**)&buffer->mapped);
484 memcpy(buffer->mapped, data, buffer->size);
486 if ((buffer->memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) {
487 vmaFlushAllocation(buffer->allocator, buffer->allocation, allocationInfo.offset, allocationInfo.size);
489 vmaUnmapMemory(buffer->allocator, buffer->allocation);
490 buffer->mapped =
nullptr;
492 buffer->setupDescriptor();
507 VmaAllocatorCreateInfo allocatorInfo = {};
508 allocatorInfo.vulkanApiVersion = apiVerion;
511 allocatorInfo.instance = instance;
514 VmaPoolCreateInfo poolCreateInfo = {};
515 poolCreateInfo.blockSize = 20 * 1024 * 1024;
516 poolCreateInfo.minBlockCount = 1;
517 poolCreateInfo.maxBlockCount = 2;
519 VmaAllocationCreateInfo allocationCreateInfo = {};
520 VkBufferCreateInfo bufferCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
521 bufferCreateInfo.size = 1024;
528 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
529 allocationCreateInfo.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
530 bufferCreateInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
531 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
532 VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
537 allocationCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
538 allocationCreateInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
539 bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
544 allocationCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
545 allocationCreateInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
546 bufferCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
553 memoryPoolInfo.
usage = allocationCreateInfo.usage;
554 vmaFindMemoryTypeIndexForBufferInfo(
g_Allocator, &bufferCreateInfo, &allocationCreateInfo, &poolCreateInfo.memoryTypeIndex);
555 VkResult res = vmaCreatePool(
g_Allocator, &poolCreateInfo, &memoryPoolInfo.
pool);
556 if (res != VK_SUCCESS) {
560 poolMap[type] = memoryPoolInfo;
581 VkBufferCopy bufferCopy{};
582 if (copyRegion ==
nullptr)
584 bufferCopy.size = src->
size;
588 bufferCopy = *copyRegion;
591 vkCmdCopyBuffer(copyCmd, src->
buffer, dst->
buffer, 1, &bufferCopy);
608 VkCommandPoolCreateInfo cmdPoolInfo = {};
609 cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
610 cmdPoolInfo.queueFamilyIndex = queueFamilyIndex;
611 cmdPoolInfo.flags = createFlags;
612 VkCommandPool cmdPool;
629 VkCommandBuffer cmdBuffer;
658 if (commandBuffer == VK_NULL_HANDLE)
666 submitInfo.commandBufferCount = 1;
667 submitInfo.pCommandBuffers = &commandBuffer;
679 vkFreeCommandBuffers(
logicalDevice, pool, 1, &commandBuffer);
712 std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
713 for (
auto& format : depthFormats)
715 VkFormatProperties formatProperties;
716 vkGetPhysicalDeviceFormatProperties(
physicalDevice, format, &formatProperties);
718 if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
720 if (checkSamplingSupport) {
721 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
728 throw std::runtime_error(
"Could not find a matching depth format");
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL)
VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size, VkBuffer *buffer, VkDeviceMemory *memory, void *data=nullptr)
VkCommandPool commandPool
Default command pool for the graphics queue family index.
bool extensionSupported(std::string extension)
std::vector< std::string > supportedExtensions
List of extensions supported by the device.
uint32_t getQueueFamilyIndex(VkQueueFlagBits queueFlags) const
void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, VkCommandPool pool, bool free=true)
VkCommandBuffer createCommandBuffer(VkCommandBufferLevel level, VkCommandPool pool, bool begin=false)
VkPhysicalDeviceFeatures features
Features of the physical device that an application can use to check if a feature is supported.
VkContext(VkPhysicalDevice physicalDevice)
VkPhysicalDevice physicalDeviceHandle()
struct dyno::VkContext::@247250360024255345354242335264053265034214002126 queueFamilyIndices
VkResult createLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, std::vector< const char * > enabledExtensions, void *pNextChain, bool useSwapChain=true, VkQueueFlags requestedQueueTypes=VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT)
bool enableDebugMarkers
Set to true when the debug marker extension is detected.
VkCommandPool createCommandPool(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags createFlags=VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)
uint32_t getMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound=nullptr) const
void copyBuffer(vks::Buffer *src, vks::Buffer *dst, VkQueue queue, VkBufferCopy *copyRegion=nullptr)
VkPhysicalDevice physicalDevice
Physical device representation.
VkResult createMemoryPool(VkInstance instance, uint32_t apiVerion)
VkPipelineCache pipelineCache
Contains queue family indices.
VkPhysicalDeviceMemoryProperties memoryProperties
Memory types and heaps of the physical device.
bool isComputeQueueSpecial()
VkPhysicalDeviceProperties properties
Properties of the physical device including limits that the application can check against.
VkPhysicalDeviceFeatures enabledFeatures
Features that have been enabled for use on the physical device.
void createPipelineCache()
std::vector< VkQueueFamilyProperties > queueFamilyProperties
Queue family properties of the physical device.
std::map< VkFlags, MemoryPoolInfo > poolMap
VkFormat getSupportedDepthFormat(bool checkSamplingSupport)
VkDevice logicalDevice
Logical device representation (application's view of the device)
Encapsulates access to a Vulkan buffer backed up by device memory.
This is an implementation of AdditiveCCD based on peridyno.
VkCommandBufferAllocateInfo commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags=0)
VkMemoryAllocateInfo memoryAllocateInfo()
VkCommandBufferBeginInfo commandBufferBeginInfo()
VkBufferCreateInfo bufferCreateInfo()
VkMappedMemoryRange mappedMemoryRange()
VkSubmitInfo submitInfo()