Commit d9d02261 authored by chili's avatar chili
Browse files

dxgi debug info added

parent 4a2e05f8
#include "DxgiInfoManager.h"
#include "Window.h"
#include "Graphics.h"
#include <dxgidebug.h>
#include <memory>
#pragma comment(lib, "dxguid.lib")
#define GFX_THROW_NOINFO(hrcall) if( FAILED( hr = (hrcall) ) ) throw Graphics::HrException( __LINE__,__FILE__,hr )
DxgiInfoManager::DxgiInfoManager()
{
// define function signature of DXGIGetDebugInterface
typedef HRESULT (WINAPI* DXGIGetDebugInterface)(REFIID,void **);
// load the dll that contains the function DXGIGetDebugInterface
const auto hModDxgiDebug = LoadLibraryEx( "dxgidebug.dll",nullptr,LOAD_LIBRARY_SEARCH_SYSTEM32 );
if( hModDxgiDebug == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
// get address of DXGIGetDebugInterface in dll
const auto DxgiGetDebugInterface = reinterpret_cast<DXGIGetDebugInterface>(
reinterpret_cast<void*>(GetProcAddress( hModDxgiDebug,"DXGIGetDebugInterface" ))
);
if( DxgiGetDebugInterface == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
HRESULT hr;
GFX_THROW_NOINFO( DxgiGetDebugInterface( __uuidof(IDXGIInfoQueue),reinterpret_cast<void**>(&pDxgiInfoQueue) ) );
}
DxgiInfoManager::~DxgiInfoManager()
{
if( pDxgiInfoQueue != nullptr )
{
pDxgiInfoQueue->Release();
}
}
void DxgiInfoManager::Set() noexcept
{
// set the index (next) so that the next all to GetMessages()
// will only get errors generated after this call
next = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
}
std::vector<std::string> DxgiInfoManager::GetMessages() const
{
std::vector<std::string> messages;
const auto end = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
for( auto i = next; i < end; i++ )
{
HRESULT hr;
SIZE_T messageLength;
// get the size of message i in bytes
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,nullptr,&messageLength ) );
// allocate memory for message
auto bytes = std::make_unique<byte[]>( messageLength );
auto pMessage = reinterpret_cast<DXGI_INFO_QUEUE_MESSAGE*>(bytes.get());
// get the message and push its description into the vector
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,pMessage,&messageLength ) );
messages.emplace_back( pMessage->pDescription );
}
return messages;
}
#pragma once
#include "ChiliWin.h"
#include <vector>
class DxgiInfoManager
{
public:
DxgiInfoManager();
~DxgiInfoManager();
DxgiInfoManager( const DxgiInfoManager& ) = delete;
DxgiInfoManager& operator=( const DxgiInfoManager& ) = delete;
void Set() noexcept;
std::vector<std::string> GetMessages() const;
private:
unsigned long long next = 0u;
struct IDXGIInfoQueue* pDxgiInfoQueue = nullptr;
};
\ No newline at end of file
......@@ -4,8 +4,20 @@
#pragma comment(lib,"d3d11.lib")
#define GFX_THROW_FAILED(hrcall) if( FAILED( hr = (hrcall) ) ) throw Graphics::HrException( __LINE__,__FILE__,hr )
// graphics exception checking/throwing macros (some with dxgi infos)
#define GFX_EXCEPT_NOINFO(hr) Graphics::HrException( __LINE__,__FILE__,(hr) )
#define GFX_THROW_NOINFO(hrcall) if( FAILED( hr = (hrcall) ) ) throw Graphics::HrException( __LINE__,__FILE__,hr )
#ifndef NDEBUG
#define GFX_EXCEPT(hr) Graphics::HrException( __LINE__,__FILE__,(hr),infoManager.GetMessages() )
#define GFX_THROW_INFO(hrcall) infoManager.Set(); if( FAILED( hr = (hrcall) ) ) throw GFX_EXCEPT(hr)
#define GFX_DEVICE_REMOVED_EXCEPT(hr) Graphics::DeviceRemovedException( __LINE__,__FILE__,(hr),infoManager.GetMessages() )
#else
#define GFX_EXCEPT(hr) Graphics::HrException( __LINE__,__FILE__,(hr) )
#define GFX_THROW_INFO(hrcall) GFX_THROW_NOINFO(hrcall)
#define GFX_DEVICE_REMOVED_EXCEPT(hr) Graphics::DeviceRemovedException( __LINE__,__FILE__,(hr) )
#endif
Graphics::Graphics( HWND hWnd )
{
......@@ -26,15 +38,20 @@ Graphics::Graphics( HWND hWnd )
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
UINT swapCreateFlags = 0u;
#ifndef NDEBUG
swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// for checking results of d3d functions
HRESULT hr;
// create device and front/back buffers, and swap chain and rendering context
GFX_THROW_FAILED( D3D11CreateDeviceAndSwapChain(
GFX_THROW_INFO( D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
0,
swapCreateFlags,
nullptr,
0,
D3D11_SDK_VERSION,
......@@ -46,8 +63,8 @@ Graphics::Graphics( HWND hWnd )
) );
// gain access to texture subresource in swap chain (back buffer)
ID3D11Resource* pBackBuffer = nullptr;
GFX_THROW_FAILED( pSwap->GetBuffer( 0,__uuidof(ID3D11Texture2D),reinterpret_cast<void**>(&pBackBuffer) ) );
GFX_THROW_FAILED( pDevice->CreateRenderTargetView( pBackBuffer,nullptr,&pTarget ) );
GFX_THROW_INFO( pSwap->GetBuffer( 0,__uuidof(ID3D11Resource),reinterpret_cast<void**>(&pBackBuffer) ) );
GFX_THROW_INFO( pDevice->CreateRenderTargetView( pBackBuffer,nullptr,&pTarget ) );
pBackBuffer->Release();
}
......@@ -74,6 +91,9 @@ Graphics::~Graphics()
void Graphics::EndFrame()
{
HRESULT hr;
#ifndef NDEBUG
infoManager.Set();
#endif
if( FAILED( hr = pSwap->Present( 1u,0u ) ) )
{
if( hr == DXGI_ERROR_DEVICE_REMOVED )
......@@ -82,7 +102,7 @@ void Graphics::EndFrame()
}
else
{
GFX_THROW_FAILED( hr );
throw GFX_EXCEPT( hr );
}
}
}
......@@ -95,11 +115,23 @@ void Graphics::ClearBuffer( float red,float green,float blue ) noexcept
// Graphics exception stuff
Graphics::HrException::HrException( int line,const char * file,HRESULT hr ) noexcept
Graphics::HrException::HrException( int line,const char * file,HRESULT hr,std::vector<std::string> infoMsgs ) noexcept
:
Exception( line,file ),
hr( hr )
{}
{
// join all info messages with newlines into single string
for( const auto& m : infoMsgs )
{
info += m;
info.push_back( '\n' );
}
// remove final newline if exists
if( !info.empty() )
{
info.pop_back();
}
}
const char* Graphics::HrException::what() const noexcept
{
......@@ -108,8 +140,12 @@ const char* Graphics::HrException::what() const noexcept
<< "[Error Code] 0x" << std::hex << std::uppercase << GetErrorCode()
<< std::dec << " (" << (unsigned long)GetErrorCode() << ")" << std::endl
<< "[Error String] " << GetErrorString() << std::endl
<< "[Description] " << GetErrorDescription() << std::endl
<< GetOriginString();
<< "[Description] " << GetErrorDescription() << std::endl;
if( !info.empty() )
{
oss << "\n[Error Info]\n" << GetErrorInfo() << std::endl << std::endl;
}
oss << GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
......@@ -136,6 +172,11 @@ std::string Graphics::HrException::GetErrorDescription() const noexcept
return buf;
}
std::string Graphics::HrException::GetErrorInfo() const noexcept
{
return info;
}
const char* Graphics::DeviceRemovedException::GetType() const noexcept
{
......
......@@ -2,6 +2,8 @@
#include "ChiliWin.h"
#include "ChiliException.h"
#include <d3d11.h>
#include <vector>
#include "DxgiInfoManager.h"
class Graphics
{
......@@ -13,20 +15,24 @@ public:
class HrException : public Exception
{
public:
HrException( int line,const char* file,HRESULT hr ) noexcept;
HrException( int line,const char* file,HRESULT hr,std::vector<std::string> infoMsgs = {} ) noexcept;
const char* what() const noexcept override;
const char* GetType() const noexcept override;
HRESULT GetErrorCode() const noexcept;
std::string GetErrorString() const noexcept;
std::string GetErrorDescription() const noexcept;
std::string GetErrorInfo() const noexcept;
private:
HRESULT hr;
std::string info;
};
class DeviceRemovedException : public HrException
{
using HrException::HrException;
public:
const char* GetType() const noexcept override;
private:
std::string reason;
};
public:
Graphics( HWND hWnd );
......@@ -36,6 +42,9 @@ public:
void EndFrame();
void ClearBuffer( float red,float green,float blue ) noexcept;
private:
#ifndef NDEBUG
DxgiInfoManager infoManager;
#endif
ID3D11Device* pDevice = nullptr;
IDXGISwapChain* pSwap = nullptr;
ID3D11DeviceContext* pContext = nullptr;
......
......@@ -149,6 +149,7 @@
<ClCompile Include="ChiliException.cpp" />
<ClCompile Include="ChiliTimer.cpp" />
<ClCompile Include="dxerr.cpp" />
<ClCompile Include="DxgiInfoManager.cpp" />
<ClCompile Include="Graphics.cpp" />
<ClCompile Include="Keyboard.cpp" />
<ClCompile Include="Mouse.cpp" />
......@@ -162,6 +163,7 @@
<ClInclude Include="ChiliTimer.h" />
<ClInclude Include="ChiliWin.h" />
<ClInclude Include="dxerr.h" />
<ClInclude Include="DxgiInfoManager.h" />
<ClInclude Include="Graphics.h" />
<ClInclude Include="Keyboard.h" />
<ClInclude Include="Mouse.h" />
......
......@@ -48,6 +48,9 @@
<ClCompile Include="dxerr.cpp">
<Filter>Dxerr</Filter>
</ClCompile>
<ClCompile Include="DxgiInfoManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="WindowsMessageMap.h">
......@@ -83,6 +86,9 @@
<ClInclude Include="dxerr.h">
<Filter>Dxerr</Filter>
</ClInclude>
<ClInclude Include="DxgiInfoManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="hw3d.rc">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment