1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 10:54:16 +01:00

[dxvk] Use new mip map generator

This commit is contained in:
Philip Rebohle 2018-05-25 17:45:41 +02:00
parent 19b6a16173
commit 4b37590e14
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 126 additions and 131 deletions

View File

@ -856,9 +856,7 @@ namespace dxvk {
if (view->GetResourceType() != D3D11_RESOURCE_DIMENSION_BUFFER) { if (view->GetResourceType() != D3D11_RESOURCE_DIMENSION_BUFFER) {
EmitCs([cDstImageView = view->GetImageView()] EmitCs([cDstImageView = view->GetImageView()]
(DxvkContext* ctx) { (DxvkContext* ctx) {
ctx->generateMipmaps( ctx->generateMipmaps(cDstImageView);
cDstImageView->image(),
cDstImageView->subresources());
}); });
} else { } else {
Logger::err("D3D11: GenerateMips called on a buffer"); Logger::err("D3D11: GenerateMips called on a buffer");

View File

@ -9,10 +9,12 @@ namespace dxvk {
DxvkContext::DxvkContext( DxvkContext::DxvkContext(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
const Rc<DxvkPipelineManager>& pipelineManager, const Rc<DxvkPipelineManager>& pipelineManager,
const Rc<DxvkMetaClearObjects>& metaClearObjects) const Rc<DxvkMetaClearObjects>& metaClearObjects,
const Rc<DxvkMetaMipGenObjects>& metaMipGenObjects)
: m_device (device), : m_device (device),
m_pipeMgr (pipelineManager), m_pipeMgr (pipelineManager),
m_metaClear (metaClearObjects) { } m_metaClear (metaClearObjects),
m_metaMipGen(metaMipGenObjects) { }
DxvkContext::~DxvkContext() { DxvkContext::~DxvkContext() {
@ -976,123 +978,102 @@ namespace dxvk {
void DxvkContext::generateMipmaps( void DxvkContext::generateMipmaps(
const Rc<DxvkImage>& image, const Rc<DxvkImageView>& imageView) {
const VkImageSubresourceRange& subresources) { if (imageView->info().numLevels <= 1)
if (subresources.levelCount <= 1)
return; return;
this->spillRenderPass(); this->spillRenderPass();
this->unbindGraphicsPipeline();
// The top-most level will only be read. We can // Create the a set of framebuffers and image views
// discard the contents of all the lower levels const Rc<DxvkMetaMipGenRenderPass> mipGenerator
// since we're going to override them anyway. = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView);
m_barriers.accessImage(image,
VkImageSubresourceRange {
subresources.aspectMask,
subresources.baseMipLevel, 1,
subresources.baseArrayLayer,
subresources.layerCount },
image->info().layout,
image->info().stages,
image->info().access,
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
m_barriers.accessImage(image, // Common descriptor set properties that we use to
VkImageSubresourceRange { // bind the source image view to the fragment shader
subresources.aspectMask, VkDescriptorImageInfo descriptorImage;
subresources.baseMipLevel + 1, descriptorImage.sampler = VK_NULL_HANDLE;
subresources.levelCount - 1, descriptorImage.imageView = VK_NULL_HANDLE;
subresources.baseArrayLayer, descriptorImage.imageLayout = imageView->imageInfo().layout;
subresources.layerCount },
VK_IMAGE_LAYOUT_UNDEFINED,
image->info().stages,
image->info().access,
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
m_barriers.recordCommands(m_cmd); VkWriteDescriptorSet descriptorWrite;
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.pNext = nullptr;
descriptorWrite.dstSet = VK_NULL_HANDLE;
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorCount = 1;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrite.pImageInfo = &descriptorImage;
descriptorWrite.pBufferInfo = nullptr;
descriptorWrite.pTexelBufferView = nullptr;
// Generate each individual mip level with a blit // Common render pass info
for (uint32_t i = 1; i < subresources.levelCount; i++) { VkRenderPassBeginInfo passInfo;
const uint32_t mip = subresources.baseMipLevel + i; passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
passInfo.pNext = nullptr;
passInfo.renderPass = mipGenerator->renderPass();
passInfo.framebuffer = VK_NULL_HANDLE;
passInfo.renderArea = VkRect2D { };
passInfo.clearValueCount = 0;
passInfo.pClearValues = nullptr;
const VkExtent3D srcExtent = image->mipLevelExtent(mip - 1); // Retrieve a compatible pipeline to use for rendering
const VkExtent3D dstExtent = image->mipLevelExtent(mip); DxvkMetaMipGenPipeline pipeInfo = m_metaMipGen->getPipeline(
mipGenerator->viewType(), imageView->info().format);
VkImageBlit region; for (uint32_t i = 0; i < mipGenerator->passCount(); i++) {
region.srcSubresource = VkImageSubresourceLayers { DxvkMetaMipGenPass pass = mipGenerator->pass(i);
subresources.aspectMask, mip - 1,
subresources.baseArrayLayer,
subresources.layerCount };
region.srcOffsets[0] = VkOffset3D { 0, 0, 0 };
region.srcOffsets[1].x = srcExtent.width;
region.srcOffsets[1].y = srcExtent.height;
region.srcOffsets[1].z = srcExtent.depth;
region.dstSubresource = VkImageSubresourceLayers { // Width, height and layer count for the current pass
subresources.aspectMask, mip, VkExtent3D passExtent = mipGenerator->passExtent(i);
subresources.baseArrayLayer,
subresources.layerCount };
region.dstOffsets[0] = VkOffset3D { 0, 0, 0 };
region.dstOffsets[1].x = dstExtent.width;
region.dstOffsets[1].y = dstExtent.height;
region.dstOffsets[1].z = dstExtent.depth;
m_cmd->cmdBlitImage( // Create descriptor set with the current source view
image->handle(), image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), descriptorImage.imageView = pass.srcView;
image->handle(), image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), descriptorWrite.dstSet = m_cmd->allocateDescriptorSet(pipeInfo.dsetLayout);
1, &region, VK_FILTER_LINEAR); m_cmd->updateDescriptorSets(1, &descriptorWrite);
if (i + 1 < subresources.levelCount) { // Set up viewport and scissor rect
m_barriers.accessImage(image, VkViewport viewport;
VkImageSubresourceRange { viewport.x = 0.0f;
subresources.aspectMask, mip, 1, viewport.y = 0.0f;
subresources.baseArrayLayer, viewport.width = float(passExtent.width);
subresources.layerCount }, viewport.height = float(passExtent.height);
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), viewport.minDepth = 0.0f;
VK_PIPELINE_STAGE_TRANSFER_BIT, viewport.maxDepth = 1.0f;
VK_ACCESS_TRANSFER_WRITE_BIT,
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL), VkRect2D scissor;
VK_PIPELINE_STAGE_TRANSFER_BIT, scissor.offset = { 0, 0 };
VK_ACCESS_TRANSFER_READ_BIT); scissor.extent = { passExtent.width, passExtent.height };
m_barriers.recordCommands(m_cmd);
} // Set up render pass info
passInfo.framebuffer = pass.framebuffer;
passInfo.renderArea = scissor;
// Set up push constants
DxvkMetaMipGenPushConstants pushConstants;
pushConstants.layerCount = passExtent.depth;
m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE);
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle);
m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeInfo.pipeLayout, descriptorWrite.dstSet);
m_cmd->cmdSetViewport(0, 1, &viewport);
m_cmd->cmdSetScissor (0, 1, &scissor);
m_cmd->cmdPushConstants(
pipeInfo.pipeLayout,
VK_SHADER_STAGE_FRAGMENT_BIT,
0, sizeof(pushConstants),
&pushConstants);
m_cmd->cmdDraw(1, passExtent.depth, 0, 0);
m_cmd->cmdEndRenderPass();
} }
// Transform mip levels back into their original layout. m_cmd->trackResource(mipGenerator);
// The last mip level is still in TRANSFER_DST_OPTIMAL. m_cmd->trackResource(imageView);
m_barriers.accessImage(image,
VkImageSubresourceRange {
subresources.aspectMask,
subresources.baseMipLevel,
subresources.levelCount - 1,
subresources.baseArrayLayer,
subresources.layerCount },
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
image->info().layout,
image->info().stages,
image->info().access);
m_barriers.accessImage(image,
VkImageSubresourceRange {
subresources.aspectMask,
subresources.baseMipLevel
+ subresources.levelCount - 1, 1,
subresources.baseArrayLayer,
subresources.layerCount },
image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL),
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
image->info().layout,
image->info().stages,
image->info().access);
m_barriers.recordCommands(m_cmd);
} }
@ -1680,6 +1661,18 @@ namespace dxvk {
} }
void DxvkContext::unbindGraphicsPipeline() {
m_flags.set(
DxvkContextFlag::GpDirtyPipeline,
DxvkContextFlag::GpDirtyPipelineState,
DxvkContextFlag::GpDirtyResources,
DxvkContextFlag::GpDirtyVertexBuffers,
DxvkContextFlag::GpDirtyIndexBuffer);
m_gpActivePipeline = VK_NULL_HANDLE;
}
void DxvkContext::updateGraphicsPipeline() { void DxvkContext::updateGraphicsPipeline() {
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) { if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
m_flags.clr(DxvkContextFlag::GpDirtyPipeline); m_flags.clr(DxvkContextFlag::GpDirtyPipeline);

View File

@ -7,6 +7,7 @@
#include "dxvk_data.h" #include "dxvk_data.h"
#include "dxvk_event.h" #include "dxvk_event.h"
#include "dxvk_meta_clear.h" #include "dxvk_meta_clear.h"
#include "dxvk_meta_mipgen.h"
#include "dxvk_meta_resolve.h" #include "dxvk_meta_resolve.h"
#include "dxvk_pipecache.h" #include "dxvk_pipecache.h"
#include "dxvk_pipemanager.h" #include "dxvk_pipemanager.h"
@ -30,7 +31,8 @@ namespace dxvk {
DxvkContext( DxvkContext(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
const Rc<DxvkPipelineManager>& pipelineManager, const Rc<DxvkPipelineManager>& pipelineManager,
const Rc<DxvkMetaClearObjects>& metaClearObjects); const Rc<DxvkMetaClearObjects>& metaClearObjects,
const Rc<DxvkMetaMipGenObjects>& metaMipGenObjects);
~DxvkContext(); ~DxvkContext();
/** /**
@ -403,12 +405,10 @@ namespace dxvk {
* *
* Uses blitting to generate lower mip levels from * Uses blitting to generate lower mip levels from
* the top-most mip level passed to this method. * the top-most mip level passed to this method.
* \param [in] image The image to generate mips for * \param [in] imageView The image to generate mips for
* \param [in] subresource The subresource range
*/ */
void generateMipmaps( void generateMipmaps(
const Rc<DxvkImage>& image, const Rc<DxvkImageView>& imageView);
const VkImageSubresourceRange& subresources);
/** /**
* \brief Initializes or invalidates an image * \brief Initializes or invalidates an image
@ -621,6 +621,7 @@ namespace dxvk {
const Rc<DxvkDevice> m_device; const Rc<DxvkDevice> m_device;
const Rc<DxvkPipelineManager> m_pipeMgr; const Rc<DxvkPipelineManager> m_pipeMgr;
const Rc<DxvkMetaClearObjects> m_metaClear; const Rc<DxvkMetaClearObjects> m_metaClear;
const Rc<DxvkMetaMipGenObjects> m_metaMipGen;
Rc<DxvkCommandList> m_cmd; Rc<DxvkCommandList> m_cmd;
DxvkContextFlags m_flags; DxvkContextFlags m_flags;
@ -654,10 +655,10 @@ namespace dxvk {
DxvkRenderPassOps& renderPassOps); DxvkRenderPassOps& renderPassOps);
void unbindComputePipeline(); void unbindComputePipeline();
void updateComputePipeline(); void updateComputePipeline();
void updateComputePipelineState(); void updateComputePipelineState();
void unbindGraphicsPipeline();
void updateGraphicsPipeline(); void updateGraphicsPipeline();
void updateGraphicsPipelineState(); void updateGraphicsPipelineState();

View File

@ -17,6 +17,7 @@ namespace dxvk {
m_renderPassPool (new DxvkRenderPassPool (vkd)), m_renderPassPool (new DxvkRenderPassPool (vkd)),
m_pipelineManager (new DxvkPipelineManager (this)), m_pipelineManager (new DxvkPipelineManager (this)),
m_metaClearObjects (new DxvkMetaClearObjects (vkd)), m_metaClearObjects (new DxvkMetaClearObjects (vkd)),
m_metaMipGenObjects (new DxvkMetaMipGenObjects(vkd)),
m_unboundResources (this), m_unboundResources (this),
m_submissionQueue (this) { m_submissionQueue (this) {
m_graphicsQueue.queueFamily = m_adapter->graphicsQueueFamily(); m_graphicsQueue.queueFamily = m_adapter->graphicsQueueFamily();
@ -106,7 +107,8 @@ namespace dxvk {
Rc<DxvkContext> DxvkDevice::createContext() { Rc<DxvkContext> DxvkDevice::createContext() {
return new DxvkContext(this, return new DxvkContext(this,
m_pipelineManager, m_pipelineManager,
m_metaClearObjects); m_metaClearObjects,
m_metaMipGenObjects);
} }

View File

@ -356,6 +356,7 @@ namespace dxvk {
Rc<DxvkRenderPassPool> m_renderPassPool; Rc<DxvkRenderPassPool> m_renderPassPool;
Rc<DxvkPipelineManager> m_pipelineManager; Rc<DxvkPipelineManager> m_pipelineManager;
Rc<DxvkMetaClearObjects> m_metaClearObjects; Rc<DxvkMetaClearObjects> m_metaClearObjects;
Rc<DxvkMetaMipGenObjects> m_metaMipGenObjects;
DxvkUnboundResources m_unboundResources; DxvkUnboundResources m_unboundResources;