187 lines
7.8 KiB
C++
187 lines
7.8 KiB
C++
#include "XCEngine/RHI/Vulkan/VulkanResourceView.h"
|
|
|
|
#include "XCEngine/RHI/Vulkan/VulkanBuffer.h"
|
|
#include "XCEngine/RHI/Vulkan/VulkanTexture.h"
|
|
|
|
namespace XCEngine {
|
|
namespace RHI {
|
|
|
|
VulkanResourceView::~VulkanResourceView() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsRenderTarget(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc) {
|
|
if (device == VK_NULL_HANDLE || texture == nullptr || texture->GetImage() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_device = device;
|
|
m_texture = texture;
|
|
m_viewType = ResourceViewType::RenderTarget;
|
|
m_dimension = desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Texture2D;
|
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : texture->GetFormat();
|
|
|
|
VkImageViewCreateInfo viewInfo = {};
|
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
viewInfo.image = texture->GetImage();
|
|
viewInfo.viewType = ToVulkanImageViewType(m_dimension, texture->GetTextureType());
|
|
viewInfo.format = m_format != Format::Unknown ? ToVulkanFormat(m_format) : texture->GetVkFormat();
|
|
viewInfo.subresourceRange.aspectMask = GetImageAspectMask(texture->GetFormat());
|
|
viewInfo.subresourceRange.baseMipLevel = desc.mipLevel;
|
|
viewInfo.subresourceRange.levelCount = 1;
|
|
viewInfo.subresourceRange.baseArrayLayer = desc.firstArraySlice;
|
|
viewInfo.subresourceRange.layerCount = 1;
|
|
|
|
return vkCreateImageView(device, &viewInfo, nullptr, &m_imageView) == VK_SUCCESS;
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsDepthStencil(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc) {
|
|
if (device == VK_NULL_HANDLE || texture == nullptr || texture->GetImage() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_device = device;
|
|
m_texture = texture;
|
|
m_viewType = ResourceViewType::DepthStencil;
|
|
m_dimension = desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Texture2D;
|
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : texture->GetFormat();
|
|
|
|
VkImageViewCreateInfo viewInfo = {};
|
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
viewInfo.image = texture->GetImage();
|
|
viewInfo.viewType = ToVulkanImageViewType(m_dimension, texture->GetTextureType());
|
|
viewInfo.format = m_format != Format::Unknown ? ToVulkanFormat(m_format) : texture->GetVkFormat();
|
|
viewInfo.subresourceRange.aspectMask = GetImageAspectMask(m_format != Format::Unknown ? m_format : texture->GetFormat());
|
|
viewInfo.subresourceRange.baseMipLevel = desc.mipLevel;
|
|
viewInfo.subresourceRange.levelCount = 1;
|
|
viewInfo.subresourceRange.baseArrayLayer = desc.firstArraySlice;
|
|
viewInfo.subresourceRange.layerCount = 1;
|
|
|
|
return vkCreateImageView(device, &viewInfo, nullptr, &m_imageView) == VK_SUCCESS;
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsShaderResource(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc) {
|
|
if (device == VK_NULL_HANDLE || texture == nullptr || texture->GetImage() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_device = device;
|
|
m_texture = texture;
|
|
m_viewType = ResourceViewType::ShaderResource;
|
|
m_dimension = desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Texture2D;
|
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : texture->GetFormat();
|
|
|
|
VkImageViewCreateInfo viewInfo = {};
|
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
viewInfo.image = texture->GetImage();
|
|
viewInfo.viewType = ToVulkanImageViewType(m_dimension, texture->GetTextureType());
|
|
viewInfo.format = m_format != Format::Unknown ? ToVulkanFormat(m_format) : texture->GetVkFormat();
|
|
viewInfo.subresourceRange.aspectMask = GetImageAspectMask(texture->GetFormat());
|
|
viewInfo.subresourceRange.baseMipLevel = desc.mipLevel;
|
|
viewInfo.subresourceRange.levelCount = 1;
|
|
viewInfo.subresourceRange.baseArrayLayer = desc.firstArraySlice;
|
|
viewInfo.subresourceRange.layerCount = 1;
|
|
|
|
return vkCreateImageView(device, &viewInfo, nullptr, &m_imageView) == VK_SUCCESS;
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsUnorderedAccess(VkDevice device, VulkanTexture* texture, const ResourceViewDesc& desc) {
|
|
if (device == VK_NULL_HANDLE || texture == nullptr || texture->GetImage() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_device = device;
|
|
m_texture = texture;
|
|
m_viewType = ResourceViewType::UnorderedAccess;
|
|
m_dimension = desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Texture2D;
|
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : texture->GetFormat();
|
|
|
|
VkImageViewCreateInfo viewInfo = {};
|
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
viewInfo.image = texture->GetImage();
|
|
viewInfo.viewType = ToVulkanImageViewType(m_dimension, texture->GetTextureType());
|
|
viewInfo.format = m_format != Format::Unknown ? ToVulkanFormat(m_format) : texture->GetVkFormat();
|
|
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
viewInfo.subresourceRange.baseMipLevel = desc.mipLevel;
|
|
viewInfo.subresourceRange.levelCount = 1;
|
|
viewInfo.subresourceRange.baseArrayLayer = desc.firstArraySlice;
|
|
viewInfo.subresourceRange.layerCount = 1;
|
|
|
|
return vkCreateImageView(device, &viewInfo, nullptr, &m_imageView) == VK_SUCCESS;
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsVertexBuffer(VulkanBuffer* buffer, const ResourceViewDesc& desc) {
|
|
if (buffer == nullptr || buffer->GetBuffer() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_viewType = ResourceViewType::VertexBuffer;
|
|
m_dimension = ResourceViewDimension::Buffer;
|
|
m_format = Format::Unknown;
|
|
m_buffer = buffer;
|
|
m_bufferOffset = desc.bufferLocation;
|
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize());
|
|
m_bufferStride = desc.structureByteStride > 0 ? desc.structureByteStride : buffer->GetStride();
|
|
return true;
|
|
}
|
|
|
|
bool VulkanResourceView::InitializeAsIndexBuffer(VulkanBuffer* buffer, const ResourceViewDesc& desc) {
|
|
if (buffer == nullptr || buffer->GetBuffer() == VK_NULL_HANDLE) {
|
|
return false;
|
|
}
|
|
|
|
m_viewType = ResourceViewType::IndexBuffer;
|
|
m_dimension = ResourceViewDimension::Buffer;
|
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : Format::R32_UInt;
|
|
m_buffer = buffer;
|
|
m_bufferOffset = desc.bufferLocation;
|
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize());
|
|
m_bufferStride = buffer->GetStride();
|
|
return true;
|
|
}
|
|
|
|
void* VulkanResourceView::GetNativeHandle() {
|
|
if (m_imageView != VK_NULL_HANDLE) {
|
|
return m_imageView;
|
|
}
|
|
|
|
return m_buffer != nullptr ? m_buffer->GetNativeHandle() : nullptr;
|
|
}
|
|
|
|
bool VulkanResourceView::IsValid() const {
|
|
switch (m_viewType) {
|
|
case ResourceViewType::VertexBuffer:
|
|
case ResourceViewType::IndexBuffer:
|
|
return m_buffer != nullptr && m_buffer->GetBuffer() != VK_NULL_HANDLE;
|
|
case ResourceViewType::RenderTarget:
|
|
case ResourceViewType::DepthStencil:
|
|
case ResourceViewType::ShaderResource:
|
|
case ResourceViewType::UnorderedAccess:
|
|
return m_imageView != VK_NULL_HANDLE;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
VkBuffer VulkanResourceView::GetBuffer() const {
|
|
return m_buffer != nullptr ? m_buffer->GetBuffer() : VK_NULL_HANDLE;
|
|
}
|
|
|
|
void VulkanResourceView::Shutdown() {
|
|
if (m_imageView != VK_NULL_HANDLE && m_device != VK_NULL_HANDLE) {
|
|
vkDestroyImageView(m_device, m_imageView, nullptr);
|
|
}
|
|
m_imageView = VK_NULL_HANDLE;
|
|
m_device = VK_NULL_HANDLE;
|
|
m_texture = nullptr;
|
|
m_buffer = nullptr;
|
|
m_format = Format::Unknown;
|
|
m_dimension = ResourceViewDimension::Unknown;
|
|
m_bufferOffset = 0;
|
|
m_bufferSize = 0;
|
|
m_bufferStride = 0;
|
|
}
|
|
|
|
} // namespace RHI
|
|
} // namespace XCEngine
|