Add Vulkan quad integration path
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "XCEngine/RHI/RHIEnums.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -245,6 +246,162 @@ inline VkSampleCountFlagBits ToVulkanSampleCount(uint32_t sampleCount) {
|
||||
}
|
||||
}
|
||||
|
||||
inline VkDescriptorType ToVulkanDescriptorType(DescriptorType type) {
|
||||
switch (type) {
|
||||
case DescriptorType::CBV:
|
||||
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
case DescriptorType::SRV:
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
case DescriptorType::UAV:
|
||||
return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
case DescriptorType::Sampler:
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
default:
|
||||
return VK_DESCRIPTOR_TYPE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkShaderStageFlags ToVulkanShaderStageFlags(uint32_t visibility) {
|
||||
switch (static_cast<ShaderVisibility>(visibility)) {
|
||||
case ShaderVisibility::Vertex:
|
||||
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
case ShaderVisibility::Geometry:
|
||||
return VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
case ShaderVisibility::Pixel:
|
||||
return VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
case ShaderVisibility::Amplification:
|
||||
case ShaderVisibility::Mesh:
|
||||
case ShaderVisibility::Hull:
|
||||
case ShaderVisibility::Domain:
|
||||
case ShaderVisibility::All:
|
||||
default:
|
||||
return VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkFilter ToVulkanMinFilter(FilterMode filter) {
|
||||
switch (filter) {
|
||||
case FilterMode::Point:
|
||||
case FilterMode::ComparisonPoint:
|
||||
case FilterMode::MinimumPoint:
|
||||
case FilterMode::MaximumPoint:
|
||||
return VK_FILTER_NEAREST;
|
||||
default:
|
||||
return VK_FILTER_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkFilter ToVulkanMagFilter(FilterMode filter) {
|
||||
switch (filter) {
|
||||
case FilterMode::Point:
|
||||
case FilterMode::ComparisonPoint:
|
||||
case FilterMode::MinimumPoint:
|
||||
case FilterMode::MaximumPoint:
|
||||
return VK_FILTER_NEAREST;
|
||||
default:
|
||||
return VK_FILTER_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkSamplerMipmapMode ToVulkanSamplerMipmapMode(FilterMode filter) {
|
||||
switch (filter) {
|
||||
case FilterMode::Point:
|
||||
case FilterMode::ComparisonPoint:
|
||||
case FilterMode::MinimumPoint:
|
||||
case FilterMode::MaximumPoint:
|
||||
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
default:
|
||||
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool UsesVulkanSamplerAnisotropy(FilterMode filter) {
|
||||
return filter == FilterMode::Anisotropic ||
|
||||
filter == FilterMode::ComparisonAnisotropic ||
|
||||
filter == FilterMode::MinimumAnisotropic ||
|
||||
filter == FilterMode::MaximumAnisotropic;
|
||||
}
|
||||
|
||||
inline bool UsesVulkanComparisonSampling(FilterMode filter) {
|
||||
return filter == FilterMode::ComparisonPoint ||
|
||||
filter == FilterMode::ComparisonLinear ||
|
||||
filter == FilterMode::ComparisonAnisotropic;
|
||||
}
|
||||
|
||||
inline VkSamplerAddressMode ToVulkanSamplerAddressMode(TextureAddressMode mode) {
|
||||
switch (mode) {
|
||||
case TextureAddressMode::Wrap:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
case TextureAddressMode::Mirror:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
case TextureAddressMode::Clamp:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
case TextureAddressMode::Border:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
case TextureAddressMode::MirrorOnce:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
default:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkBorderColor ToVulkanBorderColor(float r, float g, float b, float a) {
|
||||
const bool opaqueBlack = std::fabs(r) < 0.0001f &&
|
||||
std::fabs(g) < 0.0001f &&
|
||||
std::fabs(b) < 0.0001f &&
|
||||
std::fabs(a - 1.0f) < 0.0001f;
|
||||
if (opaqueBlack) {
|
||||
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
}
|
||||
|
||||
const bool opaqueWhite = std::fabs(r - 1.0f) < 0.0001f &&
|
||||
std::fabs(g - 1.0f) < 0.0001f &&
|
||||
std::fabs(b - 1.0f) < 0.0001f &&
|
||||
std::fabs(a - 1.0f) < 0.0001f;
|
||||
if (opaqueWhite) {
|
||||
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
}
|
||||
|
||||
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
}
|
||||
|
||||
inline VkImageViewType ToVulkanImageViewType(ResourceViewDimension dimension, TextureType textureType) {
|
||||
switch (dimension) {
|
||||
case ResourceViewDimension::Texture1D:
|
||||
return VK_IMAGE_VIEW_TYPE_1D;
|
||||
case ResourceViewDimension::Texture1DArray:
|
||||
return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
case ResourceViewDimension::Texture2DArray:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
case ResourceViewDimension::Texture3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
case ResourceViewDimension::TextureCube:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
case ResourceViewDimension::TextureCubeArray:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
case ResourceViewDimension::Texture2D:
|
||||
case ResourceViewDimension::Unknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (textureType) {
|
||||
case TextureType::Texture1D:
|
||||
return VK_IMAGE_VIEW_TYPE_1D;
|
||||
case TextureType::Texture2DArray:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
case TextureType::Texture3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
case TextureType::TextureCube:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
case TextureType::TextureCubeArray:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
case TextureType::Texture2D:
|
||||
default:
|
||||
return VK_IMAGE_VIEW_TYPE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t ResolveVulkanApiMajor(uint32_t apiVersion) {
|
||||
return VK_API_VERSION_MAJOR(apiVersion);
|
||||
}
|
||||
|
||||
42
engine/include/XCEngine/RHI/Vulkan/VulkanDescriptorPool.h
Normal file
42
engine/include/XCEngine/RHI/Vulkan/VulkanDescriptorPool.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCEngine/RHI/RHIDescriptorPool.h"
|
||||
#include "XCEngine/RHI/Vulkan/VulkanCommon.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class VulkanDescriptorSet;
|
||||
|
||||
class VulkanDescriptorPool : public RHIDescriptorPool {
|
||||
public:
|
||||
VulkanDescriptorPool() = default;
|
||||
~VulkanDescriptorPool() override;
|
||||
|
||||
bool Initialize(VkDevice device, const DescriptorPoolDesc& desc);
|
||||
bool Initialize(const DescriptorPoolDesc& desc) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void* GetNativeHandle() override { return m_descriptorPool; }
|
||||
|
||||
uint32_t GetDescriptorCount() const override { return m_descriptorCount; }
|
||||
DescriptorHeapType GetType() const override { return m_type; }
|
||||
|
||||
RHIDescriptorSet* AllocateSet(const DescriptorSetLayoutDesc& layout) override;
|
||||
void FreeSet(RHIDescriptorSet* set) override;
|
||||
|
||||
VkDevice GetDevice() const { return m_device; }
|
||||
VkDescriptorPool GetDescriptorPool() const { return m_descriptorPool; }
|
||||
|
||||
private:
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkDescriptorPool m_descriptorPool = VK_NULL_HANDLE;
|
||||
DescriptorHeapType m_type = DescriptorHeapType::CBV_SRV_UAV;
|
||||
uint32_t m_descriptorCount = 0;
|
||||
std::vector<VulkanDescriptorSet*> m_allocatedSets;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
63
engine/include/XCEngine/RHI/Vulkan/VulkanDescriptorSet.h
Normal file
63
engine/include/XCEngine/RHI/Vulkan/VulkanDescriptorSet.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCEngine/RHI/RHIDescriptorSet.h"
|
||||
#include "XCEngine/RHI/Vulkan/VulkanCommon.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class VulkanDescriptorPool;
|
||||
|
||||
class VulkanDescriptorSet : public RHIDescriptorSet {
|
||||
public:
|
||||
VulkanDescriptorSet() = default;
|
||||
~VulkanDescriptorSet() override;
|
||||
|
||||
bool Initialize(
|
||||
VkDevice device,
|
||||
VulkanDescriptorPool* pool,
|
||||
VkDescriptorSetLayout layout,
|
||||
VkDescriptorSet descriptorSet,
|
||||
const DescriptorSetLayoutDesc& desc);
|
||||
|
||||
void Shutdown() override;
|
||||
void Bind() override;
|
||||
void Unbind() override;
|
||||
|
||||
void Update(uint32_t offset, RHIResourceView* view) override;
|
||||
void UpdateSampler(uint32_t offset, RHISampler* sampler) override;
|
||||
void WriteConstant(uint32_t binding, const void* data, size_t size, size_t offset = 0) override;
|
||||
|
||||
uint32_t GetBindingCount() const override { return static_cast<uint32_t>(m_bindings.size()); }
|
||||
const DescriptorSetLayoutBinding* GetBindings() const override {
|
||||
return m_bindings.empty() ? nullptr : m_bindings.data();
|
||||
}
|
||||
|
||||
void* GetConstantBufferData() override {
|
||||
return m_constantBufferData.empty() ? nullptr : m_constantBufferData.data();
|
||||
}
|
||||
size_t GetConstantBufferSize() const override { return m_constantBufferData.size(); }
|
||||
bool IsConstantDirty() const override { return m_constantDirty; }
|
||||
void MarkConstantClean() override { m_constantDirty = false; }
|
||||
|
||||
VkDescriptorSet GetDescriptorSet() const { return m_descriptorSet; }
|
||||
VkDescriptorSetLayout GetDescriptorSetLayout() const { return m_descriptorSetLayout; }
|
||||
|
||||
private:
|
||||
const DescriptorSetLayoutBinding* FindBinding(uint32_t binding) const;
|
||||
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VulkanDescriptorPool* m_pool = nullptr;
|
||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_descriptorSet = VK_NULL_HANDLE;
|
||||
std::vector<DescriptorSetLayoutBinding> m_bindings;
|
||||
std::unordered_map<uint32_t, uint32_t> m_bindingToIndex;
|
||||
std::vector<uint8_t> m_constantBufferData;
|
||||
bool m_constantDirty = false;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
40
engine/include/XCEngine/RHI/Vulkan/VulkanPipelineLayout.h
Normal file
40
engine/include/XCEngine/RHI/Vulkan/VulkanPipelineLayout.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCEngine/RHI/RHIPipelineLayout.h"
|
||||
#include "XCEngine/RHI/Vulkan/VulkanCommon.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class VulkanPipelineLayout : public RHIPipelineLayout {
|
||||
public:
|
||||
VulkanPipelineLayout() = default;
|
||||
~VulkanPipelineLayout() override;
|
||||
|
||||
bool Initialize(VkDevice device, const RHIPipelineLayoutDesc& desc);
|
||||
bool Initialize(const RHIPipelineLayoutDesc& desc) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void* GetNativeHandle() override { return m_pipelineLayout; }
|
||||
|
||||
VkPipelineLayout GetPipelineLayout() const { return m_pipelineLayout; }
|
||||
const RHIPipelineLayoutDesc& GetDesc() const { return m_desc; }
|
||||
bool UsesSetLayouts() const { return m_desc.setLayoutCount > 0 && m_desc.setLayouts != nullptr; }
|
||||
|
||||
private:
|
||||
void PrepareExplicitLayouts(const RHIPipelineLayoutDesc& desc);
|
||||
void PrepareFlatLayouts(const RHIPipelineLayoutDesc& desc);
|
||||
bool CreateNativeSetLayouts();
|
||||
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
RHIPipelineLayoutDesc m_desc = {};
|
||||
std::vector<DescriptorSetLayoutDesc> m_setLayouts;
|
||||
std::vector<std::vector<DescriptorSetLayoutBinding>> m_setLayoutBindings;
|
||||
std::vector<VkDescriptorSetLayout> m_nativeSetLayouts;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkRenderPass m_renderPass = VK_NULL_HANDLE;
|
||||
bool m_ownsPipelineLayout = false;
|
||||
InputLayoutDesc m_inputLayoutDesc = {};
|
||||
RasterizerDesc m_rasterizerDesc = {};
|
||||
BlendDesc m_blendDesc = {};
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
~VulkanResourceView() override;
|
||||
|
||||
bool InitializeAsRenderTarget(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc);
|
||||
bool InitializeAsShaderResource(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc);
|
||||
bool InitializeAsVertexBuffer(VulkanBuffer* buffer, const ResourceViewDesc& desc);
|
||||
bool InitializeAsIndexBuffer(VulkanBuffer* buffer, const ResourceViewDesc& desc);
|
||||
|
||||
|
||||
31
engine/include/XCEngine/RHI/Vulkan/VulkanSampler.h
Normal file
31
engine/include/XCEngine/RHI/Vulkan/VulkanSampler.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCEngine/RHI/RHISampler.h"
|
||||
#include "XCEngine/RHI/Vulkan/VulkanCommon.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class VulkanSampler : public RHISampler {
|
||||
public:
|
||||
VulkanSampler() = default;
|
||||
~VulkanSampler() override;
|
||||
|
||||
bool Initialize(VkDevice device, const SamplerDesc& desc);
|
||||
void Shutdown() override;
|
||||
|
||||
void Bind(unsigned int unit) override;
|
||||
void Unbind(unsigned int unit) override;
|
||||
|
||||
void* GetNativeHandle() override { return m_sampler != VK_NULL_HANDLE ? &m_sampler : nullptr; }
|
||||
unsigned int GetID() override { return 0; }
|
||||
|
||||
VkSampler GetSampler() const { return m_sampler; }
|
||||
|
||||
private:
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
@@ -20,13 +20,23 @@ public:
|
||||
uint32_t height,
|
||||
Format format,
|
||||
VkFormat vkFormat);
|
||||
bool InitializeOwnedImage(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
VkDeviceMemory memory,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t mipLevels,
|
||||
Format format,
|
||||
TextureType textureType,
|
||||
VkFormat vkFormat);
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
uint32_t GetWidth() const override { return m_width; }
|
||||
uint32_t GetHeight() const override { return m_height; }
|
||||
uint32_t GetDepth() const override { return 1; }
|
||||
uint32_t GetMipLevels() const override { return 1; }
|
||||
uint32_t GetMipLevels() const override { return m_mipLevels; }
|
||||
Format GetFormat() const override { return m_format; }
|
||||
TextureType GetTextureType() const override { return m_textureType; }
|
||||
|
||||
@@ -39,17 +49,21 @@ public:
|
||||
void SetName(const std::string& name) override { m_name = name; }
|
||||
|
||||
VkImage GetImage() const { return m_image; }
|
||||
VkDeviceMemory GetMemory() const { return m_memory; }
|
||||
VkFormat GetVkFormat() const { return m_vkFormat; }
|
||||
|
||||
private:
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkImage m_image = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_memory = VK_NULL_HANDLE;
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
uint32_t m_mipLevels = 1;
|
||||
Format m_format = Format::Unknown;
|
||||
TextureType m_textureType = TextureType::Texture2D;
|
||||
ResourceStates m_state = ResourceStates::Common;
|
||||
VkFormat m_vkFormat = VK_FORMAT_UNDEFINED;
|
||||
bool m_ownsImage = false;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user