mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
1 Commits
master
...
gs_auto_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05f5e07e2e |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -139,15 +139,12 @@ The clamp modes are also numerically based.
|
||||
|
||||
### GS Hardware Mipmap Fixes
|
||||
|
||||
* mipmap [`0` or `1`] {Off, On} Default: On (looks up GameDB)
|
||||
* mipmap [`0` or `1` or `2`] {Off, Basic, Full} Default: Automatic (No value, looks up GameDB)
|
||||
* trilinearFiltering [`0` or `1` or `2`] {None, Trilinear, Trilinear Ultra} Default: None (`0`)
|
||||
|
||||
### GS Hardware General Fixes
|
||||
|
||||
* beforeDraw {`OI` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name (ex. OI_BurnoutGames)
|
||||
|
||||
* moveHandler {`MV` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name (ex. MV_Ico)
|
||||
|
||||
* afterDraw {`OO` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name
|
||||
* conservativeFramebuffer [`0` or `1`] {Off or On} Default: On (`1`)
|
||||
* texturePreloading [`0` or `1` or `2`] {None, Partial or Full Hash Cache} Default: None (`0`)
|
||||
@@ -156,17 +153,11 @@ The clamp modes are also numerically based.
|
||||
### GS Hardware Renderer Fixes
|
||||
|
||||
* autoFlush [`0` or `1` or `2`] {Disabled, Enabled (Sprites Only), Enabled (All Primitives)} Default: Off (`0`)
|
||||
* partialTargetInvalidation [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* PCRTCOffsets [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
|
||||
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
|
||||
* disableDepthSupport [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* disablePartialInvalidation [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* cpuFramebufferConversion [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* preloadFrameData [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* textureInsideRT [`0` or `1`or `2`] {Disabled, Inside Targets, Merge Targets} Default: Off (`0`)
|
||||
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* textureInsideRT [`0` or `1`] {Disabled, Inside Targets, Merge Targets} Default: Off (`0`)
|
||||
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* cpuCLUTRender [`0` or `1` or `2`] {Disabled, Normal, Aggressive} Default: Disabled (`0`)
|
||||
* cpuSpriteRenderBW [Value between `0` to `10`] {Disabled, 1 (64), 2 (128), 3 (192), 4 (256), 5 (320), 6 (384), 7 (448), 8 (512), 9 (576), 10 (640)} Default: Off (`0`)
|
||||
|
||||
@@ -229,6 +229,11 @@
|
||||
"minimum": 0,
|
||||
"maximum": 100000
|
||||
},
|
||||
"halfBottomOverride": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"halfPixelOffset": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
|
||||
@@ -7,10 +7,16 @@
|
||||
#include "GS/GSExtra.h"
|
||||
#include "Host.h"
|
||||
|
||||
#ifdef _M_X86
|
||||
#include "GS/Renderers/DX12/GSDevice12.h"
|
||||
|
||||
#if defined(_M_X86) && defined(ENABLE_VULKAN)
|
||||
#include "GS/Renderers/Vulkan/GSDeviceVK.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "GS/Renderers/OpenGL/GSDeviceOGL.h"
|
||||
#endif
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Path.h"
|
||||
@@ -350,9 +356,9 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
const auto factory = CreateFactory(false);
|
||||
const auto adapter = GetChosenOrFirstAdapter(factory.get(), GSConfig.Adapter);
|
||||
|
||||
// If we somehow can't get a D3D11 device, it's unlikely any of the renderers are going to work.
|
||||
// If we somehow can't get a D3D11 device, it's unlikely any of the renderers are going to work, why are we here just to suffer?
|
||||
if (!adapter)
|
||||
return GSRendererType::DX11;
|
||||
return GSRendererType::Null;
|
||||
|
||||
const auto get_d3d11_feature_level = [&adapter]() -> std::optional<D3D_FEATURE_LEVEL> {
|
||||
static const D3D_FEATURE_LEVEL check[] = {
|
||||
@@ -374,13 +380,30 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
Console.WriteLn("D3D11 feature level for autodetection: %x", static_cast<unsigned>(feature_level));
|
||||
return feature_level;
|
||||
};
|
||||
const auto get_d3d12_device = [&adapter]() {
|
||||
wil::com_ptr_nothrow<ID3D12Device> device;
|
||||
const HRESULT hr = D3D12CreateDevice(adapter.get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(device.put()));
|
||||
if (FAILED(hr))
|
||||
Console.Error("D3D12CreateDevice() for automatic renderer failed: %08X", hr);
|
||||
return device;
|
||||
|
||||
static auto showUnsupportedOSD = [](const char* apiName, const char* messageId) {
|
||||
Host::AddIconOSDMessage(
|
||||
messageId,
|
||||
ICON_FA_TV,
|
||||
TRANSLATE_STR("GS",
|
||||
fmt::format(
|
||||
"The {} graphics API was automatically selected, but no compatible devices were found.\n"
|
||||
" You should update all graphics drivers in your system, including any integrated GPUs\n"
|
||||
" to use the {} renderer.",
|
||||
apiName, apiName)
|
||||
.c_str()),
|
||||
Host::OSD_WARNING_DURATION);
|
||||
};
|
||||
|
||||
static constexpr auto check_direct3d12_supported = []() {
|
||||
GSDevice12 device;
|
||||
if (device.CheckDevice())
|
||||
return true;
|
||||
|
||||
showUnsupportedOSD("Direct3D 12", "D3D12DriverUnsupported");
|
||||
return false;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VULKAN
|
||||
static constexpr auto check_for_mapping_layers = []() {
|
||||
PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
|
||||
@@ -405,19 +428,30 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
if (check_for_mapping_layers())
|
||||
return false;
|
||||
|
||||
if (!GSDeviceVK::EnumerateGPUs().empty())
|
||||
GSDeviceVK device;
|
||||
if (device.CheckDevice())
|
||||
return true;
|
||||
|
||||
Host::AddIconOSDMessage("VKDriverUnsupported", ICON_FA_TV, TRANSLATE_STR("GS",
|
||||
"The Vulkan graphics API was automatically selected, but no compatible devices were found.\n"
|
||||
" You should update all graphics drivers in your system, including any integrated GPUs\n"
|
||||
" to use the Vulkan renderer."), Host::OSD_WARNING_DURATION);
|
||||
showUnsupportedOSD("Vulkan", "VKDriverUnsupported");
|
||||
return false;
|
||||
};
|
||||
#else
|
||||
static constexpr auto check_vulkan_supported = []() { return false; };
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
static constexpr auto check_opengl_supported = []() {
|
||||
GSDeviceOGL device;
|
||||
if (device.CheckDevice())
|
||||
return true;
|
||||
|
||||
showUnsupportedOSD("OpenGL", "GLDriverUnsupported");
|
||||
return false;
|
||||
};
|
||||
#else
|
||||
static constexpr auto check_opengl_supported = []() { return false; };
|
||||
#endif
|
||||
|
||||
switch (GetVendorID(adapter.get()))
|
||||
{
|
||||
case VendorID::Nvidia:
|
||||
@@ -425,13 +459,35 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
const std::optional<D3D_FEATURE_LEVEL> feature_level = get_d3d11_feature_level();
|
||||
if (!feature_level.has_value())
|
||||
return GSRendererType::DX11;
|
||||
else if (feature_level == D3D_FEATURE_LEVEL_12_0)
|
||||
//return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::OGL;
|
||||
return GSRendererType::DX12;
|
||||
else if (feature_level == D3D_FEATURE_LEVEL_11_0)
|
||||
return GSRendererType::OGL;
|
||||
else
|
||||
|
||||
// Maxwell gen2 and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_12_0)
|
||||
{
|
||||
if (check_direct3d12_supported())
|
||||
return GSRendererType::DX12;
|
||||
|
||||
if (check_vulkan_supported())
|
||||
return GSRendererType::VK;
|
||||
|
||||
if (check_opengl_supported())
|
||||
return GSRendererType::OGL;
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
// Fermi and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
if (check_vulkan_supported())
|
||||
return GSRendererType::VK;
|
||||
|
||||
if (check_opengl_supported())
|
||||
return GSRendererType::OGL;
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
case VendorID::AMD:
|
||||
@@ -439,21 +495,53 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
const std::optional<D3D_FEATURE_LEVEL> feature_level = get_d3d11_feature_level();
|
||||
if (!feature_level.has_value())
|
||||
return GSRendererType::DX11;
|
||||
else if (feature_level == D3D_FEATURE_LEVEL_12_0)
|
||||
//return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::DX12;
|
||||
return GSRendererType::DX12;
|
||||
else if (feature_level == D3D_FEATURE_LEVEL_11_1)
|
||||
return GSRendererType::DX12;
|
||||
else
|
||||
|
||||
// GCN 5.0 and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_12_1)
|
||||
{
|
||||
if (check_direct3d12_supported())
|
||||
return GSRendererType::DX12;
|
||||
|
||||
if (check_vulkan_supported())
|
||||
return GSRendererType::VK;
|
||||
|
||||
if (check_opengl_supported())
|
||||
return GSRendererType::OGL;
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
// GCN 1.1 and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_12_0)
|
||||
{
|
||||
if (check_direct3d12_supported())
|
||||
return GSRendererType::DX12;
|
||||
|
||||
if (check_vulkan_supported())
|
||||
return GSRendererType::VK;
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
// GCN 1.0 and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_11_1)
|
||||
return GSRendererType::DX12;
|
||||
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
|
||||
case VendorID::Intel:
|
||||
{
|
||||
const std::optional<D3D_FEATURE_LEVEL> feature_level = get_d3d11_feature_level();
|
||||
if (!feature_level.has_value())
|
||||
return GSRendererType::DX11;
|
||||
|
||||
// Vulkan has broken barriers, prior to Xe.
|
||||
|
||||
// Sampler feedback Tier 0.9 is only present in Tiger Lake/Xe/Arc, so we can use that to
|
||||
// differentiate between them. Unfortunately, that requires a D3D12 device.
|
||||
// Edit: It's better to use OpenGL on intel as it has support for fb fetch.
|
||||
/*
|
||||
const auto device12 = get_d3d12_device();
|
||||
if (device12)
|
||||
{
|
||||
@@ -471,8 +559,13 @@ GSRendererType D3D::GetPreferredRenderer()
|
||||
return GSRendererType::OGL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Haswell and newer pickup.
|
||||
if (feature_level == D3D_FEATURE_LEVEL_11_1)
|
||||
if (check_opengl_supported())
|
||||
return GSRendererType::OGL;
|
||||
|
||||
Console.WriteLn("Sampler feedback tier 0.9 or Direct3D 12 not found for Intel GPU, using Direct3D 11.");
|
||||
return GSRendererType::DX11;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -831,11 +831,8 @@ bool GSDevice12::HasSurface() const
|
||||
return static_cast<bool>(m_swap_chain);
|
||||
}
|
||||
|
||||
bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
bool GSDevice12::CheckDevice()
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
u32 vendor_id = 0;
|
||||
if (!CreateDevice(vendor_id))
|
||||
return false;
|
||||
@@ -846,6 +843,17 @@ bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice12::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
if (!CheckDevice())
|
||||
return false;
|
||||
|
||||
m_name = D3D::GetAdapterName(m_adapter.get());
|
||||
|
||||
if (!CreateDescriptorHeaps() || !CreateCommandLists() || !CreateTimestampQuery())
|
||||
|
||||
@@ -429,6 +429,7 @@ public:
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool Create(GSVSyncMode vsync_mode, bool allow_present_throttle) override;
|
||||
bool CheckDevice();
|
||||
void Destroy() override;
|
||||
|
||||
bool UpdateWindow() override;
|
||||
|
||||
@@ -5910,7 +5910,6 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
|
||||
{
|
||||
case AccBlendLevel::Maximum:
|
||||
sw_blending |= true;
|
||||
accumulation_blend &= (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 32);
|
||||
[[fallthrough]];
|
||||
case AccBlendLevel::Full:
|
||||
sw_blending |= m_conf.ps.blend_a != m_conf.ps.blend_b && alpha_c0_high_max_one;
|
||||
|
||||
@@ -157,11 +157,8 @@ void GSDeviceOGL::SetVSyncMode(GSVSyncMode mode, bool allow_present_throttle)
|
||||
SetSwapInterval();
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
bool GSDeviceOGL::CheckDevice()
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
// GL is a pain and needs the window super early to create the context.
|
||||
if (!AcquireWindow(true))
|
||||
return false;
|
||||
@@ -183,6 +180,17 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
if (!CheckFeatures())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
if (!CheckDevice())
|
||||
return false;
|
||||
|
||||
// Store adapter name currently in use
|
||||
m_name = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ public:
|
||||
RenderAPI GetRenderAPI() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CheckDevice();
|
||||
bool Create(GSVSyncMode vsync_mode, bool allow_present_throttle) override;
|
||||
void Destroy() override;
|
||||
|
||||
|
||||
@@ -2065,11 +2065,8 @@ bool GSDeviceVK::HasSurface() const
|
||||
return static_cast<bool>(m_swap_chain);
|
||||
}
|
||||
|
||||
bool GSDeviceVK::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
bool GSDeviceVK::CheckDevice()
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
if (!CreateDeviceAndSwapChain())
|
||||
return false;
|
||||
|
||||
@@ -2079,6 +2076,17 @@ bool GSDeviceVK::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDeviceVK::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
{
|
||||
if (!GSDevice::Create(vsync_mode, allow_present_throttle))
|
||||
return false;
|
||||
|
||||
if (!CheckDevice())
|
||||
return false;
|
||||
|
||||
if (!CreateNullTexture())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to create dummy texture");
|
||||
|
||||
@@ -502,6 +502,7 @@ public:
|
||||
RenderAPI GetRenderAPI() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CheckDevice();
|
||||
bool Create(GSVSyncMode vsync_mode, bool allow_present_throttle) override;
|
||||
void Destroy() override;
|
||||
|
||||
|
||||
@@ -380,6 +380,7 @@ static const char* s_gs_hw_fix_names[] = {
|
||||
"trilinearFiltering",
|
||||
"skipDrawStart",
|
||||
"skipDrawEnd",
|
||||
"halfBottomOverride",
|
||||
"halfPixelOffset",
|
||||
"roundSprite",
|
||||
"nativeScaling",
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace GameDatabaseSchema
|
||||
TrilinearFiltering,
|
||||
SkipDrawStart,
|
||||
SkipDrawEnd,
|
||||
HalfBottomOverride,
|
||||
HalfPixelOffset,
|
||||
RoundSprite,
|
||||
NativeScaling,
|
||||
|
||||
@@ -163,7 +163,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
|
||||
if ((AutoDMACtrl & (Index + 1)) == 0)
|
||||
{
|
||||
ActiveTSA = 0x2000 + (Index << 10);
|
||||
DMAICounter = size * 48;
|
||||
DMAICounter = size * 4;
|
||||
LastClock = psxRegs.cycle;
|
||||
}
|
||||
else if (size >= 256)
|
||||
@@ -191,7 +191,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
|
||||
if (SPU2::MsgToConsole())
|
||||
SPU2::ConLog("ADMA%c Error Size of %x too small\n", GetDmaIndexChar(), size);
|
||||
InputDataLeft = 0;
|
||||
DMAICounter = size * 48;
|
||||
DMAICounter = size * 4;
|
||||
LastClock = psxRegs.cycle;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +248,7 @@ void V_Core::FinishDMAwrite()
|
||||
DMA7LogWrite(DMAPtr, ReadSize << 1);
|
||||
#endif
|
||||
|
||||
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 48));
|
||||
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
|
||||
u32 buff2end = 0;
|
||||
if (buff1end > 0x100000)
|
||||
{
|
||||
@@ -343,7 +343,7 @@ void V_Core::FinishDMAwrite()
|
||||
DMAPtr += TDA - ActiveTSA;
|
||||
ReadSize -= TDA - ActiveTSA;
|
||||
|
||||
DMAICounter = (DMAICounter - ReadSize) * 48;
|
||||
DMAICounter = (DMAICounter - ReadSize) * 4;
|
||||
|
||||
CounterUpdate(DMAICounter);
|
||||
|
||||
@@ -354,7 +354,7 @@ void V_Core::FinishDMAwrite()
|
||||
|
||||
void V_Core::FinishDMAread()
|
||||
{
|
||||
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 48));
|
||||
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
|
||||
u32 buff2end = 0;
|
||||
|
||||
if (buff1end > 0x100000)
|
||||
@@ -426,9 +426,9 @@ void V_Core::FinishDMAread()
|
||||
|
||||
// DMA Reads are done AFTER the delay, so to get the timing right we need to scheule one last DMA to catch IRQ's
|
||||
if (ReadSize)
|
||||
DMAICounter = std::min(ReadSize, (u32)0x100) * 48;
|
||||
DMAICounter = std::min(ReadSize, (u32)0x100) * 4;
|
||||
else
|
||||
DMAICounter = 48;
|
||||
DMAICounter = 4;
|
||||
|
||||
CounterUpdate(DMAICounter);
|
||||
|
||||
@@ -446,7 +446,7 @@ void V_Core::DoDMAread(u16* pMem, u32 size)
|
||||
ReadSize = size;
|
||||
IsDMARead = true;
|
||||
LastClock = psxRegs.cycle;
|
||||
DMAICounter = (std::min(ReadSize, (u32)0x100) * 48);
|
||||
DMAICounter = std::min(ReadSize, (u32)0x100) * 4;
|
||||
Regs.STATX &= ~0x80;
|
||||
Regs.STATX |= 0x400;
|
||||
//Regs.ATTR |= 0x30;
|
||||
@@ -470,7 +470,7 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size)
|
||||
{
|
||||
Regs.STATX &= ~0x80;
|
||||
//Regs.ATTR |= 0x30;
|
||||
DMAICounter = 1 * 48;
|
||||
DMAICounter = 1 * 4;
|
||||
LastClock = psxRegs.cycle;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user