diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index faafc4998e..aa52c919dd 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -312,6 +312,12 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de caps_.isTilingGPU = false; + // Hide D3D9 when we know it likely won't work well. + caps_.supportsD3D9 = true; + if (!strcmp(adapterDesc_.c_str(), "Intel(R) Iris(R) Xe Graphics")) { + caps_.supportsD3D9 = false; + } + // Temp texture for read-back of small images. Custom textures are created on demand for larger ones. // TODO: Should really benchmark if this extra complexity has any benefit. D3D11_TEXTURE2D_DESC packDesc{}; diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index bc0135e834..a4d668e369 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -773,6 +773,11 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID caps_.textureNPOTFullySupported = true; } + caps_.supportsD3D9 = true; + if (!strcmp(identifier_.Description, "Intel(R) Iris(R) Xe Graphics")) { + caps_.supportsD3D9 = false; + } + // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. // Also causes problems on old NVIDIA. switch (caps_.vendor) { @@ -1254,10 +1259,10 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) { D3D9Framebuffer *fbo = new D3D9Framebuffer(desc.width, desc.height); fbo->depthstenciltex = nullptr; - HRESULT rtResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL); + HRESULT rtResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, nullptr); if (FAILED(rtResult)) { ERROR_LOG(G3D, "Failed to create render target"); - delete fbo; + fbo->Release(); return NULL; } fbo->tex->GetSurfaceLevel(0, &fbo->surf); @@ -1286,9 +1291,15 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) { } D3D9Framebuffer::~D3D9Framebuffer() { - tex->Release(); - surf->Release(); - depthstencil->Release(); + if (tex) { + tex->Release(); + } + if (surf) { + surf->Release(); + } + if (depthstencil) { + depthstencil->Release(); + } if (depthstenciltex) { depthstenciltex->Release(); } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index c9edb68502..b7737bd919 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -611,6 +611,14 @@ OpenGLContext::OpenGLContext() { break; } + // Hide D3D9 when we know it likely won't work well. +#if PPSSPP_PLATFORM(WINDOWS) + caps_.supportsD3D9 = true; + if (!strcmp(gl_extensions.model, "Intel(R) Iris(R) Xe Graphics")) { + caps_.supportsD3D9 = false; + } +#endif + // Very rough heuristic! caps_.isTilingGPU = gl_extensions.IsGLES && caps_.vendor != GPUVendor::VENDOR_NVIDIA && caps_.vendor != GPUVendor::VENDOR_INTEL; diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index 4cc760f429..422c288083 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -861,6 +861,14 @@ VKContext::VKContext(VulkanContext *vulkan) } caps_.isTilingGPU = hasLazyMemory && caps_.vendor != GPUVendor::VENDOR_APPLE; + // Hide D3D9 when we know it likely won't work well. +#if PPSSPP_PLATFORM(WINDOWS) + caps_.supportsD3D9 = true; + if (!strcmp(deviceProps.deviceName, "Intel(R) Iris(R) Xe Graphics")) { + caps_.supportsD3D9 = false; + } +#endif + // VkSampleCountFlagBits is arranged correctly for our purposes. // Only support MSAA levels that have support for all three of color, depth, stencil. if (!caps_.isTilingGPU) { diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 76afa314be..5d68541f3e 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -578,6 +578,9 @@ struct DeviceCaps { bool isTilingGPU; // This means that it benefits from correct store-ops, msaa without backing memory, etc. bool sampleRateShadingSupported; + // From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it. + bool supportsD3D9; + u32 multiSampleLevelsMask; // Bit n is set if (1 << n) is a valid multisample level. Bit 0 is always set. std::string deviceName; // The device name to use when creating the thin3d context, to get the same one. }; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 9ca9ce1282..536a5f4426 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -262,9 +262,14 @@ void GameSettingsScreen::CreateViews() { graphicsSettings->Add(new ItemHeader(gr->T("Rendering Mode"))); + Draw::DrawContext *draw = screenManager()->getDrawContext(); + #if !PPSSPP_PLATFORM(UWP) static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" }; PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), gr->GetName(), screenManager())); + if (g_Config.iGPUBackend != (int)GPUBackend::DIRECT3D9 && !draw->GetDeviceCaps().supportsD3D9) { + renderingBackendChoice->HideChoice(1); + } renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend); if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL)) @@ -282,8 +287,6 @@ void GameSettingsScreen::CreateViews() { } #endif - Draw::DrawContext *draw = screenManager()->getDrawContext(); - // Backends that don't allow a device choice will only expose one device. if (draw->GetDeviceList().size() > 1) { std::string *deviceNameSetting = GPUDeviceNameSetting();