diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp index a635d7c969..18dda66297 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.cpp +++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp @@ -66,7 +66,7 @@ bool Create(u32 adapter_index, bool enable_debug_layer) HRESULT hr = dxgi_factory->EnumAdapters(adapter_index, adapter.GetAddressOf()); if (FAILED(hr)) { - WARN_LOG_FMT(VIDEO, "Adapter {} not found, using default", adapter_index); + WARN_LOG_FMT(VIDEO, "Adapter {} not found, using default: {}", adapter_index, DX11HRWrap(hr)); adapter = nullptr; } @@ -80,7 +80,7 @@ bool Create(u32 adapter_index, bool enable_debug_layer) D3D11_SDK_VERSION, device.GetAddressOf(), &feature_level, context.GetAddressOf()); // Debugbreak on D3D error - if (SUCCEEDED(hr) && SUCCEEDED(device.As(&s_debug))) + if (SUCCEEDED(hr) && SUCCEEDED(hr = device.As(&s_debug))) { ComPtr info_queue; if (SUCCEEDED(s_debug.As(&info_queue))) @@ -98,7 +98,7 @@ bool Create(u32 adapter_index, bool enable_debug_layer) } else { - WARN_LOG_FMT(VIDEO, "Debug layer requested but not available."); + WARN_LOG_FMT(VIDEO, "Debug layer requested but not available: {}", DX11HRWrap(hr)); } } @@ -113,7 +113,8 @@ bool Create(u32 adapter_index, bool enable_debug_layer) if (FAILED(hr)) { PanicAlertFmtT( - "Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"); + "Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0\n{0}", + DX11HRWrap(hr)); dxgi_factory.Reset(); D3DCommon::UnloadLibraries(); s_d3d11_library.Close(); @@ -123,7 +124,9 @@ bool Create(u32 adapter_index, bool enable_debug_layer) hr = device.As(&device1); if (FAILED(hr)) { - WARN_LOG_FMT(VIDEO, "Missing Direct3D 11.1 support. Logical operations will not be supported."); + WARN_LOG_FMT(VIDEO, + "Missing Direct3D 11.1 support. Logical operations will not be supported.\n{}", + DX11HRWrap(hr)); } stateman = std::make_unique(); diff --git a/Source/Core/VideoBackends/D3D/D3DBase.h b/Source/Core/VideoBackends/D3D/D3DBase.h index 443500c966..03872b0240 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.h +++ b/Source/Core/VideoBackends/D3D/D3DBase.h @@ -7,12 +7,12 @@ #include #include #include +#include #include #include -#include "Common/Common.h" #include "Common/CommonTypes.h" -#include "Common/MsgHandler.h" +#include "Common/HRWrap.h" namespace DX11 { @@ -41,4 +41,32 @@ bool SupportsLogicOp(u32 adapter_index); } // namespace D3D +// Wrapper for HRESULT to be used with fmt. Note that we can't create a fmt::formatter directly +// for HRESULT as HRESULT is simply a typedef on long and not a distinct type. +// Unlike the version in Common, this variant also knows to call GetDeviceRemovedReason if needed. +struct DX11HRWrap +{ + constexpr explicit DX11HRWrap(HRESULT hr) : m_hr(hr) {} + const HRESULT m_hr; +}; + } // namespace DX11 + +template <> +struct fmt::formatter +{ + constexpr auto parse(fmt::format_parse_context& ctx) { return ctx.begin(); } + template + auto format(const DX11::DX11HRWrap& hr, FormatContext& ctx) + { + if (hr.m_hr == DXGI_ERROR_DEVICE_REMOVED && DX11::D3D::device != nullptr) + { + return fmt::format_to(ctx.out(), "{}\nDevice removal reason: {}", Common::HRWrap(hr.m_hr), + Common::HRWrap(DX11::D3D::device->GetDeviceRemovedReason())); + } + else + { + return fmt::format_to(ctx.out(), "{}", Common::HRWrap(hr.m_hr)); + } + } +}; diff --git a/Source/Core/VideoBackends/D3D/D3DBoundingBox.cpp b/Source/Core/VideoBackends/D3D/D3DBoundingBox.cpp index 56ff1ad5b2..2eb6da73df 100644 --- a/Source/Core/VideoBackends/D3D/D3DBoundingBox.cpp +++ b/Source/Core/VideoBackends/D3D/D3DBoundingBox.cpp @@ -35,7 +35,7 @@ bool D3DBoundingBox::Initialize() data.SysMemSlicePitch = 0; HRESULT hr; hr = D3D::device->CreateBuffer(&desc, &data, &m_buffer); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox Buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox Buffer: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; D3DCommon::SetDebugObjectName(m_buffer.Get(), "BoundingBox Buffer"); @@ -45,7 +45,8 @@ bool D3DBoundingBox::Initialize() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.BindFlags = 0; hr = D3D::device->CreateBuffer(&desc, nullptr, &m_staging_buffer); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox Staging Buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox Staging Buffer: {}", + DX11HRWrap(hr)); if (FAILED(hr)) return false; D3DCommon::SetDebugObjectName(m_staging_buffer.Get(), "BoundingBox Staging Buffer"); @@ -58,7 +59,7 @@ bool D3DBoundingBox::Initialize() UAVdesc.Buffer.Flags = 0; UAVdesc.Buffer.NumElements = NUM_BBOX_VALUES; hr = D3D::device->CreateUnorderedAccessView(m_buffer.Get(), &UAVdesc, &m_uav); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox UAV"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create BoundingBox UAV: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; D3DCommon::SetDebugObjectName(m_uav.Get(), "BoundingBox UAV"); diff --git a/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp b/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp index 76eeef6ec3..b7aeab512c 100644 --- a/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp +++ b/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp @@ -183,7 +183,7 @@ ID3D11InputLayout* D3DVertexFormat::GetInputLayout(const void* vs_bytecode, size HRESULT hr = D3D::device->CreateInputLayout(m_elems.data(), m_num_elems, vs_bytecode, vs_bytecode_size, &layout); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create input layout"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create input layout: {}", DX11HRWrap(hr)); // This method can be called from multiple threads, so ensure that only one thread sets the // cached input layout pointer. If another thread beats this thread, use the existing layout. diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index a5aa2f863e..9a568ae6e4 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -349,7 +349,7 @@ ID3D11SamplerState* StateCache::Get(SamplerState state) ComPtr res; HRESULT hr = D3D::device->CreateSamplerState(&sampdc, res.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D sampler state failed"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D sampler state failed: {}", DX11HRWrap(hr)); return m_sampler.emplace(state, std::move(res)).first->second.Get(); } @@ -387,7 +387,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state) { return m_blend.emplace(state.hex, std::move(res)).first->second.Get(); } - WARN_LOG_FMT(VIDEO, "Creating D3D blend state failed with an error: {:08X}", hr); + WARN_LOG_FMT(VIDEO, "Creating D3D blend state failed with an error: {}", DX11HRWrap(hr)); } D3D11_BLEND_DESC desc = {}; @@ -426,7 +426,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state) ComPtr res; HRESULT hr = D3D::device->CreateBlendState(&desc, res.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D blend state failed"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D blend state failed: {}", DX11HRWrap(hr)); return m_blend.emplace(state.hex, std::move(res)).first->second.Get(); } @@ -447,7 +447,7 @@ ID3D11RasterizerState* StateCache::Get(RasterizationState state) ComPtr res; HRESULT hr = D3D::device->CreateRasterizerState(&desc, res.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D rasterizer state failed"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D rasterizer state failed: {}", DX11HRWrap(hr)); return m_raster.emplace(state.hex, std::move(res)).first->second.Get(); } @@ -489,7 +489,7 @@ ID3D11DepthStencilState* StateCache::Get(DepthState state) ComPtr res; HRESULT hr = D3D::device->CreateDepthStencilState(&depthdc, res.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D depth stencil state failed"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating D3D depth stencil state failed: {}", DX11HRWrap(hr)); return m_depth.emplace(state.hex, std::move(res)).first->second.Get(); } diff --git a/Source/Core/VideoBackends/D3D/D3DSwapChain.cpp b/Source/Core/VideoBackends/D3D/D3DSwapChain.cpp index a79e0e3829..c3f2a9094a 100644 --- a/Source/Core/VideoBackends/D3D/D3DSwapChain.cpp +++ b/Source/Core/VideoBackends/D3D/D3DSwapChain.cpp @@ -31,7 +31,7 @@ bool SwapChain::CreateSwapChainBuffers() { ComPtr texture; HRESULT hr = m_swap_chain->GetBuffer(0, IID_PPV_ARGS(&texture)); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to get swap chain buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to get swap chain buffer: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; diff --git a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp index 05d76805c0..318559affa 100644 --- a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp @@ -34,7 +34,8 @@ static ComPtr AllocateConstantBuffer(u32 size) D3D11_CPU_ACCESS_WRITE); ComPtr cbuf; const HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &cbuf); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create shader constant buffer (size={})", cbsize); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create shader constant buffer (size={}): {}", cbsize, + DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -60,7 +61,7 @@ CreateTexelBufferView(ID3D11Buffer* buffer, TexelBufferFormat format, DXGI_FORMA VertexManager::TEXEL_STREAM_BUFFER_SIZE / VertexManager::GetTexelBufferElementSize(format)); HRESULT hr = D3D::device->CreateShaderResourceView(buffer, &srv_desc, &srv); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create SRV for texel buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create SRV for texel buffer: {}", DX11HRWrap(hr)); return srv; } @@ -80,7 +81,7 @@ bool VertexManager::Initialize() for (int i = 0; i < BUFFER_COUNT; i++) { HRESULT hr = D3D::device->CreateBuffer(&bufdesc, nullptr, &m_buffers[i]); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create buffer: {}", DX11HRWrap(hr)); if (m_buffers[i]) D3DCommon::SetDebugObjectName(m_buffers[i].Get(), "Buffer of VertexManager"); } @@ -94,7 +95,7 @@ bool VertexManager::Initialize() CD3D11_BUFFER_DESC texel_buf_desc(TEXEL_STREAM_BUFFER_SIZE, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); HRESULT hr = D3D::device->CreateBuffer(&texel_buf_desc, nullptr, &m_texel_buffer); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating texel buffer failed"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Creating texel buffer failed: {}", DX11HRWrap(hr)); if (!m_texel_buffer) return false; @@ -132,7 +133,7 @@ bool VertexManager::MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE& { // Restart buffer. HRESULT hr = D3D::context->Map(m_texel_buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map texel buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map texel buffer: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; @@ -142,7 +143,7 @@ bool VertexManager::MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE& { // Don't overwrite the earlier-used space. HRESULT hr = D3D::context->Map(m_texel_buffer.Get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &sr); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map texel buffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map texel buffer: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; } diff --git a/Source/Core/VideoBackends/D3D/DXShader.cpp b/Source/Core/VideoBackends/D3D/DXShader.cpp index 533bb3a2a7..8ee6b0aecc 100644 --- a/Source/Core/VideoBackends/D3D/DXShader.cpp +++ b/Source/Core/VideoBackends/D3D/DXShader.cpp @@ -55,7 +55,7 @@ std::unique_ptr DXShader::CreateFromBytecode(ShaderStage stage, Binary { ComPtr vs; HRESULT hr = D3D::device->CreateVertexShader(bytecode.data(), bytecode.size(), nullptr, &vs); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create vertex shader"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create vertex shader: {}", DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -66,7 +66,7 @@ std::unique_ptr DXShader::CreateFromBytecode(ShaderStage stage, Binary { ComPtr gs; HRESULT hr = D3D::device->CreateGeometryShader(bytecode.data(), bytecode.size(), nullptr, &gs); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create geometry shader"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create geometry shader: {}", DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -78,7 +78,7 @@ std::unique_ptr DXShader::CreateFromBytecode(ShaderStage stage, Binary { ComPtr ps; HRESULT hr = D3D::device->CreatePixelShader(bytecode.data(), bytecode.size(), nullptr, &ps); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create pixel shader"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create pixel shader: {}", DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -90,7 +90,7 @@ std::unique_ptr DXShader::CreateFromBytecode(ShaderStage stage, Binary { ComPtr cs; HRESULT hr = D3D::device->CreateComputeShader(bytecode.data(), bytecode.size(), nullptr, &cs); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create compute shader"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create compute shader: {}", DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp index 0f72ec9c98..f3e6912337 100644 --- a/Source/Core/VideoBackends/D3D/DXTexture.cpp +++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp @@ -51,8 +51,8 @@ std::unique_ptr DXTexture::Create(const TextureConfig& config, std::s HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf()); if (FAILED(hr)) { - PanicAlertFmt("Failed to create {}x{}x{} D3D backing texture", config.width, config.height, - config.layers); + PanicAlertFmt("Failed to create {}x{}x{} D3D backing texture: {}", config.width, config.height, + config.layers, DX11HRWrap(hr)); return nullptr; } @@ -98,8 +98,8 @@ bool DXTexture::CreateSRV() HRESULT hr = D3D::device->CreateShaderResourceView(m_texture.Get(), &desc, m_srv.GetAddressOf()); if (FAILED(hr)) { - PanicAlertFmt("Failed to create {}x{}x{} D3D SRV", m_config.width, m_config.height, - m_config.layers); + PanicAlertFmt("Failed to create {}x{}x{} D3D SRV: {}", m_config.width, m_config.height, + m_config.layers, DX11HRWrap(hr)); return false; } @@ -115,8 +115,8 @@ bool DXTexture::CreateUAV() HRESULT hr = D3D::device->CreateUnorderedAccessView(m_texture.Get(), &desc, m_uav.GetAddressOf()); if (FAILED(hr)) { - PanicAlertFmt("Failed to create {}x{}x{} D3D UAV", m_config.width, m_config.height, - m_config.layers); + PanicAlertFmt("Failed to create {}x{}x{} D3D UAV: {}", m_config.width, m_config.height, + m_config.layers, DX11HRWrap(hr)); return false; } @@ -207,7 +207,7 @@ std::unique_ptr DXStagingTexture::Create(StagingTextureType ty ComPtr texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, texture.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create staging texture"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create staging texture: {}", DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -298,7 +298,7 @@ bool DXStagingTexture::Map() D3D11_MAPPED_SUBRESOURCE sr; HRESULT hr = D3D::context->Map(m_tex.Get(), 0, map_type, 0, &sr); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map readback texture"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to map readback texture: {}", DX11HRWrap(hr)); if (FAILED(hr)) return false; @@ -363,7 +363,8 @@ std::unique_ptr DXFramebuffer::Create(DXTexture* color_attachment color_attachment->GetLayers()); HRESULT hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc, rtv.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create render target view for framebuffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create render target view for framebuffer: {}", + DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; @@ -376,7 +377,7 @@ std::unique_ptr DXFramebuffer::Create(DXTexture* color_attachment hr = D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc, integer_rtv.GetAddressOf()); ASSERT_MSG(VIDEO, SUCCEEDED(hr), - "Failed to create integer render target view for framebuffer"); + "Failed to create integer render target view for framebuffer: {}", DX11HRWrap(hr)); } } @@ -390,7 +391,8 @@ std::unique_ptr DXFramebuffer::Create(DXTexture* color_attachment depth_attachment->GetLayers(), 0); HRESULT hr = D3D::device->CreateDepthStencilView(depth_attachment->GetD3DTexture(), &desc, dsv.GetAddressOf()); - ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create depth stencil view for framebuffer"); + ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create depth stencil view for framebuffer: {}", + DX11HRWrap(hr)); if (FAILED(hr)) return nullptr; }