From 6d8069dfd1b12a73a54e725773a1db70d372a650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 13 Jun 2023 20:46:27 +0200 Subject: [PATCH] Vulkan: Remove the remains of the input attachment experiment Haven't been using these for a while. I've come to the conclusion here that I think it's better to try to deal with the issues using safe workarounds like copies, instead of relying on features with somewhat iffy driver support that are not universal across APIs anyway. --- Common/GPU/Vulkan/VulkanFramebuffer.cpp | 31 +++------------- Common/GPU/Vulkan/VulkanFramebuffer.h | 11 ++---- Common/GPU/Vulkan/VulkanQueueRunner.cpp | 43 ----------------------- Common/GPU/Vulkan/VulkanQueueRunner.h | 10 ++---- Common/GPU/Vulkan/VulkanRenderManager.cpp | 13 ------- Common/GPU/Vulkan/VulkanRenderManager.h | 2 -- Common/GPU/Vulkan/thin3d_vulkan.cpp | 11 ++---- GPU/Common/FragmentShaderGenerator.cpp | 7 ++-- GPU/Common/FragmentShaderGenerator.h | 1 - GPU/GPUCommonHW.cpp | 4 --- GPU/Vulkan/DrawEngineVulkan.cpp | 22 ++++-------- GPU/Vulkan/DrawEngineVulkan.h | 5 +-- GPU/Vulkan/GPU_Vulkan.cpp | 10 ------ GPU/Vulkan/PipelineManagerVulkan.cpp | 3 -- GPU/Vulkan/PipelineManagerVulkan.h | 1 - GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 7 ---- 17 files changed, 25 insertions(+), 158 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.cpp b/Common/GPU/Vulkan/VulkanFramebuffer.cpp index 17167e36eb..e9c68794a5 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.cpp +++ b/Common/GPU/Vulkan/VulkanFramebuffer.cpp @@ -265,7 +265,6 @@ static VkAttachmentStoreOp ConvertStoreAction(VKRRenderPassStoreAction action) { // Also see https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#synchronization-pipeline-barriers-subpass-self-dependencies VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPassType rpType, VkSampleCountFlagBits sampleCount) { - bool selfDependency = RenderPassTypeHasInput(rpType); bool isBackbuffer = rpType == RenderPassType::BACKBUFFER; bool hasDepth = RenderPassTypeHasDepth(rpType); bool multiview = RenderPassTypeHasMultiView(rpType); @@ -330,7 +329,7 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas VkAttachmentReference colorReference{}; colorReference.attachment = colorAttachmentIndex; - colorReference.layout = selfDependency ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkAttachmentReference depthReference{}; depthReference.attachment = depthAttachmentIndex; @@ -339,20 +338,15 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas VkSubpassDescription subpass{}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.flags = 0; - if (selfDependency) { - subpass.inputAttachmentCount = 1; - subpass.pInputAttachments = &colorReference; - } else { - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - } + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorReference; VkAttachmentReference colorResolveReference; if (multisample) { colorResolveReference.attachment = 0; // the non-msaa color buffer. - colorResolveReference.layout = selfDependency ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorResolveReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; subpass.pResolveAttachments = &colorResolveReference; } else { subpass.pResolveAttachments = nullptr; @@ -396,17 +390,6 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas numDeps++; } - if (selfDependency) { - deps[numDeps].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - deps[numDeps].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - deps[numDeps].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - deps[numDeps].srcSubpass = 0; - deps[numDeps].dstSubpass = 0; - numDeps++; - } - if (numDeps > 0) { rp.dependencyCount = (u32)numDeps; rp.pDependencies = deps; @@ -463,10 +446,6 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas VkSubpassDescription2KHR subpass2{ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR }; subpass2.colorAttachmentCount = subpass.colorAttachmentCount; subpass2.flags = subpass.flags; - if (selfDependency) { - subpass2.inputAttachmentCount = subpass.inputAttachmentCount; - subpass2.pInputAttachments = &colorReference2; - } subpass2.pColorAttachments = &colorReference2; if (hasDepth) { subpass2.pDepthStencilAttachment = &depthReference2; @@ -476,7 +455,7 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas if (multisample) { colorResolveReference2.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; colorResolveReference2.attachment = colorResolveReference.attachment; // the non-msaa color buffer. - colorResolveReference2.layout = selfDependency ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorResolveReference2.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; subpass2.pResolveAttachments = &colorResolveReference2; } else { subpass2.pResolveAttachments = nullptr; diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.h b/Common/GPU/Vulkan/VulkanFramebuffer.h index fc584f4b8c..465983efaa 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.h +++ b/Common/GPU/Vulkan/VulkanFramebuffer.h @@ -13,15 +13,14 @@ enum class RenderPassType { // These eight are organized so that bit 0 is DEPTH and bit 1 is INPUT and bit 2 is MULTIVIEW, so // they can be OR-ed together in MergeRPTypes. HAS_DEPTH = 1, - COLOR_INPUT = 2, // input attachment - MULTIVIEW = 4, - MULTISAMPLE = 8, + MULTIVIEW = 2, + MULTISAMPLE = 4, // This is the odd one out, and gets special handling in MergeRPTypes. // If this flag is set, none of the other flags can be set. // For the backbuffer we can always use CLEAR/DONT_CARE, so bandwidth cost for a depth channel is negligible // so we don't bother with a non-depth version. - BACKBUFFER = 16, + BACKBUFFER = 8, TYPE_COUNT = BACKBUFFER + 1, }; @@ -107,10 +106,6 @@ inline bool RenderPassTypeHasDepth(RenderPassType type) { return (type & RenderPassType::HAS_DEPTH) || type == RenderPassType::BACKBUFFER; } -inline bool RenderPassTypeHasInput(RenderPassType type) { - return (type & RenderPassType::COLOR_INPUT) != 0; -} - inline bool RenderPassTypeHasMultiView(RenderPassType type) { return (type & RenderPassType::MULTIVIEW) != 0; } diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index b34435c0b2..6276205e11 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -261,31 +261,6 @@ VKRRenderPass *VulkanQueueRunner::GetRenderPass(const RPKey &key) { return pass; } -// Must match the subpass self-dependency declared above. -void VulkanQueueRunner::SelfDependencyBarrier(VKRImage &img, VkImageAspectFlags aspect, VulkanBarrier *recordBarrier) { - if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { - VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - VkAccessFlags dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - recordBarrier->TransitionImage( - img.image, - 0, - 1, - img.numLayers, - aspect, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_GENERAL, - srcAccessMask, - dstAccessMask, - srcStageMask, - dstStageMask - ); - } else { - _assert_msg_(false, "Depth self-dependencies not yet supported"); - } -} - void VulkanQueueRunner::PreprocessSteps(std::vector &steps) { // Optimizes renderpasses, then sequences them. // Planned optimizations: @@ -918,9 +893,6 @@ void VulkanQueueRunner::LogRenderPass(const VKRStep &pass, bool verbose) { case VKRRenderCommand::REMOVED: INFO_LOG(G3D, " (Removed)"); break; - case VKRRenderCommand::SELF_DEPENDENCY_BARRIER: - INFO_LOG(G3D, " SelfBarrier()"); - break; case VKRRenderCommand::BIND_GRAPHICS_PIPELINE: INFO_LOG(G3D, " BindGraphicsPipeline(%x)", (int)(intptr_t)cmd.graphics_pipeline.pipeline); break; @@ -1361,21 +1333,6 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c break; } - case VKRRenderCommand::SELF_DEPENDENCY_BARRIER: - { - _assert_(step.render.pipelineFlags & PipelineFlags::USES_INPUT_ATTACHMENT); - _assert_(fb); - VulkanBarrier barrier; - if (fb->sampleCount != VK_SAMPLE_COUNT_1_BIT) { - // Rendering is happening to the multisample buffer, not the color buffer. - SelfDependencyBarrier(fb->msaaColor, VK_IMAGE_ASPECT_COLOR_BIT, &barrier); - } else { - SelfDependencyBarrier(fb->color, VK_IMAGE_ASPECT_COLOR_BIT, &barrier); - } - barrier.Flush(cmd); - break; - } - case VKRRenderCommand::PUSH_CONSTANTS: if (pipelineOK) { vkCmdPushConstants(cmd, pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data); diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.h b/Common/GPU/Vulkan/VulkanQueueRunner.h index da0edceaf6..161e429982 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.h +++ b/Common/GPU/Vulkan/VulkanQueueRunner.h @@ -39,7 +39,6 @@ enum class VKRRenderCommand : uint8_t { DRAW, DRAW_INDEXED, PUSH_CONSTANTS, - SELF_DEPENDENCY_BARRIER, DEBUG_ANNOTATION, NUM_RENDER_COMMANDS, }; @@ -48,10 +47,9 @@ enum class PipelineFlags : u8 { NONE = 0, USES_BLEND_CONSTANT = (1 << 1), USES_DEPTH_STENCIL = (1 << 2), // Reads or writes the depth or stencil buffers. - USES_INPUT_ATTACHMENT = (1 << 3), - USES_GEOMETRY_SHADER = (1 << 4), - USES_MULTIVIEW = (1 << 5), // Inherited from the render pass it was created with. - USES_DISCARD = (1 << 6), + USES_GEOMETRY_SHADER = (1 << 3), + USES_MULTIVIEW = (1 << 4), // Inherited from the render pass it was created with. + USES_DISCARD = (1 << 5), }; ENUM_CLASS_BITOPS(PipelineFlags); @@ -314,8 +312,6 @@ private: static void SetupTransitionToTransferDst(VKRImage &img, VkImageAspectFlags aspect, VulkanBarrier *recordBarrier); static void SetupTransferDstWriteAfterWrite(VKRImage &img, VkImageAspectFlags aspect, VulkanBarrier *recordBarrier); - static void SelfDependencyBarrier(VKRImage &img, VkImageAspectFlags aspect, VulkanBarrier *recordBarrier); - VulkanContext *vulkan_; VkFramebuffer backbuffer_ = VK_NULL_HANDLE; diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index c1bde6d525..be0dd585c0 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -659,10 +659,6 @@ VKRGraphicsPipeline *VulkanRenderManager::CreateGraphicsPipeline(VKRGraphicsPipe WARN_LOG(G3D, "Not compiling pipeline that requires depth, for non depth renderpass type"); continue; } - if ((pipelineFlags & PipelineFlags::USES_INPUT_ATTACHMENT) && !RenderPassTypeHasInput(rpType)) { - WARN_LOG(G3D, "Not compiling pipeline that requires input attachment, for non input renderpass type"); - continue; - } // Shouldn't hit this, these should have been filtered elsewhere. However, still a good check to do. if (sampleCount == VK_SAMPLE_COUNT_1_BIT && RenderPassTypeHasMultisample(rpType)) { WARN_LOG(G3D, "Not compiling single sample pipeline for a multisampled render pass type"); @@ -712,10 +708,6 @@ void VulkanRenderManager::EndCurRenderStep() { if (!curRenderStep_->render.framebuffer) { rpType = RenderPassType::BACKBUFFER; } else { - if (curPipelineFlags_ & PipelineFlags::USES_INPUT_ATTACHMENT) { - // Not allowed on backbuffers. - rpType = depthStencil ? (RenderPassType::HAS_DEPTH | RenderPassType::COLOR_INPUT) : RenderPassType::COLOR_INPUT; - } // Framebuffers can be stereo, and if so, will control the render pass type to match. // Pipelines can be mono and render fine to stereo etc, so not checking them here. // Note that we don't support rendering to just one layer of a multilayer framebuffer! @@ -766,11 +758,6 @@ void VulkanRenderManager::EndCurRenderStep() { curPipelineFlags_ = (PipelineFlags)0; } -void VulkanRenderManager::BindCurrentFramebufferAsInputAttachment0(VkImageAspectFlags aspectBits) { - _dbg_assert_(curRenderStep_); - curRenderStep_->commands.push_back(VkRenderData{ VKRRenderCommand::SELF_DEPENDENCY_BARRIER }); -} - void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassLoadAction color, VKRRenderPassLoadAction depth, VKRRenderPassLoadAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { _dbg_assert_(insideFrame_); // Eliminate dupes (bind of the framebuffer we already are rendering to), instantly convert to a clear if possible. diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index d624735447..37a16975c4 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -218,8 +218,6 @@ public: // get an array texture view. VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, VkImageAspectFlags aspectBits, int layer); - void BindCurrentFramebufferAsInputAttachment0(VkImageAspectFlags aspectBits); - bool CopyFramebufferToMemory(VKRFramebuffer *src, VkImageAspectFlags aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, Draw::ReadbackMode mode, const char *tag); void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index f33e34ec06..ddd1ca220b 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -438,7 +438,6 @@ public: // These functions should be self explanatory. void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int layer) override; - void BindCurrentFramebufferForColorInput() override; void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; @@ -1011,9 +1010,9 @@ VKContext::VKContext(VulkanContext *vulkan) } } - // Limited, through input attachments and self-dependencies. - // We turn it off here already if buggy. - caps_.framebufferFetchSupported = !bugs_.Has(Bugs::SUBPASS_FEEDBACK_BROKEN); + // Vulkan can support this through input attachments and various extensions, but not worth + // the trouble. + caps_.framebufferFetchSupported = false; caps_.deviceID = deviceProps.deviceID; device_ = vulkan->GetDevice(); @@ -1777,10 +1776,6 @@ void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChanne boundImageView_[binding] = renderManager_.BindFramebufferAsTexture(fb->GetFB(), binding, aspect, layer); } -void VKContext::BindCurrentFramebufferForColorInput() { - renderManager_.BindCurrentFramebufferAsInputAttachment0(VK_IMAGE_ASPECT_COLOR_BIT); -} - void VKContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) { VKFramebuffer *fb = (VKFramebuffer *)fbo; if (fb) { diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index a529a4e300..2495051ac7 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -171,8 +171,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu bool fetchFramebuffer = needFramebufferRead && id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH); bool readFramebufferTex = needFramebufferRead && !id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH); - if (fetchFramebuffer && compat.shaderLanguage != GLSL_VULKAN && (compat.shaderLanguage != GLSL_3xx || !compat.lastFragData)) { - *errorString = "framebuffer fetch requires GLSL: vulkan or 3xx"; + if (fetchFramebuffer && (compat.shaderLanguage != GLSL_3xx || !compat.lastFragData)) { + *errorString = "framebuffer fetch requires GLSL 3xx"; return false; } @@ -204,9 +204,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (readFramebufferTex) { // The framebuffer texture is always bound as an array. p.F("layout (set = 0, binding = %d) uniform sampler2DArray fbotex;\n", DRAW_BINDING_2ND_TEXTURE); - } else if (fetchFramebuffer) { - p.F("layout (input_attachment_index = 0, set = 0, binding = %d) uniform subpassInput inputColor;\n", DRAW_BINDING_INPUT_ATTACHMENT); - *fragmentShaderFlags |= FragmentShaderFlags::INPUT_ATTACHMENT; } if (shaderDepalMode != ShaderDepalMode::OFF) { diff --git a/GPU/Common/FragmentShaderGenerator.h b/GPU/Common/FragmentShaderGenerator.h index 31923d0006..63f0a52044 100644 --- a/GPU/Common/FragmentShaderGenerator.h +++ b/GPU/Common/FragmentShaderGenerator.h @@ -46,7 +46,6 @@ struct FShaderID; // Can technically be deduced from the fragment shader ID, but this is safer. enum class FragmentShaderFlags : u32 { - INPUT_ATTACHMENT = 1, USES_DISCARD = 2, }; ENUM_CLASS_BITOPS(FragmentShaderFlags); diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index c326d2630f..f554e4e2c1 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -607,10 +607,6 @@ u32 GPUCommonHW::CheckGPUFeatures() const { features |= GPU_USE_VS_RANGE_CULLING; } - if (draw_->GetDeviceCaps().framebufferFetchSupported) { - features |= GPU_USE_FRAMEBUFFER_FETCH; - } - if (draw_->GetShaderLanguageDesc().bitwiseOps) { features |= GPU_USE_LIGHT_UBERSHADER; } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 88a722cbcd..3bcc54be3d 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -123,17 +123,12 @@ void DrawEngineVulkan::InitDeviceObjects() { bindings[8].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; bindings[8].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; bindings[8].binding = DRAW_BINDING_TESS_STORAGE_BUF_WV; - // Note: This binding is not included if !gstate_c.Use(GPU_USE_FRAMEBUFFER_FETCH), using bindingCount below. - bindings[9].descriptorCount = 1; - bindings[9].descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; - bindings[9].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[9].binding = DRAW_BINDING_INPUT_ATTACHMENT; VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); VkDevice device = vulkan->GetDevice(); VkDescriptorSetLayoutCreateInfo dsl{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; - dsl.bindingCount = gstate_c.Use(GPU_USE_FRAMEBUFFER_FETCH) ? ARRAY_SIZE(bindings) : ARRAY_SIZE(bindings) - 1; + dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); _dbg_assert_(VK_SUCCESS == res); @@ -141,17 +136,15 @@ void DrawEngineVulkan::InitDeviceObjects() { static constexpr int DEFAULT_DESC_POOL_SIZE = 512; std::vector dpTypes; - dpTypes.resize(5); + dpTypes.resize(4); dpTypes[0].descriptorCount = DEFAULT_DESC_POOL_SIZE * 3; dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; dpTypes[1].descriptorCount = DEFAULT_DESC_POOL_SIZE * 3; // Don't use these for tess anymore, need max three per set. dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; dpTypes[2].descriptorCount = DEFAULT_DESC_POOL_SIZE * 3; // TODO: Use a separate layout when no spline stuff is needed to reduce the need for these. dpTypes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - dpTypes[3].descriptorCount = DEFAULT_DESC_POOL_SIZE; // TODO: Use a separate layout when no spline stuff is needed to reduce the need for these. - dpTypes[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; - dpTypes[4].descriptorCount = DEFAULT_DESC_POOL_SIZE; // For the frame global uniform buffer. Might need to allocate multiple times. - dpTypes[4].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + dpTypes[3].descriptorCount = DEFAULT_DESC_POOL_SIZE; // For the frame global uniform buffer. Might need to allocate multiple times. + dpTypes[3].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; // Don't want to mess around with individually freeing these. @@ -386,7 +379,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView key.base_ = base; key.light_ = light; key.bone_ = bone; - key.secondaryIsInputAttachment = boundSecondaryIsInputAttachment_; FrameData &frame = GetCurFrame(); // See if we already have this descriptor set cached. @@ -425,15 +417,15 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView } if (boundSecondary_) { - tex[1].imageLayout = key.secondaryIsInputAttachment ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + tex[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; tex[1].imageView = boundSecondary_; tex[1].sampler = samplerSecondaryNearest_; writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[n].pNext = nullptr; - writes[n].dstBinding = key.secondaryIsInputAttachment ? DRAW_BINDING_INPUT_ATTACHMENT : DRAW_BINDING_2ND_TEXTURE; + writes[n].dstBinding = DRAW_BINDING_2ND_TEXTURE; writes[n].pImageInfo = &tex[1]; writes[n].descriptorCount = 1; - writes[n].descriptorType = key.secondaryIsInputAttachment ? VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writes[n].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; writes[n].dstSet = desc; n++; } diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 541263ab8a..0848028e54 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -132,8 +132,7 @@ enum { DRAW_BINDING_TESS_STORAGE_BUF = 6, DRAW_BINDING_TESS_STORAGE_BUF_WU = 7, DRAW_BINDING_TESS_STORAGE_BUF_WV = 8, - DRAW_BINDING_INPUT_ATTACHMENT = 9, - DRAW_BINDING_COUNT = 10, + DRAW_BINDING_COUNT = 9, }; // Handles transform, lighting and drawing. @@ -245,7 +244,6 @@ private: // Secondary texture for shader blending VkImageView boundSecondary_ = VK_NULL_HANDLE; - bool boundSecondaryIsInputAttachment_ = false; // CLUT texture for shader depal VkImageView boundDepal_ = VK_NULL_HANDLE; @@ -264,7 +262,6 @@ private: VkSampler sampler_; VkBuffer base_, light_, bone_; // All three UBO slots will be set to this. This will usually be identical // for all draws in a frame, except when the buffer has to grow. - bool secondaryIsInputAttachment; }; // We alternate between these. diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 959faaf666..7146123a65 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -280,7 +280,6 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { features |= GPU_USE_SINGLE_PASS_STEREO; features |= GPU_USE_SIMPLE_STEREO_PERSPECTIVE; - features &= ~GPU_USE_FRAMEBUFFER_FETCH; // Need to figure out if this can be supported with multiview rendering if (features & GPU_USE_GS_CULLING) { // Many devices that support stereo and GS don't support GS during stereo. features &= ~GPU_USE_GS_CULLING; @@ -288,15 +287,6 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { } } - // We need to turn off framebuffer fetch through input attachments if MSAA is on for now. - // This is fixable, just needs some shader generator work (subpassInputMS). - // Actually, I've decided to disable framebuffer fetch entirely for now. Perf isn't worth - // the compatibility problems. - - // if (msaaLevel_ != 0) { - features &= ~GPU_USE_FRAMEBUFFER_FETCH; - // } - // Only a few low-power GPUs should probably avoid this. // Let's figure that out later. features |= GPU_USE_FRAGMENT_UBERSHADER; diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index d5aeb8b2c5..d7d31da8b6 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -356,9 +356,6 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VulkanRenderManager * return iter; PipelineFlags pipelineFlags = (PipelineFlags)0; - if (fs->Flags() & FragmentShaderFlags::INPUT_ATTACHMENT) { - pipelineFlags |= PipelineFlags::USES_INPUT_ATTACHMENT; - } if (fs->Flags() & FragmentShaderFlags::USES_DISCARD) { pipelineFlags |= PipelineFlags::USES_DISCARD; } diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index a208c201ac..72f37813f9 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -73,7 +73,6 @@ struct VulkanPipeline { bool UsesBlendConstant() const { return (pipelineFlags & PipelineFlags::USES_BLEND_CONSTANT) != 0; } bool UsesDepthStencil() const { return (pipelineFlags & PipelineFlags::USES_DEPTH_STENCIL) != 0; } - bool UsesInputAttachment() const { return (pipelineFlags & PipelineFlags::USES_INPUT_ATTACHMENT) != 0; } bool UsesGeometryShader() const { return (pipelineFlags & PipelineFlags::USES_GEOMETRY_SHADER) != 0; } bool UsesDiscard() const { return (pipelineFlags & PipelineFlags::USES_DISCARD) != 0; } diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index fcae89a8ea..8d7cd6dc1e 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -520,7 +520,7 @@ enum class VulkanCacheDetectFlags { }; #define CACHE_HEADER_MAGIC 0xff51f420 -#define CACHE_VERSION 45 +#define CACHE_VERSION 46 struct VulkanCacheHeader { uint32_t magic; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 18bff95502..c6e65286fb 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -370,19 +370,12 @@ void DrawEngineVulkan::BindShaderBlendTex() { bool bindResult = framebufferManager_->BindFramebufferAsColorTexture(1, curRenderVfb, BINDFBCOLOR_MAY_COPY | BINDFBCOLOR_UNCACHED, Draw::ALL_LAYERS); _dbg_assert_(bindResult); boundSecondary_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE1_IMAGEVIEW); - boundSecondaryIsInputAttachment_ = false; fboTexBound_ = true; fboTexBindState_ = FBO_TEX_NONE; // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE; - } else if (fboTexBindState_ == FBO_TEX_READ_FRAMEBUFFER) { - draw_->BindCurrentFramebufferForColorInput(); - boundSecondary_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_FRAMEBUFFER_COLOR_IMAGEVIEW_RT, (void *)0); - boundSecondaryIsInputAttachment_ = true; - fboTexBindState_ = FBO_TEX_NONE; } else { - boundSecondaryIsInputAttachment_ = false; boundSecondary_ = VK_NULL_HANDLE; } }