mirror of https://github.com/doitsujin/dxvk
98 lines
3.6 KiB
C++
98 lines
3.6 KiB
C++
#include "dxvk_meta_mipgen.h"
|
|
|
|
namespace dxvk {
|
|
|
|
DxvkMetaMipGenRenderPass::DxvkMetaMipGenRenderPass(
|
|
const Rc<vk::DeviceFn>& vkd,
|
|
const Rc<DxvkImageView>& view)
|
|
: m_vkd(vkd), m_view(view) {
|
|
// Determine view type based on image type
|
|
const std::array<std::pair<VkImageViewType, VkImageViewType>, 3> viewTypes = {{
|
|
{ VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_1D_ARRAY },
|
|
{ VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY },
|
|
{ VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_2D_ARRAY },
|
|
}};
|
|
|
|
m_srcViewType = viewTypes.at(uint32_t(view->imageInfo().type)).first;
|
|
m_dstViewType = viewTypes.at(uint32_t(view->imageInfo().type)).second;
|
|
|
|
// Create image views and framebuffers
|
|
m_passes.resize(view->info().numLevels - 1);
|
|
|
|
for (uint32_t i = 0; i < m_passes.size(); i++)
|
|
m_passes[i] = createViews(i);
|
|
}
|
|
|
|
|
|
DxvkMetaMipGenRenderPass::~DxvkMetaMipGenRenderPass() {
|
|
for (const auto& views : m_passes) {
|
|
m_vkd->vkDestroyImageView(m_vkd->device(), views.src, nullptr);
|
|
m_vkd->vkDestroyImageView(m_vkd->device(), views.dst, nullptr);
|
|
}
|
|
}
|
|
|
|
|
|
VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const {
|
|
VkExtent3D extent = m_view->mipLevelExtent(passId + 1);
|
|
|
|
if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D)
|
|
extent.depth = m_view->info().numLayers;
|
|
|
|
return extent;
|
|
}
|
|
|
|
|
|
DxvkMetaMipGenRenderPass::PassViews DxvkMetaMipGenRenderPass::createViews(uint32_t pass) const {
|
|
PassViews result = { };
|
|
|
|
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
|
|
|
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
|
viewInfo.image = m_view->imageHandle();
|
|
viewInfo.format = m_view->info().format;
|
|
|
|
// Create source image view, which points to
|
|
// the one mip level we're going to sample.
|
|
VkImageSubresourceRange srcSubresources;
|
|
srcSubresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
srcSubresources.baseMipLevel = m_view->info().minLevel + pass;
|
|
srcSubresources.levelCount = 1;
|
|
srcSubresources.baseArrayLayer = m_view->info().minLayer;
|
|
srcSubresources.layerCount = m_view->info().numLayers;
|
|
|
|
usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
viewInfo.viewType = m_srcViewType;
|
|
viewInfo.subresourceRange = srcSubresources;
|
|
|
|
if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.src) != VK_SUCCESS)
|
|
throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create source image view");
|
|
|
|
// Create destination image view, which points
|
|
// to the mip level we're going to render to.
|
|
VkExtent3D dstExtent = m_view->mipLevelExtent(pass + 1);
|
|
|
|
VkImageSubresourceRange dstSubresources;
|
|
dstSubresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
dstSubresources.baseMipLevel = m_view->info().minLevel + pass + 1;
|
|
dstSubresources.levelCount = 1;
|
|
|
|
if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) {
|
|
dstSubresources.baseArrayLayer = m_view->info().minLayer;
|
|
dstSubresources.layerCount = m_view->info().numLayers;
|
|
} else {
|
|
dstSubresources.baseArrayLayer = 0;
|
|
dstSubresources.layerCount = dstExtent.depth;
|
|
}
|
|
|
|
usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
viewInfo.viewType = m_dstViewType;
|
|
viewInfo.subresourceRange = dstSubresources;
|
|
|
|
if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.dst) != VK_SUCCESS)
|
|
throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create destination image view");
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|