Skip to content

Commit

Permalink
RHI
Browse files Browse the repository at this point in the history
  • Loading branch information
Daethalus committed May 1, 2024
1 parent 2297aa1 commit dd4ed5f
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 24 deletions.
163 changes: 142 additions & 21 deletions Engine/Source/Fyrion/Graphics/Device/Vulkan/VulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,28 +615,84 @@ namespace Fyrion
Array<VkImageView> imageViews{};
VkAttachmentReference depthReference{};

vulkanRenderPass->clearValues.Resize(renderPassCreation.attachments.Size());
bool hasDepth = false;
Extent3D framebufferSize{};

for (u32 i = 0; i < renderPassCreation.attachments.Size(); ++i)
{
const AttachmentCreation& attachment = renderPassCreation.attachments[i];
VulkanTexture* vulkanTexture = static_cast<VulkanTexture*>(attachment.texture.handler);
FY_ASSERT(vulkanTexture, "texture not provided");
vulkanRenderPass->clearValues.Resize(renderPassCreation.attachments.Size());

//imageViews.EmplaceBack(static_cast<VulkanTextureView*>(vulkanTexture->textureView.handler)->imageView);
for (int i = 0; i < renderPassCreation.attachments.Size(); ++i)
{
const AttachmentCreation& attachment = renderPassCreation.attachments[i];

VulkanTexture* vulkanTexture = static_cast<VulkanTexture*>(attachment.texture.handler);
FY_ASSERT(vulkanTexture, "texture is mandatory");

imageViews.EmplaceBack(static_cast<VulkanTextureView*>(vulkanTexture->textureView.handler)->imageView);

VkFormat format = Vulkan::CastFormat(vulkanTexture->creation.format);
framebufferSize = vulkanTexture->creation.extent;
bool isDepthFormat = Vulkan::IsDepthFormat(format);

VkAttachmentDescription attachmentDescription{};
attachmentDescription.format = format;
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;

attachmentDescription.loadOp = Vulkan::CastLoadOp(attachment.loadOp);
attachmentDescription.storeOp = Vulkan::CastStoreOp(attachment.storeOp);

attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;

attachmentDescription.initialLayout = Vulkan::CastLayout(attachment.initialLayout);

if (!isDepthFormat)
{
attachmentDescription.finalLayout = Vulkan::CastLayout(attachment.finalLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkAttachmentReference reference{};
reference.attachment = i;
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachmentReference.EmplaceBack(reference);
}
else
{
attachmentDescription.finalLayout = Vulkan::CastLayout(attachment.finalLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthReference.attachment = i;
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
hasDepth = true;
}
attachmentDescriptions.EmplaceBack(attachmentDescription);
}

// VkFormat format = Vulkan::CastFormat(vulkanTexture->textureCreation.format);
// framebufferSize = vulkanTexture->textureCreation.extent;
// bool isDepthFormat = IsDepthFormat(format);
}
vulkanRenderPass->extent = {framebufferSize.height, framebufferSize.width};

VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
renderPassInfo.attachmentCount = attachmentDescriptions.Size();
renderPassInfo.pAttachments = attachmentDescriptions.Data();
renderPassInfo.subpassCount = 1;
// renderPassInfo.pSubpasses = &subPass;
renderPassInfo.dependencyCount = 0;
vkCreateRenderPass(device, &renderPassInfo, nullptr, &vulkanRenderPass->renderPass);
VkSubpassDescription subPass = {};
subPass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subPass.colorAttachmentCount = colorAttachmentReference.Size();
subPass.pColorAttachments = colorAttachmentReference.Data();
if (hasDepth)
{
subPass.pDepthStencilAttachment = &depthReference;
vulkanRenderPass->hasDepth = true;
}

VkRenderPassCreateInfo renderPassInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
renderPassInfo.attachmentCount = attachmentDescriptions.Size();
renderPassInfo.pAttachments = attachmentDescriptions.Data();
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subPass;
renderPassInfo.dependencyCount = 0;
vkCreateRenderPass(device, &renderPassInfo, nullptr, &vulkanRenderPass->renderPass);

VkFramebufferCreateInfo framebufferCreateInfo{};
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferCreateInfo.renderPass = vulkanRenderPass->renderPass;
framebufferCreateInfo.width = framebufferSize.width;
framebufferCreateInfo.height = framebufferSize.height;
framebufferCreateInfo.layers = std::max(framebufferSize.depth, 1u);
framebufferCreateInfo.attachmentCount = imageViews.Size();
framebufferCreateInfo.pAttachments = imageViews.Data();

vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &vulkanRenderPass->framebuffer);

return {vulkanRenderPass};
}
Expand Down Expand Up @@ -684,7 +740,7 @@ namespace Fyrion
VkImageCreateInfo imageCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = Vulkan::CastFormat(textureCreation.format);
imageCreateInfo.extent = {textureCreation.extent.width, textureCreation.extent.height, std::max(textureCreation.extent.depth, 1u)};
imageCreateInfo.extent = {textureCreation.extent.width, textureCreation.extent.height, Math::Max(textureCreation.extent.depth, 1u)};
imageCreateInfo.mipLevels = textureCreation.mipLevels;
imageCreateInfo.arrayLayers = textureCreation.arrayLayers;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
Expand Down Expand Up @@ -726,12 +782,56 @@ namespace Fyrion

TextureView VulkanDevice::CreateTextureView(const TextureViewCreation& textureViewCreation)
{
return {};
VulkanTextureView* vulkanTextureView = allocator.Alloc<VulkanTextureView>();
vulkanTextureView->texture = textureViewCreation.texture;

VulkanTexture* vulkanTexture = static_cast<VulkanTexture*>(textureViewCreation.texture.handler);

VkImageViewCreateInfo viewCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
viewCreateInfo.viewType = Vulkan::CastViewType(textureViewCreation.viewType);
viewCreateInfo.image = vulkanTexture->image;
viewCreateInfo.format = Vulkan::CastFormat(vulkanTexture->creation.format);
viewCreateInfo.subresourceRange.baseMipLevel = textureViewCreation.baseMipLevel;
viewCreateInfo.subresourceRange.levelCount = textureViewCreation.levelCount;
viewCreateInfo.subresourceRange.baseArrayLayer = textureViewCreation.baseArrayLayer;
viewCreateInfo.subresourceRange.layerCount = textureViewCreation.layerCount;

if (Vulkan::IsDepthFormat(viewCreateInfo.format))
{
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else
{
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}

vkCreateImageView(device, &viewCreateInfo, nullptr, &vulkanTextureView->imageView);

return {vulkanTextureView};
}

Sampler VulkanDevice::CreateSampler(const SamplerCreation& samplerCreation)
{
return {};
VulkanSampler* vulkanSampler = allocator.Alloc<VulkanSampler>();
VkSamplerCreateInfo vkSamplerInfo{};
vkSamplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
vkSamplerInfo.magFilter = Vulkan::CastFilter(samplerCreation.filter);
vkSamplerInfo.minFilter = Vulkan::CastFilter(samplerCreation.filter);
vkSamplerInfo.addressModeU = Vulkan::CastTextureAddressMode(samplerCreation.addressMode);
vkSamplerInfo.addressModeV = vkSamplerInfo.addressModeU;
vkSamplerInfo.addressModeW = vkSamplerInfo.addressModeU;
vkSamplerInfo.anisotropyEnable = samplerCreation.anisotropyEnable;
vkSamplerInfo.maxAnisotropy = vulkanDeviceProperties.limits.maxSamplerAnisotropy;
vkSamplerInfo.borderColor = Vulkan::CasterBorderColor(samplerCreation.borderColor);
vkSamplerInfo.unnormalizedCoordinates = VK_FALSE;
vkSamplerInfo.compareEnable = VK_FALSE;
vkSamplerInfo.compareOp = Vulkan::CastCompareOp(samplerCreation.compareOperator);
vkSamplerInfo.mipmapMode = Vulkan::CastSamplerMipmapMode(samplerCreation.samplerMipmapMode);
vkSamplerInfo.mipLodBias = samplerCreation.mipLodBias;
vkSamplerInfo.minLod = samplerCreation.minLod;
vkSamplerInfo.maxLod = samplerCreation.maxLod;
vkCreateSampler(device, &vkSamplerInfo, nullptr, &vulkanSampler->sampler);
return {vulkanSampler};
}

PipelineState VulkanDevice::CreateGraphicsPipelineState(const GraphicsPipelineCreation& graphicsPipelineCreation)
Expand Down Expand Up @@ -1005,6 +1105,8 @@ namespace Fyrion
void VulkanDevice::DestroyRenderPass(const RenderPass& renderPass)
{
VulkanRenderPass* vulkanRenderPass = static_cast<VulkanRenderPass*>(renderPass.handler);
vkDestroyFramebuffer(device, vulkanRenderPass->framebuffer, nullptr);
vkDestroyRenderPass(device, vulkanRenderPass->renderPass, nullptr);
allocator.DestroyAndFree(vulkanRenderPass);
}

Expand All @@ -1020,14 +1122,33 @@ namespace Fyrion

void VulkanDevice::DestroyTexture(const Texture& texture)
{
VulkanTexture* vulkanTexture = static_cast<VulkanTexture*>(texture.handler);

if (vulkanTexture->textureView.handler)
{
DestroyTextureView(vulkanTexture->textureView);
}

if (vulkanTexture->allocation)
{
vmaDestroyImage(vmaAllocator, vulkanTexture->image, vulkanTexture->allocation);
vulkanTexture->allocation = nullptr;
}
allocator.DestroyAndFree(vulkanTexture);
}

void VulkanDevice::DestroyTextureView(const TextureView& textureView)
{
VulkanTextureView* vulkanTextureView = static_cast<VulkanTextureView*>(textureView.handler);
vkDestroyImageView(device, vulkanTextureView->imageView, nullptr);
allocator.DestroyAndFree(vulkanTextureView);
}

void VulkanDevice::DestroySampler(const Sampler& sampler)
{
VulkanSampler* vulkanSampler = static_cast<VulkanSampler*>(sampler.handler);
vkDestroySampler(device, vulkanSampler->sampler, nullptr);
allocator.DestroyAndFree(vulkanSampler);
}

void VulkanDevice::DestroyGraphicsPipelineState(const PipelineState& pipelineState)
Expand Down
5 changes: 5 additions & 0 deletions Engine/Source/Fyrion/Graphics/Device/Vulkan/VulkanTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ namespace Fyrion
TextureView textureView{};
};

struct VulkanSampler
{
VkSampler sampler{};
};

struct VulkanPipelineState
{
GraphicsPipelineCreation graphicsPipelineCreation{};
Expand Down
95 changes: 94 additions & 1 deletion Engine/Source/Fyrion/Graphics/Device/Vulkan/VulkanUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,101 @@ namespace Fyrion::Vulkan
case ResourceLayout::CopySource: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case ResourceLayout::Present: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
}
FY_ASSERT(false, "vulkan_utils.hpp: castLayout not found");
FY_ASSERT(false, "VulkanUtils.hpp: castLayout not found");
return VK_IMAGE_LAYOUT_UNDEFINED;
}

VkAttachmentLoadOp CastLoadOp(LoadOp loadOp)
{
switch (loadOp)
{
case LoadOp::Load: return VK_ATTACHMENT_LOAD_OP_LOAD;
case LoadOp::Clear: return VK_ATTACHMENT_LOAD_OP_CLEAR;
case LoadOp::DontCare: return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
}
FY_ASSERT(false, "VulkanUtils.hpp: castLoadOp not found");
return VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
}

VkAttachmentStoreOp CastStoreOp(StoreOp storeOp)
{
switch (storeOp)
{
case StoreOp::Store: return VK_ATTACHMENT_STORE_OP_STORE;
case StoreOp::DontCare: return VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
FY_ASSERT(false, "VulkanUtils.hpp: castStoreOp not found");
return VK_ATTACHMENT_STORE_OP_MAX_ENUM;
}

VkImageViewType CastViewType(const ViewType& viewType)
{
switch(viewType)
{
case ViewType::Type1D: return VK_IMAGE_VIEW_TYPE_1D;
case ViewType::Type2D: return VK_IMAGE_VIEW_TYPE_2D;
case ViewType::Type3D: return VK_IMAGE_VIEW_TYPE_3D;
case ViewType::TypeCube: return VK_IMAGE_VIEW_TYPE_CUBE;
case ViewType::Type1DArray: return VK_IMAGE_VIEW_TYPE_1D;
case ViewType::Type2DArray: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case ViewType::TypeCubeArray: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
case ViewType::Undefined:break;
}
FY_ASSERT(false, "VulkanUtils.hpp: CastLayout not found");
return VK_IMAGE_VIEW_TYPE_MAX_ENUM;
}

VkFilter CastFilter(const SamplerFilter& samplerFilter)
{
switch (samplerFilter)
{
case SamplerFilter::Nearest: return VK_FILTER_NEAREST;
case SamplerFilter::Linear: return VK_FILTER_LINEAR;
case SamplerFilter::CubicImg: return VK_FILTER_CUBIC_IMG;
}

FY_ASSERT(false, "VulkanUtils.hpp: CastFilter not filter");
return VK_FILTER_MAX_ENUM;
}

VkBorderColor CasterBorderColor(BorderColor borderColor)
{
switch (borderColor)
{
case BorderColor::FloatTransparentBlack: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case BorderColor::IntTransparentBlack: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case BorderColor::FloatOpaqueBlack: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case BorderColor::IntOpaqueBlack: return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
case BorderColor::FloatOpaqueWhite: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
}

FY_ASSERT(false, "VulkanUtils.hpp: CasterBorderColor");
return VK_BORDER_COLOR_MAX_ENUM;
}

VkSamplerAddressMode CastTextureAddressMode(const TextureAddressMode& mode)
{
switch (mode)
{
case TextureAddressMode::Repeat:return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case TextureAddressMode::MirroredRepeat: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case TextureAddressMode::ClampToEdge: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case TextureAddressMode::ClampToBorder: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case TextureAddressMode::MirrorClampToEdge: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
}
FY_ASSERT(false, "VulkanUtils.hpp: CastTextureAddressMode not found");
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
}

VkSamplerMipmapMode CastSamplerMipmapMode(SamplerMipmapMode samplerMipmapMode)
{
switch (samplerMipmapMode)
{
case SamplerMipmapMode::Nearest: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case SamplerMipmapMode::Linear: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
}
FY_ASSERT(false, "VulkanUtils.hpp: CastTextureAddressMode not found");
return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM;
}
}

19 changes: 18 additions & 1 deletion Engine/Source/Fyrion/Graphics/Device/Vulkan/VulkanUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

namespace Fyrion::Vulkan
{
VkBool32 VKAPI_PTR DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* callbackDataExt, void* userData);
VkBool32 VKAPI_PTR DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* callbackDataExt,
void* userData);

bool QueryLayerProperties(const Span<const char*>& requiredLayers);
bool QueryInstanceExtensions(const Span<const char*>& requiredExtensions);
Expand All @@ -30,9 +31,25 @@ namespace Fyrion::Vulkan
VkDescriptorType CastDescriptorType(const DescriptorType& descriptorType);
VkPrimitiveTopology CastPrimitiveTopology(const PrimitiveTopology& primitiveTopology);
VkImageLayout CastLayout(const ResourceLayout& resourceLayout, VkImageLayout defaultUndefined = VK_IMAGE_LAYOUT_UNDEFINED);
VkAttachmentLoadOp CastLoadOp(LoadOp loadOp);
VkAttachmentStoreOp CastStoreOp(StoreOp storeOp);
VkImageViewType CastViewType(const ViewType& viewType);
VkFilter CastFilter(const SamplerFilter& samplerFilter);
VkBorderColor CasterBorderColor(BorderColor borderColor);
VkSamplerAddressMode CastTextureAddressMode(const TextureAddressMode& mode);
VkSamplerMipmapMode CastSamplerMipmapMode(SamplerMipmapMode samplerMipmapMode);

inline bool QueryInstanceExtension(const char* extension)
{
return QueryInstanceExtensions(Span<const char*>(&extension, &extension + 1));
}

constexpr bool IsDepthFormat(VkFormat format)
{
return (format == VK_FORMAT_D32_SFLOAT_S8_UINT
|| format == VK_FORMAT_D32_SFLOAT
|| format == VK_FORMAT_D24_UNORM_S8_UINT
|| format == VK_FORMAT_D16_UNORM_S8_UINT
|| format == VK_FORMAT_D16_UNORM);
}
}
10 changes: 9 additions & 1 deletion Engine/Source/Fyrion/Graphics/GraphicsTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ namespace Fyrion
Struct
};

enum class SamplerMipmapMode
{
Nearest,
Linear
};

struct SwapchainCreation
{
Expand Down Expand Up @@ -290,10 +295,13 @@ namespace Fyrion
{
SamplerFilter filter{SamplerFilter::Linear};
TextureAddressMode addressMode{TextureAddressMode::Repeat};
CompareOp compareOperator{};
CompareOp compareOperator{CompareOp::Always};
f32 mipLodBias = 0.0f;
f32 minLod{};
f32 maxLod{};
bool anisotropyEnable = true;
BorderColor borderColor{BorderColor::IntOpaqueBlack};
SamplerMipmapMode samplerMipmapMode = SamplerMipmapMode::Linear;
};

struct ShaderCreation
Expand Down

0 comments on commit dd4ed5f

Please sign in to comment.