diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 502d2c06db..bf33fd34ca 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -646,6 +646,63 @@ void D3D9Context::InvalidateCachedState() { curPipeline_ = nullptr; } +// TODO: Move this detection elsewhere when it's needed elsewhere, not before. It's ugly. +// Source: https://envytools.readthedocs.io/en/latest/hw/pciid.html#gf100 +enum NVIDIAGeneration { + NV_PRE_KEPLER, + NV_KEPLER, + NV_MAXWELL, + NV_PASCAL, + NV_VOLTA, + NV_TURING, // or later +}; + +static NVIDIAGeneration NVIDIAGetDeviceGeneration(int deviceID) { + if (deviceID >= 0x1180 && deviceID <= 0x11bf) + return NV_KEPLER; // GK104 + if (deviceID >= 0x11c0 && deviceID <= 0x11fa) + return NV_KEPLER; // GK106 + if (deviceID >= 0x0fc0 && deviceID <= 0x0fff) + return NV_KEPLER; // GK107 + if (deviceID >= 0x1003 && deviceID <= 0x1028) + return NV_KEPLER; // GK110(B) + if (deviceID >= 0x1280 && deviceID <= 0x12ba) + return NV_KEPLER; // GK208 + if (deviceID >= 0x1381 && deviceID <= 0x13b0) + return NV_MAXWELL; // GM107 + if (deviceID >= 0x1340 && deviceID <= 0x134d) + return NV_MAXWELL; // GM108 + if (deviceID >= 0x13c0 && deviceID <= 0x13d9) + return NV_MAXWELL; // GM204 + if (deviceID >= 0x1401 && deviceID <= 0x1427) + return NV_MAXWELL; // GM206 + if (deviceID >= 0x15f7 && deviceID <= 0x15f9) + return NV_PASCAL; // GP100 + if (deviceID >= 0x15f7 && deviceID <= 0x15f9) + return NV_PASCAL; // GP100 + if (deviceID >= 0x1b00 && deviceID <= 0x1b38) + return NV_PASCAL; // GP102 + if (deviceID >= 0x1b80 && deviceID <= 0x1be1) + return NV_PASCAL; // GP104 + if (deviceID >= 0x1c02 && deviceID <= 0x1c62) + return NV_PASCAL; // GP106 + if (deviceID >= 0x1c81 && deviceID <= 0x1c92) + return NV_PASCAL; // GP107 + if (deviceID >= 0x1d01 && deviceID <= 0x1d12) + return NV_PASCAL; // GP108 + if (deviceID >= 0x1d81 && deviceID <= 0x1dba) + return NV_VOLTA; // GV100 + if (deviceID >= 0x1e02 && deviceID <= 0x1e3c) + return NV_TURING; // TU102 + if (deviceID >= 0x1e82 && deviceID <= 0x1ed0) + return NV_TURING; // TU104 + if (deviceID >= 0x1f02 && deviceID <= 0x1f51) + return NV_TURING; // TU104 + if (deviceID >= 0x1e02) + return NV_TURING; // More TU models or later, probably. + return NV_PRE_KEPLER; +} + #define FB_DIV 1 #define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))) @@ -704,6 +761,21 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID caps_.textureNPOTFullySupported = true; } + // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. + // Also causes problems on old NVIDIA. + switch (caps_.vendor) { + case Draw::GPUVendor::VENDOR_INTEL: + bugs_.Infest(Bugs::BROKEN_NAN_IN_CONDITIONAL); + break; + case Draw::GPUVendor::VENDOR_NVIDIA: + // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. + // No idea if KEPLER is the right cutoff, but let's go with it. + if (NVIDIAGetDeviceGeneration(caps_.deviceID) < NV_KEPLER) { + bugs_.Infest(Bugs::BROKEN_NAN_IN_CONDITIONAL); + } + break; + } + if (d3d) { D3DDISPLAYMODE displayMode; d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode); diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index bd4d131e98..a5a35e3c12 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -111,19 +111,6 @@ u32 GPU_D3D11::CheckGPUFeatures() const { features |= GPU_SUPPORTS_DEPTH_TEXTURE; if (draw_->GetDeviceCaps().depthClampSupported) features |= GPU_SUPPORTS_DEPTH_CLAMP; - if (draw_->GetDeviceCaps().clipDistanceSupported) - features |= GPU_SUPPORTS_CLIP_DISTANCE; - if (draw_->GetDeviceCaps().cullDistanceSupported) - features |= GPU_SUPPORTS_CULL_DISTANCE; - if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { - // Ignore the compat setting if clip and cull are both enabled. - // When supported, we can do the depth side of range culling more correctly. - const bool supported = draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported; - const bool disabled = PSP_CoreParameter().compat.flags().DisableRangeCulling; - if (supported || !disabled) { - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - } - } features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 0ec02a3595..f11286a29d 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -98,63 +98,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) } } -// TODO: Move this detection elsewhere when it's needed elsewhere, not before. It's ugly. -// Source: https://envytools.readthedocs.io/en/latest/hw/pciid.html#gf100 -enum NVIDIAGeneration { - NV_PRE_KEPLER, - NV_KEPLER, - NV_MAXWELL, - NV_PASCAL, - NV_VOLTA, - NV_TURING, // or later -}; - -static NVIDIAGeneration NVIDIAGetDeviceGeneration(int deviceID) { - if (deviceID >= 0x1180 && deviceID <= 0x11bf) - return NV_KEPLER; // GK104 - if (deviceID >= 0x11c0 && deviceID <= 0x11fa) - return NV_KEPLER; // GK106 - if (deviceID >= 0x0fc0 && deviceID <= 0x0fff) - return NV_KEPLER; // GK107 - if (deviceID >= 0x1003 && deviceID <= 0x1028) - return NV_KEPLER; // GK110(B) - if (deviceID >= 0x1280 && deviceID <= 0x12ba) - return NV_KEPLER; // GK208 - if (deviceID >= 0x1381 && deviceID <= 0x13b0) - return NV_MAXWELL; // GM107 - if (deviceID >= 0x1340 && deviceID <= 0x134d) - return NV_MAXWELL; // GM108 - if (deviceID >= 0x13c0 && deviceID <= 0x13d9) - return NV_MAXWELL; // GM204 - if (deviceID >= 0x1401 && deviceID <= 0x1427) - return NV_MAXWELL; // GM206 - if (deviceID >= 0x15f7 && deviceID <= 0x15f9) - return NV_PASCAL; // GP100 - if (deviceID >= 0x15f7 && deviceID <= 0x15f9) - return NV_PASCAL; // GP100 - if (deviceID >= 0x1b00 && deviceID <= 0x1b38) - return NV_PASCAL; // GP102 - if (deviceID >= 0x1b80 && deviceID <= 0x1be1) - return NV_PASCAL; // GP104 - if (deviceID >= 0x1c02 && deviceID <= 0x1c62) - return NV_PASCAL; // GP106 - if (deviceID >= 0x1c81 && deviceID <= 0x1c92) - return NV_PASCAL; // GP107 - if (deviceID >= 0x1d01 && deviceID <= 0x1d12) - return NV_PASCAL; // GP108 - if (deviceID >= 0x1d81 && deviceID <= 0x1dba) - return NV_VOLTA; // GV100 - if (deviceID >= 0x1e02 && deviceID <= 0x1e3c) - return NV_TURING; // TU102 - if (deviceID >= 0x1e82 && deviceID <= 0x1ed0) - return NV_TURING; // TU104 - if (deviceID >= 0x1f02 && deviceID <= 0x1f51) - return NV_TURING; // TU104 - if (deviceID >= 0x1e02) - return NV_TURING; // More TU models or later, probably. - return NV_PRE_KEPLER; -} - u32 GPU_DX9::CheckGPUFeatures() const { u32 features = GPUCommon::CheckGPUFeatures(); features |= GPU_SUPPORTS_16BIT_FORMATS; @@ -167,24 +110,6 @@ u32 GPU_DX9::CheckGPUFeatures() const { features |= GPU_SUPPORTS_ACCURATE_DEPTH; auto vendor = draw_->GetDeviceCaps().vendor; - if (!PSP_CoreParameter().compat.flags().DisableRangeCulling) { - // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. - // Also causes problems on old NVIDIA. - switch (vendor) { - case Draw::GPUVendor::VENDOR_INTEL: - break; - case Draw::GPUVendor::VENDOR_NVIDIA: - // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. - // No idea if KEPLER is the right cutoff, but let's go with it. - if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) { - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - } - break; - default: - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - break; - } - } if (!g_Config.bHighQualityDepth) { features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 7d9ce963a3..d394407721 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -166,9 +166,6 @@ u32 GPU_GLES::CheckGPUFeatures() const { if (gl_extensions.GLES3 || !gl_extensions.IsGLES) features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - if (draw_->GetDeviceCaps().anisoSupported) - features |= GPU_SUPPORTS_ANISOTROPY; - bool canUseInstanceID = gl_extensions.EXT_draw_instanced || gl_extensions.ARB_draw_instanced; bool canDefInstanceID = gl_extensions.IsGLES || gl_extensions.EXT_gpu_shader4 || gl_extensions.VersionGEThan(3, 1); bool instanceRendering = gl_extensions.GLES3 || (canUseInstanceID && canDefInstanceID); @@ -189,19 +186,6 @@ u32 GPU_GLES::CheckGPUFeatures() const { } if (draw_->GetDeviceCaps().textureDepthSupported) features |= GPU_SUPPORTS_DEPTH_TEXTURE; - if (draw_->GetDeviceCaps().clipDistanceSupported) - features |= GPU_SUPPORTS_CLIP_DISTANCE; - if (draw_->GetDeviceCaps().cullDistanceSupported) - features |= GPU_SUPPORTS_CULL_DISTANCE; - if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { - // Ignore the compat setting if clip and cull are both enabled. - // When supported, we can do the depth side of range culling more correctly. - const bool supported = draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported; - const bool disabled = PSP_CoreParameter().compat.flags().DisableRangeCulling; - if (supported || !disabled) { - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - } - } // If we already have a 16-bit depth buffer, we don't need to round. bool prefer24 = draw_->GetDeviceCaps().preferredDepthBufferFormat == Draw::DataFormat::D24_S8; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index ea63b7a02b..a3f1d5cd7d 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -3174,6 +3174,24 @@ u32 GPUCommon::CheckGPUFeatures() const { features |= GPU_SUPPORTS_BLEND_MINMAX; } + if (draw_->GetDeviceCaps().clipDistanceSupported) { + features |= GPU_SUPPORTS_CLIP_DISTANCE; + } + + if (draw_->GetDeviceCaps().cullDistanceSupported) { + features |= GPU_SUPPORTS_CULL_DISTANCE; + } + + if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { + // Ignore the compat setting if clip and cull are both enabled. + // When supported, we can do the depth side of range culling more correctly. + const bool supported = draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported; + const bool disabled = PSP_CoreParameter().compat.flags().DisableRangeCulling; + if (supported || !disabled) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } + } + if (PSP_CoreParameter().compat.flags().ClearToRAM) { features |= GPU_USE_CLEAR_RAM_HACK; } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 636f852666..1dca91ddcd 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -236,22 +236,6 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { if (enabledFeatures.depthClamp) { features |= GPU_SUPPORTS_DEPTH_CLAMP; } - if (enabledFeatures.shaderClipDistance) { - features |= GPU_SUPPORTS_CLIP_DISTANCE; - } - if (enabledFeatures.shaderCullDistance) { - // Must support at least 8 if feature supported, so we're fine. - features |= GPU_SUPPORTS_CULL_DISTANCE; - } - if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { - // Ignore the compat setting if clip and cull are both enabled. - // When supported, we can do the depth side of range culling more correctly. - const bool supported = draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported; - const bool disabled = PSP_CoreParameter().compat.flags().DisableRangeCulling; - if (supported || !disabled) { - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - } - } // These are VULKAN_4444_FORMAT and friends. uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::B4G4R4A4_UNORM_PACK16);