diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp index c3978ad137..a04f80656c 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.cpp +++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp @@ -32,6 +32,7 @@ namespace D3D ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; static IDXGISwapChain* swapchain = nullptr; +static ID3D11Debug* debug = nullptr; D3D_FEATURE_LEVEL featlevel; D3DTexture2D* backbuf = nullptr; HWND hWnd; @@ -263,8 +264,7 @@ HRESULT Create(HWND wnd) UpdateActiveConfig(); } - DXGI_SWAP_CHAIN_DESC swap_chain_desc; - memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); + DXGI_SWAP_CHAIN_DESC swap_chain_desc = {}; swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; @@ -272,12 +272,10 @@ HRESULT Create(HWND wnd) swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = !g_Config.bFullscreen; - DXGI_OUTPUT_DESC out_desc; - memset(&out_desc, 0, sizeof(out_desc)); + DXGI_OUTPUT_DESC out_desc = {}; output->GetDesc(&out_desc); - DXGI_MODE_DESC mode_desc; - memset(&mode_desc, 0, sizeof(mode_desc)); + DXGI_MODE_DESC mode_desc = {}; mode_desc.Width = out_desc.DesktopCoordinates.right - out_desc.DesktopCoordinates.left; mode_desc.Height = out_desc.DesktopCoordinates.bottom - out_desc.DesktopCoordinates.top; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -302,6 +300,27 @@ HRESULT Create(HWND wnd) supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); + // Debugbreak on D3D error + if (SUCCEEDED(hr) && SUCCEEDED(device->QueryInterface(__uuidof(ID3D11Debug), (void**)&debug))) + { + ID3D11InfoQueue* infoQueue = nullptr; + if (SUCCEEDED(debug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue))) + { + infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); + infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); + + D3D11_MESSAGE_ID hide[] = + { + D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS + }; + + D3D11_INFO_QUEUE_FILTER filter = {}; + filter.DenyList.NumIDs = sizeof(hide) / sizeof(D3D11_MESSAGE_ID); + filter.DenyList.pIDList = hide; + infoQueue->AddStorageFilterEntries(&filter); + infoQueue->Release(); + } + } } if (FAILED(hr)) @@ -375,6 +394,21 @@ void Close() SAFE_RELEASE(context); ULONG references = device->Release(); + +#if defined(_DEBUG) || defined(DEBUGFAST) + if (debug) + { + --references; // the debug interface increases the refcount of the device, subtract that. + if (references) + { + // print out alive objects, but only if we actually have pending references + // note this will also print out internal live objects to the debug console + debug->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL); + } + SAFE_RELEASE(debug) + } +#endif + if (references) { ERROR_LOG(VIDEO, "Unreleased references: %i.", references); diff --git a/Source/Core/VideoBackends/D3D/D3DBase.h b/Source/Core/VideoBackends/D3D/D3DBase.h index 05190bd5d4..a0a629ac8a 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.h +++ b/Source/Core/VideoBackends/D3D/D3DBase.h @@ -70,10 +70,29 @@ void SetDebugObjectName(T resource, const char* name) static_assert(std::is_convertible::value, "resource must be convertible to ID3D11DeviceChild*"); #if defined(_DEBUG) || defined(DEBUGFAST) - resource->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(name), name); + if (resource) + resource->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)(name ? strlen(name) : 0), name); #endif } +template +std::string GetDebugObjectName(T resource) +{ + static_assert(std::is_convertible::value, + "resource must be convertible to ID3D11DeviceChild*"); + std::string name; +#if defined(_DEBUG) || defined(DEBUGFAST) + if (resource) + { + UINT size = 0; + resource->GetPrivateData(WKPDID_D3DDebugObjectName, &size, nullptr); //get required size + name.resize(size); + resource->GetPrivateData(WKPDID_D3DDebugObjectName, &size, const_cast(name.data())); + } +#endif + return name; +} + } // namespace D3D typedef HRESULT (WINAPI* CREATEDXGIFACTORY)(REFIID, void**); diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp index c4d215d413..9e758981ca 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp @@ -253,6 +253,11 @@ ID3D11PixelShader* PSTextureEncoder::SetStaticShader(unsigned int dstFormat, PEC HRESULT hr = D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), nullptr, &newShader); CHECK(SUCCEEDED(hr), "create efb encoder pixel shader"); + char debugName[255] = {}; + sprintf_s(debugName, "efb encoder pixel shader (dst:%d, src:%d, intensity:%d, scale:%d)", + dstFormat, srcFormat, isIntensity, scaleByHalf); + D3D::SetDebugObjectName(newShader, debugName); + it = m_staticShaders.insert(std::make_pair(key, newShader)).first; bytecode->Release(); } diff --git a/Source/Core/VideoBackends/D3D/XFBEncoder.cpp b/Source/Core/VideoBackends/D3D/XFBEncoder.cpp index e0932fe616..70316a9df5 100644 --- a/Source/Core/VideoBackends/D3D/XFBEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/XFBEncoder.cpp @@ -361,8 +361,8 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR D3D::context->Unmap(m_outStage, 0); // Restore API - g_renderer->RestoreAPIState(); + D3D::stateman->Apply(); // force unbind efb texture as shader resource D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());