1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[dxvk] Support multisampled destinations in blitter

Apparently this is required for some D3D9 content.
This commit is contained in:
Philip Rebohle 2019-10-16 02:17:55 +02:00
parent e747315ba6
commit 859ac59e6c
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 61 additions and 23 deletions

View File

@ -1657,7 +1657,7 @@ namespace dxvk {
// Retrieve a compatible pipeline to use for rendering
DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline(
mipGenerator->viewType(), imageView->info().format);
mipGenerator->viewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT);
for (uint32_t i = 0; i < mipGenerator->passCount(); i++) {
DxvkMetaBlitPass pass = mipGenerator->pass(i);

View File

@ -49,13 +49,15 @@ namespace dxvk {
DxvkMetaBlitPipeline DxvkMetaBlitObjects::getPipeline(
VkImageViewType viewType,
VkFormat viewFormat) {
VkImageViewType viewType,
VkFormat viewFormat,
VkSampleCountFlagBits samples) {
std::lock_guard<std::mutex> lock(m_mutex);
DxvkMetaBlitPipelineKey key;
key.viewType = viewType;
key.viewFormat = viewFormat;
key.samples = samples;
auto entry = m_pipelines.find(key);
if (entry != m_pipelines.end())
@ -74,13 +76,19 @@ namespace dxvk {
}
VkRenderPass DxvkMetaBlitObjects::getRenderPass(VkFormat viewFormat) {
auto entry = m_renderPasses.find(viewFormat);
VkRenderPass DxvkMetaBlitObjects::getRenderPass(
VkFormat viewFormat,
VkSampleCountFlagBits samples) {
DxvkMetaBlitRenderPassKey key;
key.viewFormat = viewFormat;
key.samples = samples;
auto entry = m_renderPasses.find(key);
if (entry != m_renderPasses.end())
return entry->second;
VkRenderPass renderPass = this->createRenderPass(viewFormat);
m_renderPasses.insert({ viewFormat, renderPass });
VkRenderPass renderPass = this->createRenderPass(viewFormat, samples);
m_renderPasses.insert({ key, renderPass });
return renderPass;
}
@ -134,17 +142,18 @@ namespace dxvk {
pipe.dsetLayout = this->createDescriptorSetLayout(key.viewType);
pipe.pipeLayout = this->createPipelineLayout(pipe.dsetLayout);
pipe.pipeHandle = this->createPipeline(key.viewType, pipe.pipeLayout,
this->getRenderPass(key.viewFormat));
this->getRenderPass(key.viewFormat, key.samples), key.samples);
return pipe;
}
VkRenderPass DxvkMetaBlitObjects::createRenderPass(
VkFormat format) const {
VkFormat format,
VkSampleCountFlagBits samples) const {
VkAttachmentDescription attachment;
attachment.flags = 0;
attachment.format = format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.samples = samples;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -235,7 +244,8 @@ namespace dxvk {
VkPipeline DxvkMetaBlitObjects::createPipeline(
VkImageViewType imageViewType,
VkPipelineLayout pipelineLayout,
VkRenderPass renderPass) const {
VkRenderPass renderPass,
VkSampleCountFlagBits samples) const {
std::array<VkPipelineShaderStageCreateInfo, 3> stages;
uint32_t stageCount = 0;
@ -332,7 +342,7 @@ namespace dxvk {
msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
msState.pNext = nullptr;
msState.flags = 0;
msState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
msState.rasterizationSamples = samples;
msState.sampleShadingEnable = VK_FALSE;
msState.minSampleShading = 1.0f;
msState.pSampleMask = &msMask;

View File

@ -25,22 +25,44 @@ namespace dxvk {
* and image format.
*/
struct DxvkMetaBlitPipelineKey {
VkImageViewType viewType;
VkFormat viewFormat;
VkImageViewType viewType;
VkFormat viewFormat;
VkSampleCountFlagBits samples;
bool eq(const DxvkMetaBlitPipelineKey& other) const {
return this->viewType == other.viewType
&& this->viewFormat == other.viewFormat;
&& this->viewFormat == other.viewFormat
&& this->samples == other.samples;
}
size_t hash() const {
DxvkHashState result;
result.add(uint32_t(this->viewType));
result.add(uint32_t(this->viewFormat));
result.add(uint32_t(this->samples));
return result;
}
};
/**
* \brief Blit render pass key
*/
struct DxvkMetaBlitRenderPassKey {
VkFormat viewFormat;
VkSampleCountFlagBits samples;
bool eq(const DxvkMetaBlitRenderPassKey& other) const {
return this->viewFormat == other.viewFormat
&& this->samples == other.samples;
}
size_t hash() const {
DxvkHashState result;
result.add(uint32_t(this->viewFormat));
result.add(uint32_t(this->samples));
return result;
}
};
/**
* \brief Blit pipeline
@ -88,11 +110,13 @@ namespace dxvk {
*
* \param [in] viewType Source image view type
* \param [in] viewFormat Image view format
* \param [in] samples Target sample count
* \returns The blit pipeline
*/
DxvkMetaBlitPipeline getPipeline(
VkImageViewType viewType,
VkFormat viewFormat);
VkImageViewType viewType,
VkFormat viewFormat,
VkSampleCountFlagBits samples);
/**
* \brief Retrieves sampler with a given filter
@ -101,7 +125,7 @@ namespace dxvk {
* \returns Sampler object with the given filter
*/
VkSampler getSampler(
VkFilter filter);
VkFilter filter);
private:
@ -119,8 +143,9 @@ namespace dxvk {
std::mutex m_mutex;
std::unordered_map<
VkFormat,
VkRenderPass> m_renderPasses;
DxvkMetaBlitRenderPassKey,
VkRenderPass,
DxvkHash, DxvkEq> m_renderPasses;
std::unordered_map<
DxvkMetaBlitPipelineKey,
@ -128,7 +153,8 @@ namespace dxvk {
DxvkHash, DxvkEq> m_pipelines;
VkRenderPass getRenderPass(
VkFormat viewFormat);
VkFormat viewFormat,
VkSampleCountFlagBits samples);
VkSampler createSampler(
VkFilter filter) const;
@ -140,7 +166,8 @@ namespace dxvk {
const DxvkMetaBlitPipelineKey& key);
VkRenderPass createRenderPass(
VkFormat format) const;
VkFormat format,
VkSampleCountFlagBits samples) const;
VkDescriptorSetLayout createDescriptorSetLayout(
VkImageViewType viewType) const;
@ -151,7 +178,8 @@ namespace dxvk {
VkPipeline createPipeline(
VkImageViewType imageViewType,
VkPipelineLayout pipelineLayout,
VkRenderPass renderPass) const;
VkRenderPass renderPass,
VkSampleCountFlagBits samples) const;
};