Compare commits

...
5 Commits
Author SHA1 Message Date
chaoticgd e1bbcfc414 VIF: Fix out of bounds read caused by broken alignment logic 2026-09-13 08:41:13 +02:00
lightningterror 7a9af33f7d GS: Update intel igpu/dgpu auto renderer.
Ivy Bridge and below default to Direct3D11.

Haswell/Broadwell default to OpenGL.

Skylake and above default to Direct3D12.
2026-09-13 06:01:25 +02:00
lightningterror f8ea1477f6 GS/GL: Check if RGBA16 UNORM is hw blendable, if not then fallback to RGBA16 Float. 2026-09-13 05:48:46 +02:00
lightningterror f13b70f6a0 GS/GL: Use correct formats for ColorHQ, ColorHDR.
ColorHQ: GL_RGB10_A2.
ColorHDR: GL_RGBA16F.
2026-09-13 05:48:46 +02:00
lightningterror 393278fe4d GS: Make sure ColorHDR is treated as a feedbackloop format.
It is used as a fallback when hw blending isn't supported on RGBA16 UNORM.
2026-09-13 05:48:46 +02:00
6 changed files with 73 additions and 31 deletions
+1 -1
View File
@@ -200,7 +200,7 @@ u32 GSTexture::CalcUploadSize(Format format, u32 height, u32 pitch)
bool GSTexture::IsFeedbackFormat(Format format)
{
return format == Format::Color || format == Format::ColorClip ||
return format == Format::Color || format == Format::ColorClip || format == Format::ColorHDR ||
format == Format::DepthColor || format == Format::DepthStencil;
}
+29 -14
View File
@@ -374,6 +374,8 @@ 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()));
@@ -381,6 +383,7 @@ GSRendererType D3D::GetPreferredRenderer()
Console.Error("D3D12CreateDevice() for automatic renderer failed: %08X", hr);
return device;
};
#ifdef ENABLE_VULKAN
static constexpr auto check_vulkan_supported = []() {
if (!GSDeviceVK::EnumerateGPUs().empty())
@@ -395,6 +398,7 @@ GSRendererType D3D::GetPreferredRenderer()
#else
static constexpr auto check_vulkan_supported = []() { return false; };
#endif
*/
switch (GetVendorID(adapter.get()))
{
@@ -432,26 +436,37 @@ GSRendererType D3D::GetPreferredRenderer()
// 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.
const auto device12 = get_d3d12_device();
if (device12)
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)
{
D3D12_FEATURE_DATA_D3D12_OPTIONS7 opts = {};
if (SUCCEEDED(device12->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &opts, sizeof(opts))) &&
(opts.SamplerFeedbackTier >= D3D12_SAMPLER_FEEDBACK_TIER_0_9) &&
check_vulkan_supported())
return GSRendererType::DX12;
/*
// Keep the old code as a reference if we need it.
const auto device12 = get_d3d12_device();
if (device12)
{
Console.WriteLn("Sampler feedback tier 0.9 found for Intel GPU, defaulting to Vulkan.");
return GSRendererType::VK;
D3D12_FEATURE_DATA_D3D12_OPTIONS7 opts = {};
if (SUCCEEDED(device12->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &opts, sizeof(opts))) &&
(opts.SamplerFeedbackTier >= D3D12_SAMPLER_FEEDBACK_TIER_0_9) &&
check_vulkan_supported())
{
Console.WriteLn("Sampler feedback tier 0.9 found for Intel GPU, defaulting to Vulkan.");
return GSRendererType::VK;
}
else
return GSRendererType::OGL;
}
else
{
Console.WriteLn("Sampler feedback tier 0.9 or Vulkan not found for Intel GPU, using OpenGL.");
return GSRendererType::OGL;
}
*/
}
Console.WriteLn("Sampler feedback tier 0.9 or Direct3D 12 not found for Intel GPU, using Direct3D 11.");
return GSRendererType::DX11;
else if (feature_level == D3D_FEATURE_LEVEL_11_1)
return GSRendererType::OGL;
else
return GSRendererType::DX11;
}
break;
+23 -11
View File
@@ -724,9 +724,9 @@ bool GSDeviceOGL::CreateTextureFX()
bool GSDeviceOGL::CheckFeatures()
{
//bool vendor_id_amd = false;
//bool vendor_id_nvidia = false;
//bool vendor_id_intel = false;
bool vendor_id_amd = false;
bool vendor_id_nvidia = false;
bool vendor_id_intel = false;
memset(&m_bugs, 0, sizeof(m_bugs));
@@ -735,18 +735,18 @@ bool GSDeviceOGL::CheckFeatures()
std::strstr(vendor, "ATI"))
{
Console.WriteLn(Color_StrongRed, "GL: AMD GPU detected.");
//vendor_id_amd = true;
vendor_id_amd = true;
}
else if (std::strstr(vendor, "NVIDIA Corporation"))
{
Console.WriteLn(Color_StrongGreen, "GL: NVIDIA GPU detected.");
//vendor_id_nvidia = true;
vendor_id_nvidia = true;
m_bugs.broken_blend_coherency = true;
}
else if (std::strstr(vendor, "Intel"))
{
Console.WriteLn(Color_StrongBlue, "GL: Intel GPU detected.");
//vendor_id_intel = true;
vendor_id_intel = true;
}
GLint major_gl = 0;
@@ -906,15 +906,27 @@ bool GSDeviceOGL::CheckFeatures()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
m_max_texture_size = std::max(1024u, static_cast<u32>(max_texture_size));
Console.WriteLn("GL: Using %s for point expansion, %s for line expansion and %s for sprite expansion.",
m_features.point_expand ? "hardware" : (m_features.vs_expand ? "vertex expanding" : "UNSUPPORTED"),
m_features.line_expand ? "hardware" : (m_features.vs_expand ? "vertex expanding" : "UNSUPPORTED"),
m_features.vs_expand ? "vertex expanding" : "CPU");
// Unlikely to be supported on Windows if device is stuck on GL 3.3 which is usually equivalent to feature level 10.0.
// This should also target any proprietary drivers on linux.
// Open source drivers shouldn't be hit since they have different vendor names.
if ((vendor_id_amd || vendor_id_nvidia || vendor_id_intel) && GLAD_GL_VERSION_3_3 && !GLAD_GL_VERSION_4_0)
m_rgba16_unorm_hw_blend = false;
else
m_rgba16_unorm_hw_blend = true;
if (!GLAD_GL_ARB_conservative_depth)
{
Console.Warning("GLAD_GL_ARB_conservative_depth is not supported. This will reduce performance.");
}
Console.WriteLn("GL: Using %s for point expansion, %s for line expansion and %s for sprite expansion.",
m_features.point_expand ? "hardware" : (m_features.vs_expand ? "vertex expanding" : "UNSUPPORTED"),
m_features.line_expand ? "hardware" : (m_features.vs_expand ? "vertex expanding" : "UNSUPPORTED"),
m_features.vs_expand ? "vertex expanding" : "CPU");
Console.WriteLnFmt("GL: DXTn Texture Compression: {}", m_features.dxt_textures ? "Supported" : "Not Supported");
Console.WriteLnFmt("GL: BC6/7 Texture Compression: {}", m_features.bptc_textures ? "Supported" : "Not Supported");
Console.WriteLnFmt("GL: RGBA16 UNORM Hardware Blending: {}", m_rgba16_unorm_hw_blend ? "Supported" : "Not Supported");
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.feedback_loops();
@@ -2898,7 +2910,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
{
config.colclip_update_area = config.drawarea;
colclip_rt = CreateFeedbackTarget(rtsize.x, rtsize.y, GSTexture::Format::ColorClip, false);
colclip_rt = CreateFeedbackTarget(rtsize.x, rtsize.y, m_rgba16_unorm_hw_blend ? GSTexture::Format::ColorClip : GSTexture::Format::ColorHDR, false);
if (!colclip_rt)
{
+1
View File
@@ -159,6 +159,7 @@ private:
} m_bugs;
bool m_disable_download_pbo = false;
bool m_rgba16_unorm_hw_blend = false;
GLuint m_fbo = 0; // frame buffer container
GLuint m_fbo_read = 0; // frame buffer container only for reading
+18 -4
View File
@@ -34,7 +34,7 @@ GSTextureOGL::GSTextureOGL(Usage usage, int width, int height, int levels, Forma
// Bunch of constant parameter
switch (m_format)
{
// 1 Channel integer
// 1 channel integer
case Format::PrimID:
m_gl_format = GL_R32F;
m_int_format = GL_RED;
@@ -54,7 +54,7 @@ GSTextureOGL::GSTextureOGL(Usage usage, int width, int height, int levels, Forma
m_int_shift = 1;
break;
// 1 Channel normalized
// 1 channel normalized
case Format::UNorm8:
m_gl_format = GL_R8;
m_int_format = GL_RED;
@@ -72,15 +72,29 @@ GSTextureOGL::GSTextureOGL(Usage usage, int width, int height, int levels, Forma
// 4 channel normalized
case Format::Color:
case Format::ColorHQ:
case Format::ColorHDR:
m_gl_format = GL_RGBA8;
m_int_format = GL_RGBA;
m_int_type = GL_UNSIGNED_BYTE;
m_int_shift = 2;
break;
// 4 channel normalized with 2 bits of alpha
case Format::ColorHQ:
m_gl_format = GL_RGB10_A2;
m_int_format = GL_RGBA;
m_int_type = GL_UNSIGNED_INT_2_10_10_10_REV;
m_int_shift = 2;
break;
// 4 channel float
case Format::ColorHDR:
m_gl_format = GL_RGBA16F;
m_int_format = GL_RGBA;
m_int_type = GL_HALF_FLOAT;
m_int_shift = 3;
break;
// 4 channel normalized
case Format::ColorClip:
m_gl_format = GL_RGBA16;
m_int_format = GL_RGBA;
+1 -1
View File
@@ -361,7 +361,7 @@ _vifT int nVifUnpack(const u8* data)
_nVifUnpack(idx, data, vifRegs.mode, isFill);
}
else
vu1Thread.VifUnpack(vif, vifRegs, (u8*)data, (size + 4) & ~0x3);
vu1Thread.VifUnpack(vif, vifRegs, (u8*)data, size);
vif.pass = 0;
vif.tag.size = 0;