Update zvulkan

This commit is contained in:
Magnus Norddahl 2023-10-04 19:08:50 +02:00
parent baa1ead6e9
commit 1a4d2a783f
6 changed files with 128 additions and 35 deletions

View file

@ -123,6 +123,7 @@ See documentation chapter: \ref statistics.
#ifdef __cplusplus
#include <cstdio>
extern "C" {
#endif

View file

@ -144,7 +144,7 @@ public:
ImageViewBuilder();
ImageViewBuilder& Type(VkImageViewType type);
ImageViewBuilder& Image(VulkanImage *image, VkFormat format, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT);
ImageViewBuilder& Image(VulkanImage *image, VkFormat format, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int mipLevel = 0, int arrayLayer = 0, int levelCount = 0, int layerCount = 0);
ImageViewBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanImageView> Create(VulkanDevice *device);
@ -492,8 +492,8 @@ public:
PipelineBarrier& AddMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
PipelineBarrier& AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
PipelineBarrier& AddImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1, int baseArrayLayer = 0, int layerCount = 1);
PipelineBarrier& AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1, int baseArrayLayer = 0, int layerCount = 1);
PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
@ -546,3 +546,24 @@ private:
std::vector<VkWriteDescriptorSet> writes;
std::vector<std::unique_ptr<WriteExtra>> writeExtras;
};
class BufferTransfer
{
public:
BufferTransfer& AddBuffer(VulkanBuffer* buffer, size_t offset, const void* data, size_t size);
BufferTransfer& AddBuffer(VulkanBuffer* buffer, const void* data, size_t size);
BufferTransfer& AddBuffer(VulkanBuffer* buffer, const void* data0, size_t size0, const void* data1, size_t size1);
std::unique_ptr<VulkanBuffer> Execute(VulkanDevice* device, VulkanCommandBuffer* cmdbuffer);
private:
struct BufferCopy
{
VulkanBuffer* buffer;
size_t offset;
const void* data0;
size_t size0;
const void* data1;
size_t size1;
};
std::vector<BufferCopy> bufferCopies;
};

View file

@ -94,6 +94,7 @@ std::string to_string(const T& val) {
#endif
#if defined(_MSC_VER)
#undef strdup
#define strdup _strdup
#endif

View file

@ -5,7 +5,11 @@
#define VK_USE_PLATFORM_MACOS_MVK
#define VK_USE_PLATFORM_METAL_EXT
#else
#if defined(VULKAN_USE_XLIB)
#define VK_USE_PLATFORM_XLIB_KHR
#elif defined(VULKAN_USE_WAYLAND)
#define VK_USE_PLATFORM_WAYLAND_KHR
#endif
#endif
/* This file is part of volk library; see volk.h for version/license details */

View file

@ -1,4 +1,3 @@
#include "vulkanbuilders.h"
#include "vulkansurface.h"
#include "vulkancompatibledevice.h"
@ -281,7 +280,7 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules, includer);
if (!compileSuccess)
{
throw std::runtime_error(std::string("Shader compile failed: ") + shader.getInfoLog());
VulkanError((std::string("Shader compile failed: ") + shader.getInfoLog()).c_str());
}
glslang::TProgram program;
@ -289,13 +288,13 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
bool linkSuccess = program.link(EShMsgDefault);
if (!linkSuccess)
{
throw std::runtime_error(std::string("Shader link failed: ") + program.getInfoLog());
VulkanError((std::string("Shader link failed: ") + program.getInfoLog()).c_str());
}
glslang::TIntermediate *intermediate = program.getIntermediate(stage);
if (!intermediate)
{
throw std::runtime_error("Internal shader compiler error");
VulkanError("Internal shader compiler error");
}
glslang::SpvOptions spvOptions;
@ -315,7 +314,7 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
VkShaderModule shaderModule;
VkResult result = vkCreateShaderModule(device->device, &createInfo, nullptr, &shaderModule);
if (result != VK_SUCCESS)
throw std::runtime_error("Could not create vulkan shader module");
VulkanError("Could not create vulkan shader module");
auto obj = std::make_unique<VulkanShader>(device, shaderModule);
if (debugName)
@ -505,13 +504,15 @@ ImageViewBuilder& ImageViewBuilder::Type(VkImageViewType type)
return *this;
}
ImageViewBuilder& ImageViewBuilder::Image(VulkanImage* image, VkFormat format, VkImageAspectFlags aspectMask)
ImageViewBuilder& ImageViewBuilder::Image(VulkanImage* image, VkFormat format, VkImageAspectFlags aspectMask, int mipLevel, int arrayLayer, int levelCount, int layerCount)
{
viewInfo.image = image->image;
viewInfo.format = format;
viewInfo.subresourceRange.levelCount = image->mipLevels;
viewInfo.subresourceRange.levelCount = levelCount == 0 ? image->mipLevels : levelCount;
viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.layerCount = image->layerCount;
viewInfo.subresourceRange.layerCount = layerCount == 0 ? image->layerCount : layerCount;
viewInfo.subresourceRange.baseMipLevel = mipLevel;
viewInfo.subresourceRange.baseArrayLayer = arrayLayer;
return *this;
}
@ -704,7 +705,7 @@ std::unique_ptr<VulkanAccelerationStructure> AccelerationStructureBuilder::Creat
VkAccelerationStructureKHR hande = {};
VkResult result = vkCreateAccelerationStructureKHR(device->device, &createInfo, nullptr, &hande);
if (result != VK_SUCCESS)
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
VulkanError("vkCreateAccelerationStructureKHR failed");
auto obj = std::make_unique<VulkanAccelerationStructure>(device, hande);
if (debugName)
obj->SetDebugName(debugName);
@ -1459,12 +1460,12 @@ PipelineBarrier& PipelineBarrier::AddBuffer(VulkanBuffer* buffer, VkDeviceSize o
return *this;
}
PipelineBarrier& PipelineBarrier::AddImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
PipelineBarrier& PipelineBarrier::AddImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount, int baseArrayLayer, int layerCount)
{
return AddImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount);
return AddImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount, baseArrayLayer, layerCount);
}
PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount, int baseArrayLayer, int layerCount)
{
VkImageMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@ -1478,8 +1479,8 @@ PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayou
barrier.subresourceRange.aspectMask = aspectMask;
barrier.subresourceRange.baseMipLevel = baseMipLevel;
barrier.subresourceRange.levelCount = levelCount;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.baseArrayLayer = baseArrayLayer;
barrier.subresourceRange.layerCount = layerCount;
imageMemoryBarriers.push_back(barrier);
return *this;
}
@ -1823,7 +1824,8 @@ std::vector<VulkanCompatibleDevice> VulkanDeviceBuilder::FindDevices(const std::
// Check if all required features are there
if (info.Features.Features.samplerAnisotropy != VK_TRUE ||
info.Features.Features.fragmentStoresAndAtomics != VK_TRUE)
info.Features.Features.fragmentStoresAndAtomics != VK_TRUE ||
info.Features.Features.multiDrawIndirect != VK_TRUE)
continue;
VulkanCompatibleDevice dev;
@ -1846,6 +1848,7 @@ std::vector<VulkanCompatibleDevice> VulkanDeviceBuilder::FindDevices(const std::
enabledFeatures.Features.fragmentStoresAndAtomics = deviceFeatures.Features.fragmentStoresAndAtomics;
enabledFeatures.Features.depthClamp = deviceFeatures.Features.depthClamp;
enabledFeatures.Features.shaderClipDistance = deviceFeatures.Features.shaderClipDistance;
enabledFeatures.Features.multiDrawIndirect = deviceFeatures.Features.multiDrawIndirect;
enabledFeatures.BufferDeviceAddress.bufferDeviceAddress = deviceFeatures.BufferDeviceAddress.bufferDeviceAddress;
enabledFeatures.AccelerationStructure.accelerationStructure = deviceFeatures.AccelerationStructure.accelerationStructure;
enabledFeatures.RayQuery.rayQuery = deviceFeatures.RayQuery.rayQuery;
@ -1853,6 +1856,7 @@ std::vector<VulkanCompatibleDevice> VulkanDeviceBuilder::FindDevices(const std::
enabledFeatures.DescriptorIndexing.descriptorBindingPartiallyBound = deviceFeatures.DescriptorIndexing.descriptorBindingPartiallyBound;
enabledFeatures.DescriptorIndexing.descriptorBindingSampledImageUpdateAfterBind = deviceFeatures.DescriptorIndexing.descriptorBindingSampledImageUpdateAfterBind;
enabledFeatures.DescriptorIndexing.descriptorBindingVariableDescriptorCount = deviceFeatures.DescriptorIndexing.descriptorBindingVariableDescriptorCount;
enabledFeatures.DescriptorIndexing.shaderSampledImageArrayNonUniformIndexing = deviceFeatures.DescriptorIndexing.shaderSampledImageArrayNonUniformIndexing;
// Figure out which queue can present
if (surface)
@ -1936,3 +1940,64 @@ std::shared_ptr<VulkanSwapChain> VulkanSwapChainBuilder::Create(VulkanDevice* de
{
return std::make_shared<VulkanSwapChain>(device);
}
/////////////////////////////////////////////////////////////////////////////
BufferTransfer& BufferTransfer::AddBuffer(VulkanBuffer* buffer, size_t offset, const void* data, size_t size)
{
bufferCopies.push_back({ buffer, offset, data, size, nullptr, 0 });
return *this;
}
BufferTransfer& BufferTransfer::AddBuffer(VulkanBuffer* buffer, const void* data, size_t size)
{
bufferCopies.push_back({ buffer, 0, data, size, nullptr, 0 });
return *this;
}
BufferTransfer& BufferTransfer::AddBuffer(VulkanBuffer* buffer, const void* data0, size_t size0, const void* data1, size_t size1)
{
bufferCopies.push_back({ buffer, 0, data0, size0, data1, size1 });
return *this;
}
std::unique_ptr<VulkanBuffer> BufferTransfer::Execute(VulkanDevice* device, VulkanCommandBuffer* cmdbuffer)
{
size_t transferbuffersize = 0;
for (const auto& copy : bufferCopies)
transferbuffersize += copy.size0 + copy.size1;
if (transferbuffersize == 0)
return nullptr;
auto transferBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.Size(transferbuffersize)
.DebugName("BufferTransfer.transferBuffer")
.Create(device);
uint8_t* data = (uint8_t*)transferBuffer->Map(0, transferbuffersize);
size_t pos = 0;
for (const auto& copy : bufferCopies)
{
memcpy(data + pos, copy.data0, copy.size0);
pos += copy.size0;
memcpy(data + pos, copy.data1, copy.size1);
pos += copy.size1;
}
transferBuffer->Unmap();
pos = 0;
for (const auto& copy : bufferCopies)
{
if (copy.size0 > 0)
cmdbuffer->copyBuffer(transferBuffer.get(), copy.buffer, pos, copy.offset, copy.size0);
pos += copy.size0;
if (copy.size1 > 0)
cmdbuffer->copyBuffer(transferBuffer.get(), copy.buffer, pos, copy.offset + copy.size0, copy.size1);
pos += copy.size1;
}
return transferBuffer;
}

View file

@ -34,13 +34,13 @@ void VulkanSwapChain::Create(int width, int height, int imageCount, bool vsync,
uint32_t imageCount;
VkResult result = vkGetSwapchainImagesKHR(device->device, swapchain, &imageCount, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetSwapchainImagesKHR failed");
VulkanError("vkGetSwapchainImagesKHR failed");
std::vector<VkImage> swapchainImages;
swapchainImages.resize(imageCount);
result = vkGetSwapchainImagesKHR(device->device, swapchain, &imageCount, swapchainImages.data());
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetSwapchainImagesKHR failed (2)");
VulkanError("vkGetSwapchainImagesKHR failed (2)");
for (VkImage vkimage : swapchainImages)
{
@ -103,7 +103,7 @@ bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, boo
}
if (caps.PresentModes.empty())
throw std::runtime_error("No surface present modes supported");
VulkanError("No surface present modes supported");
bool supportsFifoRelaxed = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_FIFO_RELAXED_KHR) != caps.PresentModes.end();
bool supportsMailbox = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR) != caps.PresentModes.end();
@ -241,7 +241,8 @@ int VulkanSwapChain::AcquireImage(VulkanSemaphore* semaphore, VulkanFence* fence
}
else
{
throw std::runtime_error("Failed to acquire next image!");
VulkanError("Failed to acquire next image!");
return -1;
}
}
@ -270,15 +271,15 @@ void VulkanSwapChain::QueuePresent(int imageIndex, VulkanSemaphore* semaphore)
// The spec says we can recover from this.
// However, if we are out of memory it is better to crash now than in some other weird place further away from the source of the problem.
throw std::runtime_error("vkQueuePresentKHR failed: out of memory");
VulkanError("vkQueuePresentKHR failed: out of memory");
}
else if (result == VK_ERROR_DEVICE_LOST)
{
throw std::runtime_error("vkQueuePresentKHR failed: device lost");
VulkanError("vkQueuePresentKHR failed: device lost");
}
else
{
throw std::runtime_error("vkQueuePresentKHR failed");
VulkanError("vkQueuePresentKHR failed");
}
}
@ -332,7 +333,7 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
VkResult result = vkGetPhysicalDeviceSurfaceCapabilities2KHR(device->PhysicalDevice.Device, &surfaceInfo, &caps2);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilities2KHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceCapabilities2KHR failed");
caps.Capabilites = caps2.surfaceCapabilities;
}
@ -340,7 +341,7 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
{
VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &caps.Capabilites);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed");
}
#ifdef WIN32
@ -351,14 +352,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
uint32_t presentModeCount = 0;
VkResult result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed");
VulkanError("vkGetPhysicalDeviceSurfacePresentModes2EXT failed");
if (presentModeCount > 0)
{
caps.PresentModes.resize(presentModeCount);
result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, caps.PresentModes.data());
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed");
VulkanError("vkGetPhysicalDeviceSurfacePresentModes2EXT failed");
}
}
else
@ -367,14 +368,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
uint32_t presentModeCount = 0;
VkResult result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed");
VulkanError("vkGetPhysicalDeviceSurfacePresentModesKHR failed");
if (presentModeCount > 0)
{
caps.PresentModes.resize(presentModeCount);
result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, caps.PresentModes.data());
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed");
VulkanError("vkGetPhysicalDeviceSurfacePresentModesKHR failed");
}
}
@ -383,14 +384,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
uint32_t surfaceFormatCount = 0;
VkResult result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceFormats2KHR failed");
if (surfaceFormatCount > 0)
{
std::vector<VkSurfaceFormat2KHR> formats(surfaceFormatCount, { VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR });
result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, formats.data());
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceFormats2KHR failed");
for (VkSurfaceFormat2KHR& fmt : formats)
caps.Formats.push_back(fmt.surfaceFormat);
@ -401,14 +402,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive
uint32_t surfaceFormatCount = 0;
VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceFormatsKHR failed");
if (surfaceFormatCount > 0)
{
caps.Formats.resize(surfaceFormatCount);
result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, caps.Formats.data());
if (result != VK_SUCCESS)
throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed");
VulkanError("vkGetPhysicalDeviceSurfaceFormatsKHR failed");
}
}