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.
This commit is contained in:
Henrik Rydgård 2023-06-13 20:46:27 +02:00
parent 0037a9703c
commit 6d8069dfd1
17 changed files with 25 additions and 158 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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<VKRStep *> &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);

View file

@ -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;

View file

@ -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.

View file

@ -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);

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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;
}

View file

@ -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<VkDescriptorPoolSize> 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++;
}

View file

@ -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.

View file

@ -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;

View file

@ -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;
}

View file

@ -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; }

View file

@ -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;

View file

@ -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;
}
}