Merge pull request #10290 from OatmealDome/m1-earlyz-bug

DriverDetails: Add broken discard with early-Z bug on Apple Silicon GPUs
This commit is contained in:
JMC47
2022-04-24 13:30:04 -04:00
committed by GitHub
6 changed files with 144 additions and 65 deletions

View File

@ -132,53 +132,65 @@ static VkPipelineDepthStencilStateCreateInfo GetVulkanDepthStencilState(const De
};
}
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendingState& state)
static VkPipelineColorBlendAttachmentState
GetVulkanAttachmentBlendState(const BlendingState& state, AbstractPipelineUsage usage)
{
VkPipelineColorBlendAttachmentState vk_state = {};
vk_state.blendEnable = static_cast<VkBool32>(state.blendenable);
vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
bool use_dual_source =
state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
bool use_shader_blend = !use_dual_source && state.usedualsrc && state.dstalpha &&
g_ActiveConfig.backend_info.bSupportsFramebufferFetch;
if (use_dual_source)
if (use_shader_blend || (usage == AbstractPipelineUsage::GX &&
DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z)))
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
vk_state.blendEnable = VK_FALSE;
}
else
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.blendEnable = static_cast<VkBool32>(state.blendenable);
vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
if (use_dual_source)
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
}
else
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
}
}
if (state.colorupdate)
@ -338,7 +350,7 @@ std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& con
VkPipelineDepthStencilStateCreateInfo depth_stencil_state =
GetVulkanDepthStencilState(config.depth_state);
VkPipelineColorBlendAttachmentState blend_attachment_state =
GetVulkanAttachmentBlendState(config.blending_state);
GetVulkanAttachmentBlendState(config.blending_state, config.usage);
VkPipelineColorBlendStateCreateInfo blend_state =
GetVulkanColorBlendState(config.blending_state, &blend_attachment_state, 1);

View File

@ -371,6 +371,13 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
// with depth clamping. Fall back to inverted depth range for these.
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_REVERSED_DEPTH_RANGE))
config->backend_info.bSupportsReversedDepthRange = false;
// Calling discard when early depth test is enabled can break on some Apple Silicon GPU drivers.
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z))
{
// We will use shader blending, so disable hardware dual source blending.
config->backend_info.bSupportsDualSourceBlend = false;
}
}
void VulkanContext::PopulateBackendInfoMultisampleModes(
@ -922,6 +929,11 @@ void VulkanContext::InitDriverDetails()
vendor = DriverDetails::VENDOR_IMGTEC;
driver = DriverDetails::DRIVER_IMGTEC;
}
else if (device_name.find("Apple") != std::string::npos)
{
vendor = DriverDetails::VENDOR_APPLE;
driver = DriverDetails::DRIVER_PORTABILITY;
}
else
{
WARN_LOG_FMT(VIDEO, "Unknown Vulkan driver vendor, please report it to us.");