mirror of
https://git.citron-emu.org/Citron/Citron.git
synced 2025-03-15 03:14:50 +00:00
vulkan: Implement AMD driver workaround for logic operations
- Added conditional check for AMD graphics drivers - Automatically disable logic operations when float vertex attributes are present to work around driver quirks - Maintain original logic op state to preserve emulator behavior - Prepare dynamic state management infrastructure for future OpenGL implementation changes OpenGL implementation will follow in subsequent commits. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
parent
12c63997d2
commit
f2931c7566
1 changed files with 35 additions and 1 deletions
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -928,6 +929,8 @@ bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info,
|
||||||
|
|
||||||
void RasterizerVulkan::UpdateDynamicStates() {
|
void RasterizerVulkan::UpdateDynamicStates() {
|
||||||
auto& regs = maxwell3d->regs;
|
auto& regs = maxwell3d->regs;
|
||||||
|
|
||||||
|
// Always update base dynamic states.
|
||||||
UpdateViewportsState(regs);
|
UpdateViewportsState(regs);
|
||||||
UpdateScissorsState(regs);
|
UpdateScissorsState(regs);
|
||||||
UpdateDepthBias(regs);
|
UpdateDepthBias(regs);
|
||||||
|
@ -935,7 +938,9 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
||||||
UpdateDepthBounds(regs);
|
UpdateDepthBounds(regs);
|
||||||
UpdateStencilFaces(regs);
|
UpdateStencilFaces(regs);
|
||||||
UpdateLineWidth(regs);
|
UpdateLineWidth(regs);
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||||
|
// Update extended dynamic states.
|
||||||
UpdateCullMode(regs);
|
UpdateCullMode(regs);
|
||||||
UpdateDepthCompareOp(regs);
|
UpdateDepthCompareOp(regs);
|
||||||
UpdateFrontFace(regs);
|
UpdateFrontFace(regs);
|
||||||
|
@ -946,16 +951,44 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
||||||
UpdateDepthTestEnable(regs);
|
UpdateDepthTestEnable(regs);
|
||||||
UpdateDepthWriteEnable(regs);
|
UpdateDepthWriteEnable(regs);
|
||||||
UpdateStencilTestEnable(regs);
|
UpdateStencilTestEnable(regs);
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicState2Supported()) {
|
if (device.IsExtExtendedDynamicState2Supported()) {
|
||||||
UpdatePrimitiveRestartEnable(regs);
|
UpdatePrimitiveRestartEnable(regs);
|
||||||
UpdateRasterizerDiscardEnable(regs);
|
UpdateRasterizerDiscardEnable(regs);
|
||||||
UpdateDepthBiasEnable(regs);
|
UpdateDepthBiasEnable(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
|
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
|
||||||
UpdateLogicOpEnable(regs);
|
// Store the original logic_op.enable state.
|
||||||
|
const auto oldLogicOpEnable = regs.logic_op.enable;
|
||||||
|
|
||||||
|
// Determine if the current driver is an AMD driver.
|
||||||
|
bool isAmdDriver = (device.GetDriverID() == VK_DRIVER_ID_AMD_OPEN_SOURCE ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_AMD_PROPRIETARY ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_AMD_PROPRIETARY_KHR ||
|
||||||
|
device.GetDriverID() == VK_DRIVER_ID_MESA_RADV);
|
||||||
|
|
||||||
|
if (isAmdDriver) {
|
||||||
|
// Check if any vertex attribute is of type Float.
|
||||||
|
bool hasFloat = std::any_of(
|
||||||
|
regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(),
|
||||||
|
[](const auto& attrib) {
|
||||||
|
return attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::Float;
|
||||||
|
});
|
||||||
|
|
||||||
|
// For AMD drivers, disable logic_op if a float attribute is present.
|
||||||
|
regs.logic_op.enable = static_cast<u32>(!hasFloat);
|
||||||
|
UpdateLogicOpEnable(regs);
|
||||||
|
// Restore the original value.
|
||||||
|
regs.logic_op.enable = oldLogicOpEnable;
|
||||||
|
} else {
|
||||||
|
UpdateLogicOpEnable(regs);
|
||||||
|
}
|
||||||
UpdateDepthClampEnable(regs);
|
UpdateDepthClampEnable(regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.IsExtExtendedDynamicState2ExtrasSupported()) {
|
if (device.IsExtExtendedDynamicState2ExtrasSupported()) {
|
||||||
UpdateLogicOp(regs);
|
UpdateLogicOp(regs);
|
||||||
}
|
}
|
||||||
|
@ -963,6 +996,7 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
||||||
UpdateBlending(regs);
|
UpdateBlending(regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.IsExtVertexInputDynamicStateSupported()) {
|
if (device.IsExtVertexInputDynamicStateSupported()) {
|
||||||
UpdateVertexInput(regs);
|
UpdateVertexInput(regs);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue