533 lines
21 KiB
C++
533 lines
21 KiB
C++
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
|
// This file is part of the "Nazara Engine - Vulkan renderer"
|
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
|
|
#include <Nazara/Core/Algorithm.hpp>
|
|
#include <Nazara/Core/Error.hpp>
|
|
#include <Nazara/Core/StringExt.hpp>
|
|
#include <Nazara/VulkanRenderer/Debug.hpp>
|
|
|
|
namespace Nz
|
|
{
|
|
inline std::optional<PixelFormat> FromVulkan(VkFormat format)
|
|
{
|
|
switch (format)
|
|
{
|
|
case VK_FORMAT_B8G8R8A8_UNORM: return PixelFormat::BGRA8;
|
|
case VK_FORMAT_B8G8R8A8_SRGB: return PixelFormat::BGRA8_SRGB;
|
|
case VK_FORMAT_D16_UNORM: return PixelFormat::Depth16;
|
|
case VK_FORMAT_D16_UNORM_S8_UINT: return PixelFormat::Depth16Stencil8;
|
|
case VK_FORMAT_D24_UNORM_S8_UINT: return PixelFormat::Depth24Stencil8;
|
|
case VK_FORMAT_D32_SFLOAT: return PixelFormat::Depth32F;
|
|
case VK_FORMAT_D32_SFLOAT_S8_UINT: return PixelFormat::Depth32FStencil8;
|
|
case VK_FORMAT_R8_UNORM: return PixelFormat::R8;
|
|
case VK_FORMAT_R8G8_UNORM: return PixelFormat::RG8;
|
|
case VK_FORMAT_R8G8B8_UNORM: return PixelFormat::RGB8;
|
|
case VK_FORMAT_R8G8B8_SRGB: return PixelFormat::RGB8_SRGB;
|
|
case VK_FORMAT_R8G8B8A8_UNORM: return PixelFormat::RGBA8;
|
|
case VK_FORMAT_R8G8B8A8_SRGB: return PixelFormat::RGBA8_SRGB;
|
|
default: break;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::optional<PresentMode> FromVulkan(VkPresentModeKHR presentMode)
|
|
{
|
|
switch (presentMode)
|
|
{
|
|
case VK_PRESENT_MODE_IMMEDIATE_KHR: return PresentMode::Immediate;
|
|
case VK_PRESENT_MODE_MAILBOX_KHR: return PresentMode::Mailbox;
|
|
case VK_PRESENT_MODE_FIFO_KHR: return PresentMode::VerticalSync;
|
|
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return PresentMode::RelaxedVerticalSync;
|
|
default: break;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
inline VkAttachmentLoadOp ToVulkan(AttachmentLoadOp loadOp)
|
|
{
|
|
switch (loadOp)
|
|
{
|
|
case AttachmentLoadOp::Clear: return VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
case AttachmentLoadOp::Discard: return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
case AttachmentLoadOp::Load: return VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled AttachmentLoadOp {0:#x})", UnderlyingCast(loadOp));
|
|
return {};
|
|
}
|
|
|
|
inline VkAttachmentStoreOp ToVulkan(AttachmentStoreOp storeOp)
|
|
{
|
|
switch (storeOp)
|
|
{
|
|
case AttachmentStoreOp::Discard: return VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
case AttachmentStoreOp::Store: return VK_ATTACHMENT_STORE_OP_STORE;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled AttachmentStoreOp {0:#x})", UnderlyingCast(storeOp));
|
|
return {};
|
|
}
|
|
|
|
inline VkBlendOp ToVulkan(BlendEquation blendEquation)
|
|
{
|
|
switch (blendEquation)
|
|
{
|
|
case BlendEquation::Add: return VK_BLEND_OP_ADD;
|
|
case BlendEquation::Max: return VK_BLEND_OP_MAX;
|
|
case BlendEquation::Min: return VK_BLEND_OP_MIN;
|
|
case BlendEquation::ReverseSubtract: return VK_BLEND_OP_REVERSE_SUBTRACT;
|
|
case BlendEquation::Subtract: return VK_BLEND_OP_SUBTRACT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled BlendEquation {0:#x})", UnderlyingCast(blendEquation));
|
|
return {};
|
|
}
|
|
|
|
inline VkBlendFactor ToVulkan(BlendFunc blendFunc)
|
|
{
|
|
switch (blendFunc)
|
|
{
|
|
case BlendFunc::ConstantAlpha: return VK_BLEND_FACTOR_CONSTANT_ALPHA;
|
|
case BlendFunc::ConstantColor: return VK_BLEND_FACTOR_CONSTANT_COLOR;
|
|
case BlendFunc::DstAlpha: return VK_BLEND_FACTOR_DST_ALPHA;
|
|
case BlendFunc::DstColor: return VK_BLEND_FACTOR_DST_COLOR;
|
|
case BlendFunc::InvConstantAlpha: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
|
|
case BlendFunc::InvConstantColor: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
|
|
case BlendFunc::InvDstAlpha: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
|
|
case BlendFunc::InvDstColor: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
|
|
case BlendFunc::InvSrcAlpha: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
|
case BlendFunc::InvSrcColor: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
|
|
case BlendFunc::SrcAlpha: return VK_BLEND_FACTOR_SRC_ALPHA;
|
|
case BlendFunc::SrcColor: return VK_BLEND_FACTOR_SRC_COLOR;
|
|
case BlendFunc::One: return VK_BLEND_FACTOR_ONE;
|
|
case BlendFunc::Zero: return VK_BLEND_FACTOR_ZERO;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled BlendFunc {0:#x})", UnderlyingCast(blendFunc));
|
|
return {};
|
|
}
|
|
|
|
inline VkBufferUsageFlags ToVulkan(BufferType bufferType)
|
|
{
|
|
switch (bufferType)
|
|
{
|
|
case BufferType::Index: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
case BufferType::Storage: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
|
case BufferType::Vertex: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
case BufferType::Uniform: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
|
case BufferType::Upload: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled BufferType {0:#x})", UnderlyingCast(bufferType));
|
|
return 0;
|
|
}
|
|
|
|
inline VkFormat ToVulkan(ComponentType componentType)
|
|
{
|
|
switch (componentType)
|
|
{
|
|
case ComponentType::Color: return VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
case ComponentType::Double1: return VK_FORMAT_R64_SFLOAT;
|
|
case ComponentType::Double2: return VK_FORMAT_R64G64_SFLOAT;
|
|
case ComponentType::Double3: return VK_FORMAT_R64G64B64_SFLOAT;
|
|
case ComponentType::Double4: return VK_FORMAT_R64G64B64A64_SFLOAT;
|
|
case ComponentType::Float1: return VK_FORMAT_R32_SFLOAT;
|
|
case ComponentType::Float2: return VK_FORMAT_R32G32_SFLOAT;
|
|
case ComponentType::Float3: return VK_FORMAT_R32G32B32_SFLOAT;
|
|
case ComponentType::Float4: return VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
case ComponentType::Int1: return VK_FORMAT_R32_SINT;
|
|
case ComponentType::Int2: return VK_FORMAT_R32G32_SINT;
|
|
case ComponentType::Int3: return VK_FORMAT_R32G32B32_SINT;
|
|
case ComponentType::Int4: return VK_FORMAT_R32G32B32A32_SINT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled ComponentType {0:#x})", UnderlyingCast(componentType));
|
|
return VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
inline VkCullModeFlagBits ToVulkan(FaceCulling faceSide)
|
|
{
|
|
switch (faceSide)
|
|
{
|
|
case FaceCulling::None: return VK_CULL_MODE_NONE;
|
|
case FaceCulling::Back: return VK_CULL_MODE_BACK_BIT;
|
|
case FaceCulling::Front: return VK_CULL_MODE_FRONT_BIT;
|
|
case FaceCulling::FrontAndBack: return VK_CULL_MODE_FRONT_AND_BACK;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled FaceSide {0:#x})", UnderlyingCast(faceSide));
|
|
return VK_CULL_MODE_BACK_BIT;
|
|
}
|
|
|
|
inline VkPolygonMode ToVulkan(FaceFilling faceFilling)
|
|
{
|
|
switch (faceFilling)
|
|
{
|
|
case FaceFilling::Fill: return VK_POLYGON_MODE_FILL;
|
|
case FaceFilling::Line: return VK_POLYGON_MODE_LINE;
|
|
case FaceFilling::Point: return VK_POLYGON_MODE_POINT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled FaceFilling {0:#x})", UnderlyingCast(faceFilling));
|
|
return VK_POLYGON_MODE_FILL;
|
|
}
|
|
|
|
inline VkFrontFace ToVulkan(FrontFace frontFace)
|
|
{
|
|
switch (frontFace)
|
|
{
|
|
case FrontFace::Clockwise: return VK_FRONT_FACE_CLOCKWISE;
|
|
case FrontFace::CounterClockwise: return VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled FrontFace {0:#x})", UnderlyingCast(frontFace));
|
|
return {};
|
|
}
|
|
|
|
inline VkIndexType ToVulkan(IndexType indexType)
|
|
{
|
|
switch (indexType)
|
|
{
|
|
case IndexType::U8: return VK_INDEX_TYPE_UINT8_EXT;
|
|
case IndexType::U16: return VK_INDEX_TYPE_UINT16;
|
|
case IndexType::U32: return VK_INDEX_TYPE_UINT32;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled IndexType {0:#x})", UnderlyingCast(indexType));
|
|
return {};
|
|
}
|
|
|
|
inline VkAccessFlagBits ToVulkan(MemoryAccess memoryAccess)
|
|
{
|
|
switch (memoryAccess)
|
|
{
|
|
case MemoryAccess::ColorRead: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
|
case MemoryAccess::ColorWrite: return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
case MemoryAccess::DepthStencilRead: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
|
case MemoryAccess::DepthStencilWrite: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
case MemoryAccess::IndexBufferRead: return VK_ACCESS_INDEX_READ_BIT;
|
|
case MemoryAccess::IndirectCommandRead: return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
|
case MemoryAccess::HostRead: return VK_ACCESS_HOST_READ_BIT;
|
|
case MemoryAccess::HostWrite: return VK_ACCESS_HOST_WRITE_BIT;
|
|
case MemoryAccess::MemoryRead: return VK_ACCESS_MEMORY_READ_BIT;
|
|
case MemoryAccess::MemoryWrite: return VK_ACCESS_MEMORY_WRITE_BIT;
|
|
case MemoryAccess::ShaderRead: return VK_ACCESS_SHADER_READ_BIT;
|
|
case MemoryAccess::ShaderWrite: return VK_ACCESS_SHADER_WRITE_BIT;
|
|
case MemoryAccess::TransferRead: return VK_ACCESS_TRANSFER_READ_BIT;
|
|
case MemoryAccess::TransferWrite: return VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
case MemoryAccess::UniformBufferRead: return VK_ACCESS_UNIFORM_READ_BIT;
|
|
case MemoryAccess::VertexBufferRead: return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled MemoryAccess {0:#x})", UnderlyingCast(memoryAccess));
|
|
return {};
|
|
}
|
|
|
|
inline VkAccessFlags ToVulkan(MemoryAccessFlags memoryAccessFlags)
|
|
{
|
|
VkShaderStageFlags accessBits = 0;
|
|
for (MemoryAccess memoryAccess : memoryAccessFlags)
|
|
accessBits |= ToVulkan(memoryAccess);
|
|
|
|
return accessBits;
|
|
}
|
|
|
|
inline VkPipelineStageFlagBits ToVulkan(PipelineStage pipelineStage)
|
|
{
|
|
switch (pipelineStage)
|
|
{
|
|
case PipelineStage::TopOfPipe: return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
|
case PipelineStage::ColorOutput: return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
case PipelineStage::ComputeShader: return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
case PipelineStage::DrawIndirect: return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
|
case PipelineStage::FragmentShader: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
case PipelineStage::FragmentTestsEarly: return VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
|
case PipelineStage::FragmentTestsLate: return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
|
case PipelineStage::GeometryShader: return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
|
case PipelineStage::TessellationControlShader: return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
|
|
case PipelineStage::TessellationEvaluationShader: return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
|
|
case PipelineStage::Transfer: return VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
case PipelineStage::TransformFeedback: return VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
|
case PipelineStage::VertexInput: return VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
|
case PipelineStage::VertexShader: return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
|
|
case PipelineStage::BottomOfPipe: return VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled PipelineStage {0:#x})", UnderlyingCast(pipelineStage));
|
|
return {};
|
|
}
|
|
|
|
inline VkPipelineStageFlags ToVulkan(PipelineStageFlags pipelineStages)
|
|
{
|
|
VkShaderStageFlags pipelineStageBits = 0;
|
|
for (PipelineStage pipelineStage : pipelineStages)
|
|
pipelineStageBits |= ToVulkan(pipelineStage);
|
|
|
|
return pipelineStageBits;
|
|
}
|
|
|
|
inline VkFormat ToVulkan(PixelFormat pixelFormat)
|
|
{
|
|
switch (pixelFormat)
|
|
{
|
|
// TODO: Fill this switch
|
|
case PixelFormat::BGR8: return VK_FORMAT_B8G8R8_UNORM;
|
|
case PixelFormat::BGR8_SRGB: return VK_FORMAT_B8G8R8_SRGB;
|
|
case PixelFormat::BGRA8: return VK_FORMAT_B8G8R8A8_UNORM;
|
|
case PixelFormat::BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
|
|
case PixelFormat::Depth16: return VK_FORMAT_D16_UNORM;
|
|
case PixelFormat::Depth16Stencil8: return VK_FORMAT_D16_UNORM_S8_UINT;
|
|
case PixelFormat::Depth24: return VK_FORMAT_UNDEFINED;
|
|
case PixelFormat::Depth24Stencil8: return VK_FORMAT_D24_UNORM_S8_UINT;
|
|
case PixelFormat::Depth32F: return VK_FORMAT_D32_SFLOAT;
|
|
case PixelFormat::Depth32FStencil8: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
|
case PixelFormat::R8: return VK_FORMAT_R8_UNORM;
|
|
case PixelFormat::RG8: return VK_FORMAT_R8G8_UNORM;
|
|
case PixelFormat::RGB8: return VK_FORMAT_R8G8B8_UNORM;
|
|
case PixelFormat::RGB8_SRGB: return VK_FORMAT_R8G8B8_SRGB;
|
|
case PixelFormat::RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
|
|
case PixelFormat::RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
|
|
case PixelFormat::RGBA16F: return VK_FORMAT_R16G16B16A16_SFLOAT;
|
|
case PixelFormat::RGBA32F: return VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
case PixelFormat::Stencil1: return VK_FORMAT_UNDEFINED;
|
|
case PixelFormat::Stencil4: return VK_FORMAT_UNDEFINED;
|
|
case PixelFormat::Stencil8: return VK_FORMAT_S8_UINT;
|
|
case PixelFormat::Stencil16: return VK_FORMAT_UNDEFINED;
|
|
default: break;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled PixelFormat {0:#x})", UnderlyingCast(pixelFormat));
|
|
return VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
VkImageAspectFlags ToVulkan(PixelFormatContent pixelFormatContent)
|
|
{
|
|
switch (pixelFormatContent)
|
|
{
|
|
case PixelFormatContent::Undefined:
|
|
break;
|
|
|
|
case PixelFormatContent::ColorRGBA: return VK_IMAGE_ASPECT_COLOR_BIT;
|
|
case PixelFormatContent::Depth: return VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
case PixelFormatContent::DepthStencil: return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
case PixelFormatContent::Stencil: return VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled PixelFormatContent {0:#x})", UnderlyingCast(pixelFormatContent));
|
|
return VK_IMAGE_ASPECT_COLOR_BIT;
|
|
}
|
|
|
|
VkPresentModeKHR ToVulkan(PresentMode presentMode)
|
|
{
|
|
switch (presentMode)
|
|
{
|
|
case PresentMode::Immediate: return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
|
case PresentMode::Mailbox: return VK_PRESENT_MODE_MAILBOX_KHR;
|
|
case PresentMode::RelaxedVerticalSync: return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
|
case PresentMode::VerticalSync: return VK_PRESENT_MODE_FIFO_KHR;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled PresentMode {0:#x})", UnderlyingCast(presentMode));
|
|
return VK_PRESENT_MODE_FIFO_KHR;
|
|
}
|
|
|
|
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode)
|
|
{
|
|
switch (primitiveMode)
|
|
{
|
|
case PrimitiveMode::LineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
|
case PrimitiveMode::LineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
|
case PrimitiveMode::PointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
|
case PrimitiveMode::TriangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
case PrimitiveMode::TriangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
|
case PrimitiveMode::TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled PrimitiveMode {0:#x})", UnderlyingCast(primitiveMode));
|
|
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
}
|
|
|
|
inline VkCompareOp ToVulkan(RendererComparison comparison)
|
|
{
|
|
switch (comparison)
|
|
{
|
|
case RendererComparison::Never: return VK_COMPARE_OP_NEVER;
|
|
case RendererComparison::Less: return VK_COMPARE_OP_LESS;
|
|
case RendererComparison::Equal: return VK_COMPARE_OP_EQUAL;
|
|
case RendererComparison::LessOrEqual: return VK_COMPARE_OP_LESS_OR_EQUAL;
|
|
case RendererComparison::Greater: return VK_COMPARE_OP_GREATER;
|
|
case RendererComparison::NotEqual: return VK_COMPARE_OP_NOT_EQUAL;
|
|
case RendererComparison::GreaterOrEqual: return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
|
case RendererComparison::Always: return VK_COMPARE_OP_ALWAYS;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled RendererComparison {0:#x})", UnderlyingCast(comparison));
|
|
return VK_COMPARE_OP_NEVER;
|
|
}
|
|
|
|
inline VkFilter ToVulkan(SamplerFilter samplerFilter)
|
|
{
|
|
switch (samplerFilter)
|
|
{
|
|
case SamplerFilter::Linear: return VK_FILTER_LINEAR;
|
|
case SamplerFilter::Nearest: return VK_FILTER_NEAREST;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled SamplerFilter {0:#x})", UnderlyingCast(samplerFilter));
|
|
return VK_FILTER_NEAREST;
|
|
}
|
|
|
|
inline VkSamplerMipmapMode ToVulkan(SamplerMipmapMode samplerMipmap)
|
|
{
|
|
switch (samplerMipmap)
|
|
{
|
|
case SamplerMipmapMode::Linear: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
|
case SamplerMipmapMode::Nearest: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled SamplerMipmapMode {0:#x})", UnderlyingCast(samplerMipmap));
|
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
|
}
|
|
|
|
inline VkSamplerAddressMode ToVulkan(SamplerWrap samplerWrap)
|
|
{
|
|
switch (samplerWrap)
|
|
{
|
|
case SamplerWrap::Clamp: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
|
case SamplerWrap::MirroredRepeat: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
|
case SamplerWrap::Repeat: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled SamplerWrap {0:#x})", UnderlyingCast(samplerWrap));
|
|
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
|
}
|
|
|
|
inline VkDescriptorType ToVulkan(ShaderBindingType bindingType)
|
|
{
|
|
switch (bindingType)
|
|
{
|
|
case ShaderBindingType::Sampler: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
case ShaderBindingType::StorageBuffer: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
case ShaderBindingType::Texture: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
case ShaderBindingType::UniformBuffer: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled ShaderBindingType {0:#x})", UnderlyingCast(bindingType));
|
|
return VK_DESCRIPTOR_TYPE_SAMPLER;
|
|
}
|
|
|
|
inline VkShaderStageFlagBits ToVulkan(nzsl::ShaderStageType stageType)
|
|
{
|
|
switch (stageType)
|
|
{
|
|
case nzsl::ShaderStageType::Compute: return VK_SHADER_STAGE_COMPUTE_BIT;
|
|
case nzsl::ShaderStageType::Fragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
case nzsl::ShaderStageType::Vertex: return VK_SHADER_STAGE_VERTEX_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled nzsl::ShaderStageType {0:#x})", UnderlyingCast(stageType));
|
|
return {};
|
|
}
|
|
|
|
inline VkShaderStageFlags ToVulkan(nzsl::ShaderStageTypeFlags stageType)
|
|
{
|
|
VkShaderStageFlags shaderStageBits = 0;
|
|
for (nzsl::ShaderStageType shaderStage : stageType)
|
|
shaderStageBits |= ToVulkan(shaderStage);
|
|
|
|
return shaderStageBits;
|
|
}
|
|
|
|
inline VkStencilOp ToVulkan(StencilOperation stencilOp)
|
|
{
|
|
switch (stencilOp)
|
|
{
|
|
case StencilOperation::Decrement: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
|
|
case StencilOperation::DecrementNoClamp: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
|
|
case StencilOperation::Increment: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
|
|
case StencilOperation::IncrementNoClamp: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
|
|
case StencilOperation::Invert: return VK_STENCIL_OP_INVERT;
|
|
case StencilOperation::Keep: return VK_STENCIL_OP_KEEP;
|
|
case StencilOperation::Replace: return VK_STENCIL_OP_REPLACE;
|
|
case StencilOperation::Zero: return VK_STENCIL_OP_ZERO;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled StencilOperation {0:#x})", UnderlyingCast(stencilOp));
|
|
return {};
|
|
}
|
|
|
|
inline VkImageLayout ToVulkan(TextureLayout textureLayout)
|
|
{
|
|
switch (textureLayout)
|
|
{
|
|
case TextureLayout::ColorInput: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
case TextureLayout::ColorOutput: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
case TextureLayout::DepthStencilReadOnly: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
case TextureLayout::DepthStencilReadWrite: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
case TextureLayout::General: return VK_IMAGE_LAYOUT_GENERAL;
|
|
case TextureLayout::Present: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
case TextureLayout::TransferSource: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
|
case TextureLayout::TransferDestination: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
case TextureLayout::Undefined: return VK_IMAGE_LAYOUT_UNDEFINED;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled TextureLayout {0:#x})", UnderlyingCast(textureLayout));
|
|
return {};
|
|
}
|
|
|
|
inline VkImageUsageFlagBits ToVulkan(TextureUsage textureLayout)
|
|
{
|
|
switch (textureLayout)
|
|
{
|
|
case TextureUsage::ColorAttachment: return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
case TextureUsage::DepthStencilAttachment: return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
case TextureUsage::InputAttachment: return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
|
|
case TextureUsage::ShaderReadWrite: return VK_IMAGE_USAGE_STORAGE_BIT;
|
|
case TextureUsage::ShaderSampling: return VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
case TextureUsage::TransferSource: return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
|
case TextureUsage::TransferDestination: return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled TextureUsage {0:#x})", UnderlyingCast(textureLayout));
|
|
return {};
|
|
}
|
|
|
|
inline VkImageUsageFlags ToVulkan(TextureUsageFlags textureLayout)
|
|
{
|
|
VkImageUsageFlags imageUsageBits = 0;
|
|
for (TextureUsage textureUsage : textureLayout)
|
|
imageUsageBits |= ToVulkan(textureUsage);
|
|
|
|
return imageUsageBits;
|
|
}
|
|
|
|
inline VkVertexInputRate ToVulkan(VertexInputRate inputRate)
|
|
{
|
|
switch (inputRate)
|
|
{
|
|
case VertexInputRate::Instance: return VK_VERTEX_INPUT_RATE_INSTANCE;
|
|
case VertexInputRate::Vertex: return VK_VERTEX_INPUT_RATE_VERTEX;
|
|
}
|
|
|
|
NazaraErrorFmt("unhandled VertexInputRate {0:#x})", UnderlyingCast(inputRate));
|
|
return {};
|
|
}
|
|
|
|
template<typename T>
|
|
UInt64 VulkanHandleToInteger(T handle)
|
|
{
|
|
if constexpr (std::is_pointer_v<T>)
|
|
return static_cast<UInt64>(BitCast<std::uintptr_t>(handle));
|
|
else
|
|
{
|
|
static_assert(std::is_integral_v<T>);
|
|
return static_cast<UInt64>(handle);
|
|
}
|
|
}
|
|
}
|
|
|
|
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|