initial commit
This commit is contained in:
275
source/util/vkutil.cpp
Normal file
275
source/util/vkutil.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
|
||||
#include "iwa/util/vkutil.hpp"
|
||||
|
||||
#include "iwa/device.hpp"
|
||||
#include "iwa/log.hpp"
|
||||
|
||||
namespace iwa
|
||||
{
|
||||
unsigned vkFormatSize(vk::Format format) noexcept
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
// 8 bit integer
|
||||
case vk::Format::eR8Uint:
|
||||
case vk::Format::eR8Sint:
|
||||
case vk::Format::eR8Unorm:
|
||||
case vk::Format::eR8Srgb:
|
||||
return 1;
|
||||
case vk::Format::eR8G8Uint:
|
||||
case vk::Format::eR8G8Sint:
|
||||
case vk::Format::eR8G8Unorm:
|
||||
case vk::Format::eR8G8Srgb:
|
||||
return 2;
|
||||
case vk::Format::eR8G8B8Uint:
|
||||
case vk::Format::eR8G8B8Sint:
|
||||
case vk::Format::eR8G8B8Unorm:
|
||||
case vk::Format::eR8G8B8Srgb:
|
||||
return 3;
|
||||
case vk::Format::eR8G8B8A8Uint:
|
||||
case vk::Format::eR8G8B8A8Sint:
|
||||
case vk::Format::eR8G8B8A8Unorm:
|
||||
case vk::Format::eR8G8B8A8Srgb:
|
||||
return 4;
|
||||
// 16 bit integer
|
||||
case vk::Format::eR16Uint:
|
||||
case vk::Format::eR16Sint:
|
||||
case vk::Format::eR16Unorm:
|
||||
return 2;
|
||||
case vk::Format::eR16G16Uint:
|
||||
case vk::Format::eR16G16Sint:
|
||||
case vk::Format::eR16G16Unorm:
|
||||
return 4;
|
||||
case vk::Format::eR16G16B16Uint:
|
||||
case vk::Format::eR16G16B16Sint:
|
||||
case vk::Format::eR16G16B16Unorm:
|
||||
return 6;
|
||||
case vk::Format::eR16G16B16A16Uint:
|
||||
case vk::Format::eR16G16B16A16Sint:
|
||||
case vk::Format::eR16G16B16A16Unorm:
|
||||
return 8;
|
||||
// 32 bit integer
|
||||
case vk::Format::eR32Uint:
|
||||
case vk::Format::eR32Sint:
|
||||
return 4;
|
||||
case vk::Format::eR32G32Uint:
|
||||
case vk::Format::eR32G32Sint:
|
||||
return 8;
|
||||
case vk::Format::eR32G32B32Uint:
|
||||
case vk::Format::eR32G32B32Sint:
|
||||
return 12;
|
||||
case vk::Format::eR32G32B32A32Uint:
|
||||
case vk::Format::eR32G32B32A32Sint:
|
||||
return 16;
|
||||
// 64 bit integer
|
||||
case vk::Format::eR64Uint:
|
||||
case vk::Format::eR64Sint:
|
||||
return 8;
|
||||
case vk::Format::eR64G64Uint:
|
||||
case vk::Format::eR64G64Sint:
|
||||
return 16;
|
||||
case vk::Format::eR64G64B64Uint:
|
||||
case vk::Format::eR64G64B64Sint:
|
||||
return 24;
|
||||
case vk::Format::eR64G64B64A64Uint:
|
||||
case vk::Format::eR64G64B64A64Sint:
|
||||
return 32;
|
||||
// 16 bit float
|
||||
case vk::Format::eR16Sfloat:
|
||||
return 2;
|
||||
case vk::Format::eR16G16Sfloat:
|
||||
return 4;
|
||||
case vk::Format::eR16G16B16Sfloat:
|
||||
return 6;
|
||||
case vk::Format::eR16G16B16A16Sfloat:
|
||||
return 8;
|
||||
// 32 bit float
|
||||
case vk::Format::eR32Sfloat:
|
||||
return 4;
|
||||
case vk::Format::eR32G32Sfloat:
|
||||
return 8;
|
||||
case vk::Format::eR32G32B32Sfloat:
|
||||
return 12;
|
||||
case vk::Format::eR32G32B32A32Sfloat:
|
||||
return 16;
|
||||
// 64 bit float
|
||||
case vk::Format::eR64Sfloat:
|
||||
return 8;
|
||||
case vk::Format::eR64G64Sfloat:
|
||||
return 16;
|
||||
case vk::Format::eR64G64B64Sfloat:
|
||||
return 24;
|
||||
case vk::Format::eR64G64B64A64Sfloat:
|
||||
return 32;
|
||||
default:
|
||||
logAndDie("I've never seen this format :(");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vkIndexTypeSize(vk::IndexType indexType) noexcept
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case vk::IndexType::eNoneKHR:
|
||||
return 0;
|
||||
case vk::IndexType::eUint8EXT:
|
||||
return 1;
|
||||
case vk::IndexType::eUint16:
|
||||
return 2;
|
||||
case vk::IndexType::eUint32:
|
||||
return 4;
|
||||
default:
|
||||
logAndDie("What is this sorcery?");
|
||||
}
|
||||
}
|
||||
|
||||
bool isDepthFormat(vk::Format format) noexcept
|
||||
{
|
||||
for (const vk::Format depthFormat : DEPTH_FORMATS) {
|
||||
if (format == depthFormat) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isStencilFormat(vk::Format format) noexcept
|
||||
{
|
||||
for (const vk::Format stencilFormat : STENCIL_FORMATS) {
|
||||
if (format == stencilFormat) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::string formatVkVariant(const VkVariantMWN& variant)
|
||||
{
|
||||
switch (variant.type)
|
||||
{
|
||||
case VK_VARIANT_TYPE_UNKNOWN_MWN:
|
||||
return "???";
|
||||
case VK_VARIANT_TYPE_NONE_MWN:
|
||||
return "<none>";
|
||||
case VK_VARIANT_TYPE_BOOL_MWN:
|
||||
return variant.uintValue ? "true" : "false";
|
||||
case VK_VARIANT_TYPE_UINT8_MWN:
|
||||
case VK_VARIANT_TYPE_UINT16_MWN:
|
||||
case VK_VARIANT_TYPE_UINT32_MWN:
|
||||
case VK_VARIANT_TYPE_UINT64_MWN:
|
||||
return std::to_string(variant.uintValue);
|
||||
case VK_VARIANT_TYPE_INT8_MWN:
|
||||
case VK_VARIANT_TYPE_INT16_MWN:
|
||||
case VK_VARIANT_TYPE_INT32_MWN:
|
||||
case VK_VARIANT_TYPE_INT64_MWN:
|
||||
return std::to_string(variant.intValue);
|
||||
case VK_VARIANT_TYPE_FLOAT_MWN:
|
||||
case VK_VARIANT_TYPE_DOUBLE_MWN:
|
||||
return std::to_string(variant.doubleValue);
|
||||
case VK_VARIANT_TYPE_STRING_MWN:
|
||||
return fmt::format("\"{}\"", variant.stringValue);
|
||||
case VK_VARIANT_TYPE_VOID_POINTER_MWN:
|
||||
return fmt::format("{}", fmt::ptr(variant.voidPointerValue)); // TODO: this doesnt make sense, store the original pointer!
|
||||
case VK_VARIANT_TYPE_POINTER_MWN:
|
||||
return fmt::format("{}", fmt::ptr(variant.pointerValue)); // TODO: this doesnt make sense, store the original pointer!
|
||||
case VK_VARIANT_TYPE_ARRAY_MWN:
|
||||
return fmt::format("<array of {}>", variant.arrayValue.numElements);
|
||||
case VK_VARIANT_TYPE_IN_STRUCTURE_MWN:
|
||||
return "<in struct>";
|
||||
case VK_VARIANT_TYPE_OUT_STRUCTURE_MWN:
|
||||
return "<out struct>";
|
||||
case VK_VARIANT_TYPE_OBJECT_MWN:
|
||||
return "<handle>";
|
||||
default:
|
||||
assert(0);
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
std::size_t calcVkStructHash(const void* structure, std::size_t appendTo)
|
||||
{
|
||||
if (structure == nullptr) {
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
const vk::BaseInStructure* inStruct = static_cast<const vk::BaseInStructure*>(structure);
|
||||
|
||||
std::size_t hash = appendTo;
|
||||
switch (inStruct->sType)
|
||||
{
|
||||
case vk::StructureType::eDescriptorSetLayoutBindingFlagsCreateInfo: {
|
||||
const auto& flagsInfo = *static_cast<const vk::DescriptorSetLayoutBindingFlagsCreateInfo*>(structure);
|
||||
for (std::uint32_t bindingIdx = 0; bindingIdx < flagsInfo.bindingCount; ++bindingIdx) {
|
||||
hash = calcCrcSizeAppend(flagsInfo.pBindingFlags[bindingIdx], hash);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false); // missing struct here, bad
|
||||
break;
|
||||
}
|
||||
|
||||
return calcVkStructHash(inStruct->pNext, hash);
|
||||
}
|
||||
#endif
|
||||
|
||||
vk::SampleCountFlagBits samplesToVk(unsigned samples) noexcept
|
||||
{
|
||||
switch (samples)
|
||||
{
|
||||
case 1:
|
||||
return vk::SampleCountFlagBits::e1;
|
||||
case 2:
|
||||
return vk::SampleCountFlagBits::e2;
|
||||
case 4:
|
||||
return vk::SampleCountFlagBits::e4;
|
||||
case 8:
|
||||
return vk::SampleCountFlagBits::e8;
|
||||
case 16:
|
||||
return vk::SampleCountFlagBits::e16;
|
||||
case 32:
|
||||
return vk::SampleCountFlagBits::e32;
|
||||
case 64:
|
||||
return vk::SampleCountFlagBits::e64;
|
||||
default:
|
||||
logAndDie("Invalid sample count: {}.", samples);
|
||||
}
|
||||
}
|
||||
|
||||
vk::Format detectDepthBufferFormat(Device& device, unsigned samples) noexcept
|
||||
{
|
||||
const vk::SampleCountFlagBits sampleCount = samplesToVk(samples);
|
||||
for (const vk::Format depthFormat : DEPTH_FORMATS)
|
||||
{
|
||||
try
|
||||
{
|
||||
const vk::ImageFormatProperties props = device.getVkPhysicalDevice().getImageFormatProperties(depthFormat, vk::ImageType::e2D, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eDepthStencilAttachment);
|
||||
if (props.sampleCounts & sampleCount) {
|
||||
return depthFormat;
|
||||
}
|
||||
}
|
||||
catch(vk::FormatNotSupportedError&)
|
||||
{
|
||||
continue; // not supported
|
||||
}
|
||||
}
|
||||
return vk::Format::eUndefined;
|
||||
}
|
||||
|
||||
std::vector<unsigned> detectSupportedSampleCounts(Device& device) noexcept
|
||||
{
|
||||
std::vector<unsigned> result = {1};
|
||||
|
||||
for (const unsigned samples : {2, 4, 8, 16, 32, 64})
|
||||
{
|
||||
if (detectDepthBufferFormat(device, samples) != vk::Format::eUndefined) {
|
||||
result.push_back(samples);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace iwa
|
||||
Reference in New Issue
Block a user