From ae47ac19b861695653586220f19b2adb1ac1daff Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 9 Jan 2023 17:50:46 +0100 Subject: [PATCH] dx11: check supported texture formats. Fix fb render not working if 1st Check supported texture formats including mipmap and mipmap autogen. Fall back to 8888 format. tentative fix for MINIDUMP-17, MINIDUMP-1R and MINIDUMP-1M RenderFramebuffer wasn't working if first render after init. --- core/rend/dx11/dx11_renderer.cpp | 1 + core/rend/dx11/dx11_texture.cpp | 6 ++++ core/rend/dx11/dx11context.cpp | 53 +++++++++++++++++++++++++++---- core/rend/dx11/dx11context.h | 5 +++ core/rend/dx11/dx11context_lr.cpp | 5 ++- core/rend/dx11/dx11context_lr.h | 7 ++++ 6 files changed, 69 insertions(+), 8 deletions(-) diff --git a/core/rend/dx11/dx11_renderer.cpp b/core/rend/dx11/dx11_renderer.cpp index c8ecdf56d..cc38e95f1 100644 --- a/core/rend/dx11/dx11_renderer.cpp +++ b/core/rend/dx11/dx11_renderer.cpp @@ -909,6 +909,7 @@ void DX11Renderer::RenderFramebuffer(const FramebufferInfo& info) deviceContext->UpdateSubresource(dcfbTexture, 0, nullptr, pb.data(), width * sizeof(u32), width * sizeof(u32) * height); + resize(width, height); deviceContext->OMSetRenderTargets(1, &fbRenderTarget.get(), depthTexView); float colors[4]; info.vo_border_col.getRGBColor(colors); diff --git a/core/rend/dx11/dx11_texture.cpp b/core/rend/dx11/dx11_texture.cpp index a3942b43f..5f14cfb86 100644 --- a/core/rend/dx11/dx11_texture.cpp +++ b/core/rend/dx11/dx11_texture.cpp @@ -94,6 +94,10 @@ void DX11Texture::UploadToGPU(int width, int height, const u8* temp_tex_buffer, viewDesc.Texture2D.MipLevels = desc.MipLevels == 0 ? -1 : desc.MipLevels; theDX11Context.getDevice()->CreateShaderResourceView(texture, &viewDesc, &textureView.get()); } + else + { + ERROR_LOG(RENDERER, "Texture creation failed type %d dim %dx%d mipmap %d (included %d)", tex_type, width, height, mipmapped, mipmapsIncluded); + } verify(texture != nullptr); verify(textureView != nullptr); } @@ -112,6 +116,8 @@ void DX11Texture::UploadToGPU(int width, int height, const u8* temp_tex_buffer, #ifndef TARGET_UWP bool DX11Texture::Force32BitTexture(TextureType type) const { + if (!theDX11Context.textureFormatSupported(type)) + return true; if (IsWindows8OrGreater()) return false; // DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM and DXGI_FORMAT_B5G6R5_UNORM diff --git a/core/rend/dx11/dx11context.cpp b/core/rend/dx11/dx11context.cpp index d24314f2b..fcf04e897 100644 --- a/core/rend/dx11/dx11context.cpp +++ b/core/rend/dx11/dx11context.cpp @@ -57,12 +57,13 @@ bool DX11Context::init(bool keepCurrentWindow) D3D_FEATURE_LEVEL featureLevels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; - D3D11CreateDevice( + HRESULT hr; + hr = D3D11CreateDevice( nullptr, // Specify nullptr to use the default adapter. D3D_DRIVER_TYPE_HARDWARE, nullptr, @@ -73,6 +74,10 @@ bool DX11Context::init(bool keepCurrentWindow) &pDevice.get(), &featureLevel, &pDeviceContext.get()); + if (FAILED(hr)) { + WARN_LOG(RENDERER, "D3D11 device creation failed: %x", hr); + return false; + } ComPtr dxgiDevice; pDevice.as(dxgiDevice); @@ -92,7 +97,6 @@ bool DX11Context::init(bool keepCurrentWindow) ComPtr dxgiFactory2; dxgiFactory.as(dxgiFactory2); - HRESULT hr; if (dxgiFactory2) { @@ -156,8 +160,10 @@ bool DX11Context::init(bool keepCurrentWindow) resize(); shaders.init(pDevice, &D3DCompile); overlay.init(pDevice, pDeviceContext, &shaders, &samplers); - - return true; + bool success = checkTextureSupport(); + if (!success) + term(); + return success; } void DX11Context::term() @@ -301,3 +307,36 @@ void DX11Context::handleDeviceLost() } #endif // !LIBRETRO +bool DX11Context::checkTextureSupport() +{ + const DXGI_FORMAT formats[] = { DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_A8_UNORM }; + const char * const fmtNames[] = { "B5G5R5A1", "B4G4R4A4", "B5G6R5", "B8G8R8A8", "A8" }; + const TextureType dcTexTypes[] = { TextureType::_5551, TextureType::_4444, TextureType::_565, TextureType::_8888, TextureType::_8 }; + UINT support; + for (size_t i = 0; i < ARRAY_SIZE(formats); i++) + { + supportedTexFormats[(int)dcTexTypes[i]] = false; + pDevice->CheckFormatSupport(formats[i], &support); + if ((support & (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) + { + if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM) + { + // Can't do much without this format + ERROR_LOG(RENDERER, "Fatal: Format %s not supported", fmtNames[i]); + return false; + } + WARN_LOG(RENDERER, "Format %s not supported", fmtNames[i]); + } + else + { + if ((support & D3D11_FORMAT_SUPPORT_MIP) == 0) + WARN_LOG(RENDERER, "Format %s doesn't support mipmaps", fmtNames[i]); + else if ((support & (D3D11_FORMAT_SUPPORT_MIP_AUTOGEN | D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != (D3D11_FORMAT_SUPPORT_MIP_AUTOGEN | D3D11_FORMAT_SUPPORT_RENDER_TARGET)) + WARN_LOG(RENDERER, "Format %s doesn't support mipmap autogen", fmtNames[i]); + else + supportedTexFormats[(int)dcTexTypes[i]] = true; + } + } + + return true; +} diff --git a/core/rend/dx11/dx11context.h b/core/rend/dx11/dx11context.h index 5861d21b1..90854bdc8 100644 --- a/core/rend/dx11/dx11context.h +++ b/core/rend/dx11/dx11context.h @@ -68,9 +68,13 @@ public: bool hasShaderCache() const { return _hasShaderCache; } + bool textureFormatSupported(TextureType texType) { + return supportedTexFormats[(int)texType]; + } private: void handleDeviceLost(); + bool checkTextureSupport(); ComPtr pDevice; ComPtr pDeviceContext; @@ -88,6 +92,7 @@ private: DX11Shaders shaders; Samplers samplers; D3D_FEATURE_LEVEL featureLevel{}; + bool supportedTexFormats[5] {}; // indexed by TextureType enum static constexpr UINT VENDOR_INTEL = 0x8086; }; diff --git a/core/rend/dx11/dx11context_lr.cpp b/core/rend/dx11/dx11context_lr.cpp index 217156337..f06ff7b92 100644 --- a/core/rend/dx11/dx11context_lr.cpp +++ b/core/rend/dx11/dx11context_lr.cpp @@ -53,7 +53,10 @@ bool DX11Context::init(ID3D11Device *device, ID3D11DeviceContext *deviceContext, shaders.init(pDevice, D3DCompile); overlay.init(pDevice, pDeviceContext, &shaders, &samplers); - return true; + bool success = checkTextureSupport(); + if (!success) + term(); + return success; } void DX11Context::term() diff --git a/core/rend/dx11/dx11context_lr.h b/core/rend/dx11/dx11context_lr.h index f62d6ae9a..e10866324 100644 --- a/core/rend/dx11/dx11context_lr.h +++ b/core/rend/dx11/dx11context_lr.h @@ -59,7 +59,13 @@ public: } void drawOverlay(int width, int height); + bool textureFormatSupported(TextureType texType) { + return supportedTexFormats[(int)texType]; + } + private: + bool checkTextureSupport(); + ComPtr pDevice; ComPtr pDeviceContext; pD3DCompile D3DCompile = nullptr; @@ -69,6 +75,7 @@ private: Samplers samplers; DX11Overlay overlay; D3D_FEATURE_LEVEL featureLevel{}; + bool supportedTexFormats[5] {}; // indexed by TextureType enum static constexpr UINT VENDOR_INTEL = 0x8086; };