diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 525756a57..635c63e16 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1656,11 +1656,11 @@ namespace dxvk { passInfo.pClearValues = nullptr; // Retrieve a compatible pipeline to use for rendering - DxvkMetaMipGenPipeline pipeInfo = m_common->metaMipGen().getPipeline( + DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( mipGenerator->viewType(), imageView->info().format); for (uint32_t i = 0; i < mipGenerator->passCount(); i++) { - DxvkMetaMipGenPass pass = mipGenerator->pass(i); + DxvkMetaBlitPass pass = mipGenerator->pass(i); // Width, height and layer count for the current pass VkExtent3D passExtent = mipGenerator->passExtent(i); @@ -1688,7 +1688,7 @@ namespace dxvk { passInfo.renderArea = scissor; // Set up push constants - DxvkMetaMipGenPushConstants pushConstants; + DxvkMetaBlitPushConstants pushConstants; pushConstants.layerCount = passExtent.depth; m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp new file mode 100644 index 000000000..5cb5230bf --- /dev/null +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -0,0 +1,384 @@ +#include "dxvk_device.h" +#include "dxvk_meta_blit.h" + +#include +#include +#include + +#include +#include +#include + +namespace dxvk { + + DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device) + : m_vkd (device->vkd()), + m_sampler (createSampler()), + m_shaderFrag1D(createShaderModule(dxvk_blit_frag_1d)), + m_shaderFrag2D(createShaderModule(dxvk_blit_frag_2d)), + m_shaderFrag3D(createShaderModule(dxvk_blit_frag_3d)) { + if (device->extensions().extShaderViewportIndexLayer) { + m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); + } else { + m_shaderVert = createShaderModule(dxvk_fullscreen_vert); + m_shaderGeom = createShaderModule(dxvk_fullscreen_geom); + } + } + + + DxvkMetaBlitObjects::~DxvkMetaBlitObjects() { + for (const auto& pair : m_renderPasses) + m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second, nullptr); + + for (const auto& pair : m_pipelines) { + m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); + m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); + m_vkd->vkDestroyDescriptorSetLayout (m_vkd->device(), pair.second.dsetLayout, nullptr); + } + + m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag3D, nullptr); + m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag2D, nullptr); + m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag1D, nullptr); + m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderGeom, nullptr); + m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderVert, nullptr); + + m_vkd->vkDestroySampler(m_vkd->device(), m_sampler, nullptr); + } + + + DxvkMetaBlitPipeline DxvkMetaBlitObjects::getPipeline( + VkImageViewType viewType, + VkFormat viewFormat) { + std::lock_guard lock(m_mutex); + + DxvkMetaBlitPipelineKey key; + key.viewType = viewType; + key.viewFormat = viewFormat; + + auto entry = m_pipelines.find(key); + if (entry != m_pipelines.end()) + return entry->second; + + DxvkMetaBlitPipeline pipeline = this->createPipeline(key); + m_pipelines.insert({ key, pipeline }); + return pipeline; + } + + + VkRenderPass DxvkMetaBlitObjects::getRenderPass(VkFormat viewFormat) { + auto entry = m_renderPasses.find(viewFormat); + if (entry != m_renderPasses.end()) + return entry->second; + + VkRenderPass renderPass = this->createRenderPass(viewFormat); + m_renderPasses.insert({ viewFormat, renderPass }); + return renderPass; + } + + + VkSampler DxvkMetaBlitObjects::createSampler() const { + VkSamplerCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.magFilter = VK_FILTER_LINEAR; + info.minFilter = VK_FILTER_LINEAR; + info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + info.mipLodBias = 0.0f; + info.anisotropyEnable = VK_FALSE; + info.maxAnisotropy = 1.0f; + info.compareEnable = VK_FALSE; + info.compareOp = VK_COMPARE_OP_ALWAYS; + info.minLod = 0.0f; + info.maxLod = 0.0f; + info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + info.unnormalizedCoordinates = VK_FALSE; + + VkSampler result = VK_NULL_HANDLE; + if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create sampler"); + return result; + } + + + VkShaderModule DxvkMetaBlitObjects::createShaderModule(const SpirvCodeBuffer& code) const { + VkShaderModuleCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.codeSize = code.size(); + info.pCode = code.data(); + + VkShaderModule result = VK_NULL_HANDLE; + if (m_vkd->vkCreateShaderModule(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create shader module"); + return result; + } + + + DxvkMetaBlitPipeline DxvkMetaBlitObjects::createPipeline( + const DxvkMetaBlitPipelineKey& key) { + DxvkMetaBlitPipeline pipe; + pipe.dsetLayout = this->createDescriptorSetLayout(key.viewType); + pipe.pipeLayout = this->createPipelineLayout(pipe.dsetLayout); + pipe.pipeHandle = this->createPipeline(key.viewType, pipe.pipeLayout, + this->getRenderPass(key.viewFormat)); + return pipe; + } + + + VkRenderPass DxvkMetaBlitObjects::createRenderPass( + VkFormat format) const { + VkAttachmentDescription attachment; + attachment.flags = 0; + attachment.format = format; + attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkAttachmentReference attachmentRef; + attachmentRef.attachment = 0; + attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &attachmentRef; + subpass.pResolveAttachments = nullptr; + subpass.pDepthStencilAttachment = nullptr; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = nullptr; + + VkRenderPassCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.attachmentCount = 1; + info.pAttachments = &attachment; + info.subpassCount = 1; + info.pSubpasses = &subpass; + info.dependencyCount = 0; + info.pDependencies = nullptr; + + VkRenderPass result = VK_NULL_HANDLE; + if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create render pass"); + return result; + } + + + VkDescriptorSetLayout DxvkMetaBlitObjects::createDescriptorSetLayout( + VkImageViewType viewType) const { + VkDescriptorSetLayoutBinding binding; + binding.binding = 0; + binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + binding.descriptorCount = 1; + binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + binding.pImmutableSamplers = &m_sampler; + + VkDescriptorSetLayoutCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.bindingCount = 1; + info.pBindings = &binding; + + VkDescriptorSetLayout result = VK_NULL_HANDLE; + if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create descriptor set layout"); + return result; + } + + + VkPipelineLayout DxvkMetaBlitObjects::createPipelineLayout( + VkDescriptorSetLayout descriptorSetLayout) const { + VkPushConstantRange pushRange; + pushRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + pushRange.offset = 0; + pushRange.size = sizeof(DxvkMetaBlitPushConstants); + + VkPipelineLayoutCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.setLayoutCount = 1; + info.pSetLayouts = &descriptorSetLayout; + info.pushConstantRangeCount = 1; + info.pPushConstantRanges = &pushRange; + + VkPipelineLayout result = VK_NULL_HANDLE; + if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create pipeline layout"); + return result; + } + + + VkPipeline DxvkMetaBlitObjects::createPipeline( + VkImageViewType imageViewType, + VkPipelineLayout pipelineLayout, + VkRenderPass renderPass) const { + std::array stages; + uint32_t stageCount = 0; + + VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; + vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vsStage.pNext = nullptr; + vsStage.flags = 0; + vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; + vsStage.module = m_shaderVert; + vsStage.pName = "main"; + vsStage.pSpecializationInfo = nullptr; + + if (m_shaderGeom) { + VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; + gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + gsStage.pNext = nullptr; + gsStage.flags = 0; + gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + gsStage.module = m_shaderGeom; + gsStage.pName = "main"; + gsStage.pSpecializationInfo = nullptr; + } + + VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; + psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + psStage.pNext = nullptr; + psStage.flags = 0; + psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + psStage.module = VK_NULL_HANDLE; + psStage.pName = "main"; + psStage.pSpecializationInfo = nullptr; + + switch (imageViewType) { + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psStage.module = m_shaderFrag1D; break; + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psStage.module = m_shaderFrag2D; break; + case VK_IMAGE_VIEW_TYPE_3D: psStage.module = m_shaderFrag3D; break; + default: throw DxvkError("DxvkMetaBlitObjects: Invalid view type"); + } + + std::array dynStates = {{ + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }}; + + VkPipelineDynamicStateCreateInfo dynState; + dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynState.pNext = nullptr; + dynState.flags = 0; + dynState.dynamicStateCount = dynStates.size(); + dynState.pDynamicStates = dynStates.data(); + + VkPipelineVertexInputStateCreateInfo viState; + viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + viState.pNext = nullptr; + viState.flags = 0; + viState.vertexBindingDescriptionCount = 0; + viState.pVertexBindingDescriptions = nullptr; + viState.vertexAttributeDescriptionCount = 0; + viState.pVertexAttributeDescriptions = nullptr; + + VkPipelineInputAssemblyStateCreateInfo iaState; + iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + iaState.pNext = nullptr; + iaState.flags = 0; + iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + iaState.primitiveRestartEnable = VK_FALSE; + + VkPipelineViewportStateCreateInfo vpState; + vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + vpState.pNext = nullptr; + vpState.flags = 0; + vpState.viewportCount = 1; + vpState.pViewports = nullptr; + vpState.scissorCount = 1; + vpState.pScissors = nullptr; + + VkPipelineRasterizationStateCreateInfo rsState; + rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rsState.pNext = nullptr; + rsState.flags = 0; + rsState.depthClampEnable = VK_TRUE; + rsState.rasterizerDiscardEnable = VK_FALSE; + rsState.polygonMode = VK_POLYGON_MODE_FILL; + rsState.cullMode = VK_CULL_MODE_NONE; + rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rsState.depthBiasEnable = VK_FALSE; + rsState.depthBiasConstantFactor = 0.0f; + rsState.depthBiasClamp = 0.0f; + rsState.depthBiasSlopeFactor = 0.0f; + rsState.lineWidth = 1.0f; + + uint32_t msMask = 0xFFFFFFFF; + VkPipelineMultisampleStateCreateInfo msState; + msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + msState.pNext = nullptr; + msState.flags = 0; + msState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + msState.sampleShadingEnable = VK_FALSE; + msState.minSampleShading = 1.0f; + msState.pSampleMask = &msMask; + msState.alphaToCoverageEnable = VK_FALSE; + msState.alphaToOneEnable = VK_FALSE; + + VkPipelineColorBlendAttachmentState cbAttachment; + cbAttachment.blendEnable = VK_FALSE; + cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; + cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; + cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; + cbAttachment.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineColorBlendStateCreateInfo cbState; + cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + cbState.pNext = nullptr; + cbState.flags = 0; + cbState.logicOpEnable = VK_FALSE; + cbState.logicOp = VK_LOGIC_OP_NO_OP; + cbState.attachmentCount = 1; + cbState.pAttachments = &cbAttachment; + + for (uint32_t i = 0; i < 4; i++) + cbState.blendConstants[i] = 0.0f; + + VkGraphicsPipelineCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.stageCount = stageCount; + info.pStages = stages.data(); + info.pVertexInputState = &viState; + info.pInputAssemblyState = &iaState; + info.pTessellationState = nullptr; + info.pViewportState = &vpState; + info.pRasterizationState = &rsState; + info.pMultisampleState = &msState; + info.pColorBlendState = &cbState; + info.pDepthStencilState = nullptr; + info.pDynamicState = &dynState; + info.layout = pipelineLayout; + info.renderPass = renderPass; + info.subpass = 0; + info.basePipelineHandle = VK_NULL_HANDLE; + info.basePipelineIndex = -1; + + VkPipeline result = VK_NULL_HANDLE; + if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), VK_NULL_HANDLE, 1, &info, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaBlitObjects: Failed to create graphics pipeline"); + return result; + } + +} diff --git a/src/dxvk/dxvk_meta_blit.h b/src/dxvk/dxvk_meta_blit.h new file mode 100644 index 000000000..a7a89586c --- /dev/null +++ b/src/dxvk/dxvk_meta_blit.h @@ -0,0 +1,147 @@ +#pragma once + +#include +#include + +#include "../spirv/spirv_code_buffer.h" + +#include "dxvk_hash.h" +#include "dxvk_image.h" + +namespace dxvk { + + /** + * \brief Push constant data + */ + struct DxvkMetaBlitPushConstants { + uint32_t layerCount; + }; + + /** + * \brief Blit pipeline key + * + * We have to create pipelines for each + * combination of source image view type + * and image format. + */ + struct DxvkMetaBlitPipelineKey { + VkImageViewType viewType; + VkFormat viewFormat; + + bool eq(const DxvkMetaBlitPipelineKey& other) const { + return this->viewType == other.viewType + && this->viewFormat == other.viewFormat; + } + + size_t hash() const { + DxvkHashState result; + result.add(uint32_t(this->viewType)); + result.add(uint32_t(this->viewFormat)); + return result; + } + }; + + + /** + * \brief Blit pipeline + * + * Stores the objects for a single pipeline + * that is used for blitting. + */ + struct DxvkMetaBlitPipeline { + VkDescriptorSetLayout dsetLayout; + VkPipelineLayout pipeLayout; + VkPipeline pipeHandle; + }; + + + /** + * \brief Blit framebuffer + * + * Stores the image views and framebuffer + * handle used to generate one mip level. + */ + struct DxvkMetaBlitPass { + VkImageView srcView; + VkImageView dstView; + VkFramebuffer framebuffer; + }; + + + /** + * \brief Blitter objects + * + * Stores render pass objects and pipelines used + * to generate mip maps. Due to Vulkan API design + * decisions, we have to create one render pass + * and pipeline object per image format used. + */ + class DxvkMetaBlitObjects { + + public: + + DxvkMetaBlitObjects(const DxvkDevice* device); + ~DxvkMetaBlitObjects(); + + /** + * \brief Creates a blit pipeline + * + * \param [in] viewType Source image view type + * \param [in] viewFormat Image view format + * \returns The blit pipeline + */ + DxvkMetaBlitPipeline getPipeline( + VkImageViewType viewType, + VkFormat viewFormat); + + private: + + Rc m_vkd; + + VkSampler m_sampler; + + VkShaderModule m_shaderVert = VK_NULL_HANDLE; + VkShaderModule m_shaderGeom = VK_NULL_HANDLE; + VkShaderModule m_shaderFrag1D = VK_NULL_HANDLE; + VkShaderModule m_shaderFrag2D = VK_NULL_HANDLE; + VkShaderModule m_shaderFrag3D = VK_NULL_HANDLE; + + std::mutex m_mutex; + + std::unordered_map< + VkFormat, + VkRenderPass> m_renderPasses; + + std::unordered_map< + DxvkMetaBlitPipelineKey, + DxvkMetaBlitPipeline, + DxvkHash, DxvkEq> m_pipelines; + + VkRenderPass getRenderPass( + VkFormat viewFormat); + + VkSampler createSampler() const; + + VkShaderModule createShaderModule( + const SpirvCodeBuffer& code) const; + + DxvkMetaBlitPipeline createPipeline( + const DxvkMetaBlitPipelineKey& key); + + VkRenderPass createRenderPass( + VkFormat format) const; + + VkDescriptorSetLayout createDescriptorSetLayout( + VkImageViewType viewType) const; + + VkPipelineLayout createPipelineLayout( + VkDescriptorSetLayout descriptorSetLayout) const; + + VkPipeline createPipeline( + VkImageViewType imageViewType, + VkPipelineLayout pipelineLayout, + VkRenderPass renderPass) const; + + }; + +} diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 53f4ad98a..200b4df2f 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -120,7 +120,7 @@ namespace dxvk { VkFramebuffer result = VK_NULL_HANDLE; if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target framebuffer"); + throw DxvkError("DxvkMetaCopyRenderPass: Failed to create target framebuffer"); return result; } diff --git a/src/dxvk/dxvk_meta_mipgen.cpp b/src/dxvk/dxvk_meta_mipgen.cpp index 99ef96905..2a49c7131 100644 --- a/src/dxvk/dxvk_meta_mipgen.cpp +++ b/src/dxvk/dxvk_meta_mipgen.cpp @@ -1,16 +1,7 @@ -#include "dxvk_device.h" #include "dxvk_meta_mipgen.h" -#include -#include -#include - -#include -#include -#include - namespace dxvk { - + DxvkMetaMipGenRenderPass::DxvkMetaMipGenRenderPass( const Rc& vkd, const Rc& view) @@ -112,8 +103,8 @@ namespace dxvk { } - DxvkMetaMipGenPass DxvkMetaMipGenRenderPass::createFramebuffer(uint32_t pass) const { - DxvkMetaMipGenPass result; + DxvkMetaBlitPass DxvkMetaMipGenRenderPass::createFramebuffer(uint32_t pass) const { + DxvkMetaBlitPass result; result.srcView = VK_NULL_HANDLE; result.dstView = VK_NULL_HANDLE; result.framebuffer = VK_NULL_HANDLE; @@ -186,375 +177,4 @@ namespace dxvk { return result; } - - DxvkMetaMipGenObjects::DxvkMetaMipGenObjects(const DxvkDevice* device) - : m_vkd (device->vkd()), - m_sampler (createSampler()), - m_shaderFrag1D(createShaderModule(dxvk_mipgen_frag_1d)), - m_shaderFrag2D(createShaderModule(dxvk_mipgen_frag_2d)), - m_shaderFrag3D(createShaderModule(dxvk_mipgen_frag_3d)) { - if (device->extensions().extShaderViewportIndexLayer) { - m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); - } else { - m_shaderVert = createShaderModule(dxvk_fullscreen_vert); - m_shaderGeom = createShaderModule(dxvk_fullscreen_geom); - } - } - - - DxvkMetaMipGenObjects::~DxvkMetaMipGenObjects() { - for (const auto& pair : m_renderPasses) - m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second, nullptr); - - for (const auto& pair : m_pipelines) { - m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); - m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); - m_vkd->vkDestroyDescriptorSetLayout (m_vkd->device(), pair.second.dsetLayout, nullptr); - } - - m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag3D, nullptr); - m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag2D, nullptr); - m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFrag1D, nullptr); - m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderGeom, nullptr); - m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderVert, nullptr); - - m_vkd->vkDestroySampler(m_vkd->device(), m_sampler, nullptr); - } - - - DxvkMetaMipGenPipeline DxvkMetaMipGenObjects::getPipeline( - VkImageViewType viewType, - VkFormat viewFormat) { - std::lock_guard lock(m_mutex); - - DxvkMetaMipGenPipelineKey key; - key.viewType = viewType; - key.viewFormat = viewFormat; - - auto entry = m_pipelines.find(key); - if (entry != m_pipelines.end()) - return entry->second; - - DxvkMetaMipGenPipeline pipeline = this->createPipeline(key); - m_pipelines.insert({ key, pipeline }); - return pipeline; - } - - - VkRenderPass DxvkMetaMipGenObjects::getRenderPass(VkFormat viewFormat) { - auto entry = m_renderPasses.find(viewFormat); - if (entry != m_renderPasses.end()) - return entry->second; - - VkRenderPass renderPass = this->createRenderPass(viewFormat); - m_renderPasses.insert({ viewFormat, renderPass }); - return renderPass; - } - - - VkSampler DxvkMetaMipGenObjects::createSampler() const { - VkSamplerCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.magFilter = VK_FILTER_LINEAR; - info.minFilter = VK_FILTER_LINEAR; - info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.mipLodBias = 0.0f; - info.anisotropyEnable = VK_FALSE; - info.maxAnisotropy = 1.0f; - info.compareEnable = VK_FALSE; - info.compareOp = VK_COMPARE_OP_ALWAYS; - info.minLod = 0.0f; - info.maxLod = 0.0f; - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - info.unnormalizedCoordinates = VK_FALSE; - - VkSampler result = VK_NULL_HANDLE; - if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create sampler"); - return result; - } - - - VkShaderModule DxvkMetaMipGenObjects::createShaderModule(const SpirvCodeBuffer& code) const { - VkShaderModuleCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.codeSize = code.size(); - info.pCode = code.data(); - - VkShaderModule result = VK_NULL_HANDLE; - if (m_vkd->vkCreateShaderModule(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create shader module"); - return result; - } - - - DxvkMetaMipGenPipeline DxvkMetaMipGenObjects::createPipeline( - const DxvkMetaMipGenPipelineKey& key) { - DxvkMetaMipGenPipeline pipe; - pipe.dsetLayout = this->createDescriptorSetLayout(key.viewType); - pipe.pipeLayout = this->createPipelineLayout(pipe.dsetLayout); - pipe.pipeHandle = this->createPipeline(key.viewType, pipe.pipeLayout, - this->getRenderPass(key.viewFormat)); - return pipe; - } - - - VkRenderPass DxvkMetaMipGenObjects::createRenderPass( - VkFormat format) const { - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = format; - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create render pass"); - return result; - } - - - VkDescriptorSetLayout DxvkMetaMipGenObjects::createDescriptorSetLayout( - VkImageViewType viewType) const { - VkDescriptorSetLayoutBinding binding; - binding.binding = 0; - binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - binding.descriptorCount = 1; - binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - binding.pImmutableSamplers = &m_sampler; - - VkDescriptorSetLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.bindingCount = 1; - info.pBindings = &binding; - - VkDescriptorSetLayout result = VK_NULL_HANDLE; - if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create descriptor set layout"); - return result; - } - - - VkPipelineLayout DxvkMetaMipGenObjects::createPipelineLayout( - VkDescriptorSetLayout descriptorSetLayout) const { - VkPushConstantRange pushRange; - pushRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - pushRange.offset = 0; - pushRange.size = sizeof(DxvkMetaMipGenPushConstants); - - VkPipelineLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.setLayoutCount = 1; - info.pSetLayouts = &descriptorSetLayout; - info.pushConstantRangeCount = 1; - info.pPushConstantRanges = &pushRange; - - VkPipelineLayout result = VK_NULL_HANDLE; - if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create pipeline layout"); - return result; - } - - - VkPipeline DxvkMetaMipGenObjects::createPipeline( - VkImageViewType imageViewType, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass) const { - std::array stages; - uint32_t stageCount = 0; - - VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; - vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vsStage.pNext = nullptr; - vsStage.flags = 0; - vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsStage.module = m_shaderVert; - vsStage.pName = "main"; - vsStage.pSpecializationInfo = nullptr; - - if (m_shaderGeom) { - VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; - gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - gsStage.pNext = nullptr; - gsStage.flags = 0; - gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - gsStage.module = m_shaderGeom; - gsStage.pName = "main"; - gsStage.pSpecializationInfo = nullptr; - } - - VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; - psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - psStage.pNext = nullptr; - psStage.flags = 0; - psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - psStage.module = VK_NULL_HANDLE; - psStage.pName = "main"; - psStage.pSpecializationInfo = nullptr; - - switch (imageViewType) { - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psStage.module = m_shaderFrag1D; break; - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psStage.module = m_shaderFrag2D; break; - case VK_IMAGE_VIEW_TYPE_3D: psStage.module = m_shaderFrag3D; break; - default: throw DxvkError("DxvkMetaMipGenObjects: Invalid view type"); - } - - std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }}; - - VkPipelineDynamicStateCreateInfo dynState; - dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynState.pNext = nullptr; - dynState.flags = 0; - dynState.dynamicStateCount = dynStates.size(); - dynState.pDynamicStates = dynStates.data(); - - VkPipelineVertexInputStateCreateInfo viState; - viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viState.pNext = nullptr; - viState.flags = 0; - viState.vertexBindingDescriptionCount = 0; - viState.pVertexBindingDescriptions = nullptr; - viState.vertexAttributeDescriptionCount = 0; - viState.pVertexAttributeDescriptions = nullptr; - - VkPipelineInputAssemblyStateCreateInfo iaState; - iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaState.pNext = nullptr; - iaState.flags = 0; - iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - iaState.primitiveRestartEnable = VK_FALSE; - - VkPipelineViewportStateCreateInfo vpState; - vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpState.pNext = nullptr; - vpState.flags = 0; - vpState.viewportCount = 1; - vpState.pViewports = nullptr; - vpState.scissorCount = 1; - vpState.pScissors = nullptr; - - VkPipelineRasterizationStateCreateInfo rsState; - rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsState.pNext = nullptr; - rsState.flags = 0; - rsState.depthClampEnable = VK_TRUE; - rsState.rasterizerDiscardEnable = VK_FALSE; - rsState.polygonMode = VK_POLYGON_MODE_FILL; - rsState.cullMode = VK_CULL_MODE_NONE; - rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rsState.depthBiasEnable = VK_FALSE; - rsState.depthBiasConstantFactor = 0.0f; - rsState.depthBiasClamp = 0.0f; - rsState.depthBiasSlopeFactor = 0.0f; - rsState.lineWidth = 1.0f; - - uint32_t msMask = 0xFFFFFFFF; - VkPipelineMultisampleStateCreateInfo msState; - msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msState.pNext = nullptr; - msState.flags = 0; - msState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - msState.sampleShadingEnable = VK_FALSE; - msState.minSampleShading = 1.0f; - msState.pSampleMask = &msMask; - msState.alphaToCoverageEnable = VK_FALSE; - msState.alphaToOneEnable = VK_FALSE; - - VkPipelineColorBlendAttachmentState cbAttachment; - cbAttachment.blendEnable = VK_FALSE; - cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; - cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - cbAttachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo cbState; - cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbState.pNext = nullptr; - cbState.flags = 0; - cbState.logicOpEnable = VK_FALSE; - cbState.logicOp = VK_LOGIC_OP_NO_OP; - cbState.attachmentCount = 1; - cbState.pAttachments = &cbAttachment; - - for (uint32_t i = 0; i < 4; i++) - cbState.blendConstants[i] = 0.0f; - - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.stageCount = stageCount; - info.pStages = stages.data(); - info.pVertexInputState = &viState; - info.pInputAssemblyState = &iaState; - info.pTessellationState = nullptr; - info.pViewportState = &vpState; - info.pRasterizationState = &rsState; - info.pMultisampleState = &msState; - info.pColorBlendState = &cbState; - info.pDepthStencilState = nullptr; - info.pDynamicState = &dynState; - info.layout = pipelineLayout; - info.renderPass = renderPass; - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; - info.basePipelineIndex = -1; - - VkPipeline result = VK_NULL_HANDLE; - if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), VK_NULL_HANDLE, 1, &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenObjects: Failed to create graphics pipeline"); - return result; - } - } diff --git a/src/dxvk/dxvk_meta_mipgen.h b/src/dxvk/dxvk_meta_mipgen.h index 4c602f33c..a5d2d60f9 100644 --- a/src/dxvk/dxvk_meta_mipgen.h +++ b/src/dxvk/dxvk_meta_mipgen.h @@ -1,73 +1,11 @@ #pragma once -#include -#include +#include -#include "../spirv/spirv_code_buffer.h" - -#include "dxvk_hash.h" -#include "dxvk_image.h" +#include "dxvk_meta_blit.h" namespace dxvk { - /** - * \brief Push constant data - */ - struct DxvkMetaMipGenPushConstants { - uint32_t layerCount; - }; - - /** - * \brief Mip map generation pipeline key - * - * We have to create pipelines for each - * combination of source image view type - * and image format. - */ - struct DxvkMetaMipGenPipelineKey { - VkImageViewType viewType; - VkFormat viewFormat; - - bool eq(const DxvkMetaMipGenPipelineKey& other) const { - return this->viewType == other.viewType - && this->viewFormat == other.viewFormat; - } - - size_t hash() const { - DxvkHashState result; - result.add(uint32_t(this->viewType)); - result.add(uint32_t(this->viewFormat)); - return result; - } - }; - - - /** - * \brief Mip map generation pipeline - * - * Stores the objects for a single pipeline - * that is used for mipmap generation. - */ - struct DxvkMetaMipGenPipeline { - VkDescriptorSetLayout dsetLayout; - VkPipelineLayout pipeLayout; - VkPipeline pipeHandle; - }; - - - /** - * \brief Mip map generation framebuffer - * - * Stores the image views and framebuffer - * handle used to generate one mip level. - */ - struct DxvkMetaMipGenPass { - VkImageView srcView; - VkImageView dstView; - VkFramebuffer framebuffer; - }; - - /** * \brief Mip map generation render pass * @@ -122,7 +60,7 @@ namespace dxvk { * \param [in] pass Render pass index * \returns Object handles for the given pass */ - DxvkMetaMipGenPass pass(uint32_t passId) const { + DxvkMetaBlitPass pass(uint32_t passId) const { return m_passes.at(passId); } @@ -144,88 +82,11 @@ namespace dxvk { VkImageViewType m_srcViewType; VkImageViewType m_dstViewType; - std::vector m_passes; + std::vector m_passes; VkRenderPass createRenderPass() const; - DxvkMetaMipGenPass createFramebuffer(uint32_t pass) const; - - }; - - - /** - * \brief Mip map generation objects - * - * Stores render pass objects and pipelines used - * to generate mip maps. Due to Vulkan API design - * decisions, we have to create one render pass - * and pipeline object per image format used. - */ - class DxvkMetaMipGenObjects { - - public: - - DxvkMetaMipGenObjects(const DxvkDevice* device); - ~DxvkMetaMipGenObjects(); - - /** - * \brief Creates a mip map generation pipeline - * - * \param [in] viewType Source image view type - * \param [in] viewFormat Image view format - * \returns The mip map generation pipeline - */ - DxvkMetaMipGenPipeline getPipeline( - VkImageViewType viewType, - VkFormat viewFormat); - - private: - - Rc m_vkd; - - VkSampler m_sampler; - - VkShaderModule m_shaderVert = VK_NULL_HANDLE; - VkShaderModule m_shaderGeom = VK_NULL_HANDLE; - VkShaderModule m_shaderFrag1D = VK_NULL_HANDLE; - VkShaderModule m_shaderFrag2D = VK_NULL_HANDLE; - VkShaderModule m_shaderFrag3D = VK_NULL_HANDLE; - - std::mutex m_mutex; - - std::unordered_map< - VkFormat, - VkRenderPass> m_renderPasses; - - std::unordered_map< - DxvkMetaMipGenPipelineKey, - DxvkMetaMipGenPipeline, - DxvkHash, DxvkEq> m_pipelines; - - VkRenderPass getRenderPass( - VkFormat viewFormat); - - VkSampler createSampler() const; - - VkShaderModule createShaderModule( - const SpirvCodeBuffer& code) const; - - DxvkMetaMipGenPipeline createPipeline( - const DxvkMetaMipGenPipelineKey& key); - - VkRenderPass createRenderPass( - VkFormat format) const; - - VkDescriptorSetLayout createDescriptorSetLayout( - VkImageViewType viewType) const; - - VkPipelineLayout createPipelineLayout( - VkDescriptorSetLayout descriptorSetLayout) const; - - VkPipeline createPipeline( - VkImageViewType imageViewType, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass) const; + DxvkMetaBlitPass createFramebuffer(uint32_t pass) const; }; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 68bde159f..cd8e78c2f 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -214,7 +214,7 @@ namespace dxvk { VkFramebuffer result = VK_NULL_HANDLE; if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target framebuffer"); + throw DxvkError("DxvkMetaResolveRenderPass: Failed to create target framebuffer"); return result; } @@ -241,7 +241,7 @@ namespace dxvk { VkFramebuffer result = VK_NULL_HANDLE; if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target framebuffer"); + throw DxvkError("DxvkMetaResolveRenderPass: Failed to create target framebuffer"); return result; } diff --git a/src/dxvk/dxvk_objects.h b/src/dxvk/dxvk_objects.h index f96fc373c..aaa9e19bf 100644 --- a/src/dxvk/dxvk_objects.h +++ b/src/dxvk/dxvk_objects.h @@ -3,6 +3,7 @@ #include "dxvk_gpu_event.h" #include "dxvk_gpu_query.h" #include "dxvk_memory.h" +#include "dxvk_meta_blit.h" #include "dxvk_meta_clear.h" #include "dxvk_meta_copy.h" #include "dxvk_meta_mipgen.h" @@ -55,6 +56,10 @@ namespace dxvk { return m_dummyResources; } + DxvkMetaBlitObjects& metaBlit() { + return m_metaBlit.get(m_device); + } + DxvkMetaClearObjects& metaClear() { return m_metaClear.get(m_device); } @@ -67,10 +72,6 @@ namespace dxvk { return m_metaResolve.get(m_device); } - DxvkMetaMipGenObjects& metaMipGen() { - return m_metaMipGen.get(m_device); - } - DxvkMetaPackObjects& metaPack() { return m_metaPack.get(m_device); } @@ -88,10 +89,10 @@ namespace dxvk { DxvkUnboundResources m_dummyResources; + Lazy m_metaBlit; Lazy m_metaClear; Lazy m_metaCopy; Lazy m_metaResolve; - Lazy m_metaMipGen; Lazy m_metaPack; }; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 867f30023..67118b083 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -1,4 +1,8 @@ dxvk_shaders = files([ + 'shaders/dxvk_blit_frag_1d.frag', + 'shaders/dxvk_blit_frag_2d.frag', + 'shaders/dxvk_blit_frag_3d.frag', + 'shaders/dxvk_clear_buffer_u.comp', 'shaders/dxvk_clear_buffer_f.comp', 'shaders/dxvk_clear_image1d_u.comp', @@ -26,10 +30,6 @@ dxvk_shaders = files([ 'shaders/dxvk_fullscreen_vert.vert', 'shaders/dxvk_fullscreen_layer_vert.vert', - 'shaders/dxvk_mipgen_frag_1d.frag', - 'shaders/dxvk_mipgen_frag_2d.frag', - 'shaders/dxvk_mipgen_frag_3d.frag', - 'shaders/dxvk_pack_d24s8.comp', 'shaders/dxvk_pack_d32s8.comp', @@ -74,6 +74,7 @@ dxvk_src = files([ 'dxvk_lifetime.cpp', 'dxvk_main.cpp', 'dxvk_memory.cpp', + 'dxvk_meta_blit.cpp', 'dxvk_meta_clear.cpp', 'dxvk_meta_copy.cpp', 'dxvk_meta_mipgen.cpp', diff --git a/src/dxvk/shaders/dxvk_mipgen_frag_1d.frag b/src/dxvk/shaders/dxvk_blit_frag_1d.frag similarity index 100% rename from src/dxvk/shaders/dxvk_mipgen_frag_1d.frag rename to src/dxvk/shaders/dxvk_blit_frag_1d.frag diff --git a/src/dxvk/shaders/dxvk_mipgen_frag_2d.frag b/src/dxvk/shaders/dxvk_blit_frag_2d.frag similarity index 100% rename from src/dxvk/shaders/dxvk_mipgen_frag_2d.frag rename to src/dxvk/shaders/dxvk_blit_frag_2d.frag diff --git a/src/dxvk/shaders/dxvk_mipgen_frag_3d.frag b/src/dxvk/shaders/dxvk_blit_frag_3d.frag similarity index 100% rename from src/dxvk/shaders/dxvk_mipgen_frag_3d.frag rename to src/dxvk/shaders/dxvk_blit_frag_3d.frag