mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +01:00
[dxvk] Refactor mip generation
This commit is contained in:
parent
8c67af680c
commit
58dab7e8c6
@ -1666,19 +1666,34 @@ namespace dxvk {
|
|||||||
this->spillRenderPass(false);
|
this->spillRenderPass(false);
|
||||||
this->invalidateState();
|
this->invalidateState();
|
||||||
|
|
||||||
// Create image views, etc.
|
// Make sure we can both render to and read from the image
|
||||||
Rc<DxvkMetaMipGenRenderPass> mipGenerator = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView);
|
VkFormat viewFormat = imageView->info().format;
|
||||||
|
|
||||||
|
DxvkImageUsageInfo usageInfo;
|
||||||
|
usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
usageInfo.viewFormatCount = 1;
|
||||||
|
usageInfo.viewFormats = &viewFormat;
|
||||||
|
|
||||||
|
if (!ensureImageCompatibility(imageView->image(), usageInfo)) {
|
||||||
|
Logger::err(str::format("DxvkContext: generateMipmaps: Unsupported operation:"
|
||||||
|
"\n view format: ", imageView->info().format,
|
||||||
|
"\n image format: ", imageView->image()->info().format));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write))
|
if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write))
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
// Create image views, etc.
|
||||||
|
DxvkMetaMipGenViews mipGenerator(imageView);
|
||||||
|
|
||||||
VkImageLayout dstLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VkImageLayout dstLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
// If necessary, transition first mip level to the read-only layout
|
// If necessary, transition first mip level to the read-only layout
|
||||||
if (imageView->image()->info().layout != srcLayout) {
|
if (imageView->image()->info().layout != srcLayout) {
|
||||||
m_execAcquires.accessImage(imageView->image(),
|
m_execAcquires.accessImage(imageView->image(),
|
||||||
mipGenerator->getTopSubresource(),
|
mipGenerator.getTopSubresource(),
|
||||||
imageView->image()->info().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->image()->info().stages, 0,
|
imageView->image()->info().stages, 0,
|
||||||
srcLayout,
|
srcLayout,
|
||||||
@ -1689,7 +1704,7 @@ namespace dxvk {
|
|||||||
// If necessary, initialize all levels that are written to
|
// If necessary, initialize all levels that are written to
|
||||||
if (imageView->image()->info().layout != dstLayout) {
|
if (imageView->image()->info().layout != dstLayout) {
|
||||||
m_execAcquires.accessImage(imageView->image(),
|
m_execAcquires.accessImage(imageView->image(),
|
||||||
mipGenerator->getAllTargetSubresources(),
|
mipGenerator.getAllTargetSubresources(),
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
imageView->image()->info().stages, 0,
|
imageView->image()->info().stages, 0,
|
||||||
dstLayout,
|
dstLayout,
|
||||||
@ -1724,14 +1739,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Retrieve a compatible pipeline to use for rendering
|
// Retrieve a compatible pipeline to use for rendering
|
||||||
DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline(
|
DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline(
|
||||||
mipGenerator->getSrcViewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT);
|
mipGenerator.getSrcViewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mipGenerator->getPassCount(); i++) {
|
for (uint32_t i = 0; i < mipGenerator.getPassCount(); i++) {
|
||||||
// Width, height and layer count for the current pass
|
// Width, height and layer count for the current pass
|
||||||
VkExtent3D passExtent = mipGenerator->computePassExtent(i);
|
VkExtent3D passExtent = mipGenerator.computePassExtent(i);
|
||||||
|
|
||||||
// Create descriptor set with the current source view
|
// Create descriptor set with the current source view
|
||||||
descriptorImage.imageView = mipGenerator->getSrcView(i);
|
descriptorImage.imageView = mipGenerator.getSrcViewHandle(i);
|
||||||
descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout);
|
descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout);
|
||||||
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
||||||
|
|
||||||
@ -1749,7 +1764,7 @@ namespace dxvk {
|
|||||||
scissor.extent = { passExtent.width, passExtent.height };
|
scissor.extent = { passExtent.width, passExtent.height };
|
||||||
|
|
||||||
// Set up rendering info
|
// Set up rendering info
|
||||||
attachmentInfo.imageView = mipGenerator->getDstView(i);
|
attachmentInfo.imageView = mipGenerator.getDstViewHandle(i);
|
||||||
renderingInfo.renderArea = scissor;
|
renderingInfo.renderArea = scissor;
|
||||||
renderingInfo.layerCount = passExtent.depth;
|
renderingInfo.layerCount = passExtent.depth;
|
||||||
|
|
||||||
@ -1761,7 +1776,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (i) {
|
if (i) {
|
||||||
m_execAcquires.accessImage(imageView->image(),
|
m_execAcquires.accessImage(imageView->image(),
|
||||||
mipGenerator->getSourceSubresource(i),
|
mipGenerator.getSourceSubresource(i),
|
||||||
dstLayout,
|
dstLayout,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
@ -1804,7 +1819,7 @@ namespace dxvk {
|
|||||||
imageView->image()->info().access);
|
imageView->image()->info().access);
|
||||||
} else {
|
} else {
|
||||||
m_execBarriers.accessImage(imageView->image(),
|
m_execBarriers.accessImage(imageView->image(),
|
||||||
mipGenerator->getAllSourceSubresources(),
|
mipGenerator.getAllSourceSubresources(),
|
||||||
srcLayout,
|
srcLayout,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
@ -1815,7 +1830,7 @@ namespace dxvk {
|
|||||||
imageView->image()->info().access);
|
imageView->image()->info().access);
|
||||||
|
|
||||||
m_execBarriers.accessImage(imageView->image(),
|
m_execBarriers.accessImage(imageView->image(),
|
||||||
mipGenerator->getBottomSubresource(),
|
mipGenerator.getBottomSubresource(),
|
||||||
dstLayout,
|
dstLayout,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
@ -1824,7 +1839,6 @@ namespace dxvk {
|
|||||||
imageView->image()->info().access);
|
imageView->image()->info().access);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(mipGenerator);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkMetaMipGenRenderPass::DxvkMetaMipGenRenderPass(
|
DxvkMetaMipGenViews::DxvkMetaMipGenViews(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const Rc<DxvkImageView>& view)
|
const Rc<DxvkImageView>& view)
|
||||||
: m_vkd(vkd), m_view(view) {
|
: m_view(view) {
|
||||||
// Determine view type based on image type
|
// Determine view type based on image type
|
||||||
const std::array<std::pair<VkImageViewType, VkImageViewType>, 3> viewTypes = {{
|
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_1D_ARRAY, VK_IMAGE_VIEW_TYPE_1D_ARRAY },
|
||||||
@ -24,15 +23,12 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkMetaMipGenRenderPass::~DxvkMetaMipGenRenderPass() {
|
DxvkMetaMipGenViews::~DxvkMetaMipGenViews() {
|
||||||
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 DxvkMetaMipGenViews::computePassExtent(uint32_t passId) const {
|
||||||
VkExtent3D extent = m_view->mipLevelExtent(passId + 1);
|
VkExtent3D extent = m_view->mipLevelExtent(passId + 1);
|
||||||
|
|
||||||
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D)
|
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D)
|
||||||
@ -42,54 +38,43 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkMetaMipGenRenderPass::PassViews DxvkMetaMipGenRenderPass::createViews(uint32_t pass) const {
|
DxvkMetaMipGenViews::PassViews DxvkMetaMipGenViews::createViews(uint32_t pass) const {
|
||||||
PassViews result = { };
|
PassViews result = { };
|
||||||
|
|
||||||
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
// Source image view
|
||||||
|
DxvkImageViewKey srcViewInfo;
|
||||||
|
srcViewInfo.viewType = m_srcViewType;
|
||||||
|
srcViewInfo.format = m_view->info().format;
|
||||||
|
srcViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
srcViewInfo.aspects = m_view->info().aspects;
|
||||||
|
srcViewInfo.mipIndex = m_view->info().mipIndex + pass;
|
||||||
|
srcViewInfo.mipCount = 1;
|
||||||
|
srcViewInfo.layerIndex = m_view->info().layerIndex;
|
||||||
|
srcViewInfo.layerCount = m_view->info().layerCount;
|
||||||
|
|
||||||
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
result.src = m_view->image()->createView(srcViewInfo);
|
||||||
viewInfo.image = m_view->image()->handle();
|
|
||||||
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().mipIndex + pass;
|
|
||||||
srcSubresources.levelCount = 1;
|
|
||||||
srcSubresources.baseArrayLayer = m_view->info().layerIndex;
|
|
||||||
srcSubresources.layerCount = m_view->info().layerCount;
|
|
||||||
|
|
||||||
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
|
// Create destination image view, which points
|
||||||
// to the mip level we're going to render to.
|
// to the mip level we're going to render to.
|
||||||
VkExtent3D dstExtent = m_view->mipLevelExtent(pass + 1);
|
VkExtent3D dstExtent = m_view->mipLevelExtent(pass + 1);
|
||||||
|
|
||||||
VkImageSubresourceRange dstSubresources;
|
DxvkImageViewKey dstViewInfo;
|
||||||
dstSubresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
dstViewInfo.viewType = m_dstViewType;
|
||||||
dstSubresources.baseMipLevel = m_view->info().mipIndex + pass + 1;
|
dstViewInfo.format = m_view->info().format;
|
||||||
dstSubresources.levelCount = 1;
|
dstViewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
dstViewInfo.aspects = m_view->info().aspects;
|
||||||
|
dstViewInfo.mipIndex = m_view->info().mipIndex + pass + 1;
|
||||||
|
dstViewInfo.mipCount = 1u;
|
||||||
|
|
||||||
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D) {
|
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D) {
|
||||||
dstSubresources.baseArrayLayer = m_view->info().layerIndex;
|
dstViewInfo.layerIndex = m_view->info().layerIndex;
|
||||||
dstSubresources.layerCount = m_view->info().layerCount;
|
dstViewInfo.layerCount = m_view->info().layerCount;
|
||||||
} else {
|
} else {
|
||||||
dstSubresources.baseArrayLayer = 0;
|
dstViewInfo.layerIndex = 0;
|
||||||
dstSubresources.layerCount = dstExtent.depth;
|
dstViewInfo.layerCount = dstExtent.depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
result.dst = m_view->image()->createView(dstViewInfo);
|
||||||
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../util/util_small_vector.h"
|
||||||
|
|
||||||
#include "dxvk_meta_blit.h"
|
#include "dxvk_meta_blit.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -13,15 +15,14 @@ namespace dxvk {
|
|||||||
* a render pass object for mip map generation.
|
* a render pass object for mip map generation.
|
||||||
* This must be created per image view.
|
* This must be created per image view.
|
||||||
*/
|
*/
|
||||||
class DxvkMetaMipGenRenderPass : public DxvkResource {
|
class DxvkMetaMipGenViews {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkMetaMipGenRenderPass(
|
DxvkMetaMipGenViews(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const Rc<DxvkImageView>& view);
|
const Rc<DxvkImageView>& view);
|
||||||
|
|
||||||
~DxvkMetaMipGenRenderPass();
|
~DxvkMetaMipGenViews();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Source image view type
|
* \brief Source image view type
|
||||||
@ -50,8 +51,8 @@ namespace dxvk {
|
|||||||
* \param [in] pass Render pass index
|
* \param [in] pass Render pass index
|
||||||
* \returns Source image view handle for the given pass
|
* \returns Source image view handle for the given pass
|
||||||
*/
|
*/
|
||||||
VkImageView getSrcView(uint32_t passId) const {
|
VkImageView getSrcViewHandle(uint32_t passId) const {
|
||||||
return m_passes.at(passId).src;
|
return m_passes[passId].src->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,8 +61,8 @@ namespace dxvk {
|
|||||||
* \param [in] pass Render pass index
|
* \param [in] pass Render pass index
|
||||||
* \returns Destination image view handle for the given pass
|
* \returns Destination image view handle for the given pass
|
||||||
*/
|
*/
|
||||||
VkImageView getDstView(uint32_t passId) const {
|
VkImageView getDstViewHandle(uint32_t passId) const {
|
||||||
return m_passes.at(passId).dst;
|
return m_passes[passId].dst->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,17 +131,16 @@ namespace dxvk {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
struct PassViews {
|
struct PassViews {
|
||||||
VkImageView src;
|
Rc<DxvkImageView> src;
|
||||||
VkImageView dst;
|
Rc<DxvkImageView> dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
Rc<DxvkImageView> m_view;
|
Rc<DxvkImageView> m_view;
|
||||||
|
|
||||||
VkImageViewType m_srcViewType;
|
VkImageViewType m_srcViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||||
VkImageViewType m_dstViewType;
|
VkImageViewType m_dstViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||||
|
|
||||||
std::vector<PassViews> m_passes;
|
small_vector<PassViews, 16> m_passes;
|
||||||
|
|
||||||
PassViews createViews(uint32_t pass) const;
|
PassViews createViews(uint32_t pass) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user