From 424a02cdf3276122bf2d1ac4d02fa1b34f393f1d Mon Sep 17 00:00:00 2001 From: flyinghead Date: Sun, 22 Dec 2019 17:48:24 +0100 Subject: [PATCH] vulkan: workaround for intel driver bug when depth write is disabled backport adreno driver translucent modvol workaround --- core/rend/vulkan/oit/oit_drawer.cpp | 3 ++- core/rend/vulkan/oit/oit_drawer.h | 3 +++ core/rend/vulkan/oit/oit_pipeline.cpp | 3 ++- core/rend/vulkan/oit/oit_shaders.cpp | 2 +- core/rend/vulkan/pipeline.cpp | 3 ++- core/rend/vulkan/quad.h | 9 +++++++-- core/rend/vulkan/vulkan_context.cpp | 16 +++++++++++++++- core/rend/vulkan/vulkan_context.h | 8 ++++++++ core/rend/vulkan/vulkan_renderer.cpp | 3 +++ 9 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/rend/vulkan/oit/oit_drawer.cpp b/core/rend/vulkan/oit/oit_drawer.cpp index 010486a15..3dfc92044 100644 --- a/core/rend/vulkan/oit/oit_drawer.cpp +++ b/core/rend/vulkan/oit/oit_drawer.cpp @@ -347,7 +347,8 @@ bool OITDrawer::Draw(const Texture *fogTexture) if (!oitBuffers->isFirstFrameAfterInit()) { // Tr modifier volumes - DrawModifierVolumes(cmdBuffer, previous_pass.mvo_tr_count, current_pass.mvo_tr_count - previous_pass.mvo_tr_count); + if (!GetContext()->GetVendorID() != VENDOR_QUALCOMM) // Adreno bug + DrawModifierVolumes(cmdBuffer, previous_pass.mvo_tr_count, current_pass.mvo_tr_count - previous_pass.mvo_tr_count); vk::Pipeline pipeline = pipelineManager->GetFinalPipeline(current_pass.autosort); cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); diff --git a/core/rend/vulkan/oit/oit_drawer.h b/core/rend/vulkan/oit/oit_drawer.h index 9cdc7b10f..411477827 100644 --- a/core/rend/vulkan/oit/oit_drawer.h +++ b/core/rend/vulkan/oit/oit_drawer.h @@ -67,6 +67,8 @@ protected: quadBuffer.reset(); colorAttachments[0].reset(); colorAttachments[1].reset(); + tempFramebuffers[0].reset(); + tempFramebuffers[1].reset(); depthAttachment.reset(); mainBuffers.clear(); descriptorSets.clear(); @@ -205,6 +207,7 @@ public: { colorAttachment.reset(); framebuffers.clear(); + rttPipelineManager.reset(); OITDrawer::Term(); } diff --git a/core/rend/vulkan/oit/oit_pipeline.cpp b/core/rend/vulkan/oit/oit_pipeline.cpp index 385ac1cd5..5c7791aad 100644 --- a/core/rend/vulkan/oit/oit_pipeline.cpp +++ b/core/rend/vulkan/oit/oit_pipeline.cpp @@ -60,7 +60,8 @@ void OITPipelineManager::CreatePipeline(u32 listType, bool autosort, const PolyP else depthOp = depthOps[pp.isp.DepthMode]; bool depthWriteEnable; - if (pass != 0) + // FIXME temporary Intel driver bug workaround + if (pass != 0 && (GetContext()->GetVendorID() != VENDOR_INTEL || pass != 1)) depthWriteEnable = false; // Z Write Disable seems to be ignored for punch-through. // Fixes Worms World Party, Bust-a-Move 4 and Re-Volt diff --git a/core/rend/vulkan/oit/oit_shaders.cpp b/core/rend/vulkan/oit/oit_shaders.cpp index 14a96fab1..9c54b65ee 100644 --- a/core/rend/vulkan/oit/oit_shaders.cpp +++ b/core/rend/vulkan/oit/oit_shaders.cpp @@ -614,7 +614,7 @@ vec4 resolveAlphaBlend(ivec2 coords) { vec4 finalColor = subpassLoad(tex); vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer - float depth = 1.0; + float depth = 0.0; bool do_depth_test = false; for (int i = 0; i < num_frag; i++) diff --git a/core/rend/vulkan/pipeline.cpp b/core/rend/vulkan/pipeline.cpp index 0a06ba5dc..6b8e2dfa6 100644 --- a/core/rend/vulkan/pipeline.cpp +++ b/core/rend/vulkan/pipeline.cpp @@ -206,7 +206,8 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol depthOp = depthOps[pp.isp.DepthMode]; bool depthWriteEnable; if (sortTriangles && !settings.rend.PerStripSorting) - depthWriteEnable = false; + // FIXME temporary work-around for intel driver bug + depthWriteEnable = GetContext()->GetVendorID() == VENDOR_INTEL; else { // Z Write Disable seems to be ignored for punch-through. diff --git a/core/rend/vulkan/quad.h b/core/rend/vulkan/quad.h index 4f74873fa..cbcec1f7f 100644 --- a/core/rend/vulkan/quad.h +++ b/core/rend/vulkan/quad.h @@ -71,7 +71,13 @@ class QuadPipeline { public: void Init(ShaderManager *shaderManager, vk::RenderPass renderPass); - + void Term() { + pipeline.reset(); + sampler.reset(); + descriptorSets.clear(); + pipelineLayout.reset(); + descSetLayout.reset(); + } vk::Pipeline GetPipeline() { if (!pipeline) @@ -80,7 +86,6 @@ public: } void SetTexture(vk::ImageView imageView); - void BindDescriptorSets(vk::CommandBuffer cmdBuffer); private: diff --git a/core/rend/vulkan/vulkan_context.cpp b/core/rend/vulkan/vulkan_context.cpp index b83953ae1..f9ccbd5d1 100644 --- a/core/rend/vulkan/vulkan_context.cpp +++ b/core/rend/vulkan/vulkan_context.cpp @@ -189,7 +189,20 @@ bool VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co #endif #endif - physicalDevice = instance->enumeratePhysicalDevices().front(); + // Choose a discrete gpu if there's one, otherwise just pick the first one + const auto devices = instance->enumeratePhysicalDevices(); + for (const auto& phyDev : devices) + { + vk::PhysicalDeviceProperties props; + phyDev.getProperties(&props); + if (props.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) + { + physicalDevice = phyDev; + break; + } + } + if (!physicalDevice) + physicalDevice = instance->enumeratePhysicalDevices().front(); const vk::PhysicalDeviceProperties *properties; if (vulkan11 || getProperties2KHRSupported) @@ -217,6 +230,7 @@ bool VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co storageBufferAlignment = properties->limits.minStorageBufferOffsetAlignment; maxStorageBufferRange = properties->limits.maxStorageBufferRange; unifiedMemory = properties->deviceType == vk::PhysicalDeviceType::eIntegratedGpu; + vendorID = properties->vendorID; NOTICE_LOG(RENDERER, "Vulkan API %s. Device %s", vulkan11 ? "1.1" : "1.0", properties->deviceName); vk::FormatProperties formatProperties = physicalDevice.getFormatProperties(vk::Format::eR5G5B5A1UnormPack16); diff --git a/core/rend/vulkan/vulkan_context.h b/core/rend/vulkan/vulkan_context.h index f9d0702cd..679d712b2 100644 --- a/core/rend/vulkan/vulkan_context.h +++ b/core/rend/vulkan/vulkan_context.h @@ -26,6 +26,12 @@ extern int screen_width, screen_height; +#define VENDOR_AMD 0x1022 +#define VENDOR_ARM 0x13B5 +#define VENDOR_INTEL 0x8086 +#define VENDOR_NVIDIA 0x10DE +#define VENDOR_QUALCOMM 0x5143 + class VulkanContext { public: @@ -96,6 +102,7 @@ public: bool IsUnifiedMemory() const { return unifiedMemory; } u32 GetMaxStorageBufferRange() const { return maxStorageBufferRange; } vk::DeviceSize GetMaxMemoryAllocationSize() const { return maxMemoryAllocationSize; } + u32 GetVendorID() const { return vendorID; } private: vk::Format FindDepthFormat(); @@ -157,6 +164,7 @@ private: bool samplerAnisotropy = false; bool dedicatedAllocationSupported = false; bool unifiedMemory = false; + u32 vendorID = 0; vk::UniqueDevice device; #ifdef USE_SDL diff --git a/core/rend/vulkan/vulkan_renderer.cpp b/core/rend/vulkan/vulkan_renderer.cpp index b81bae9e5..da0733539 100644 --- a/core/rend/vulkan/vulkan_renderer.cpp +++ b/core/rend/vulkan/vulkan_renderer.cpp @@ -96,6 +96,9 @@ public: DEBUG_LOG(RENDERER, "VulkanRenderer::Term"); GetContext()->WaitIdle(); quadBuffer = nullptr; + quadPipeline.Term(); + osdBuffer.reset(); + vjoyTexture.reset(); textureCache.Clear(); fogTexture = nullptr; texCommandPool.Term();