DX11:
Add multisampling support. EFB access doesn't work with MSAA enabled, yet. Additionally clean up some stuff, fix a memory leak, ... git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6468 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
6d93a6b698
commit
d36ede020c
|
@ -51,7 +51,7 @@ public:
|
||||||
VideoConfigDiag(wxWindow* parent, const std::string &title, const std::string& ininame);
|
VideoConfigDiag(wxWindow* parent, const std::string &title, const std::string& ininame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Event_Backend(wxCommandEvent &ev) { ev.Skip(); } // TODO
|
void Event_Backend(wxCommandEvent &ev) { ev.Skip(); } // TODO: Query list of supported AA modes
|
||||||
void Event_Adapter(wxCommandEvent &ev) { ev.Skip(); } // TODO
|
void Event_Adapter(wxCommandEvent &ev) { ev.Skip(); } // TODO
|
||||||
|
|
||||||
void Event_EfbCopy(wxCommandEvent &ev)
|
void Event_EfbCopy(wxCommandEvent &ev)
|
||||||
|
|
|
@ -34,6 +34,7 @@ CREATEDXGIFACTORY PCreateDXGIFactory = NULL;
|
||||||
HINSTANCE hDXGIDll = NULL;
|
HINSTANCE hDXGIDll = NULL;
|
||||||
|
|
||||||
typedef HRESULT (WINAPI* D3D11CREATEDEVICEANDSWAPCHAIN)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, CONST DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
typedef HRESULT (WINAPI* D3D11CREATEDEVICEANDSWAPCHAIN)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, CONST DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
||||||
|
D3D11CREATEDEVICE PD3D11CreateDevice = NULL;
|
||||||
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = NULL;
|
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = NULL;
|
||||||
HINSTANCE hD3DDll = NULL;
|
HINSTANCE hD3DDll = NULL;
|
||||||
|
|
||||||
|
@ -47,6 +48,8 @@ D3D_FEATURE_LEVEL featlevel;
|
||||||
D3DTexture2D* backbuf = NULL;
|
D3DTexture2D* backbuf = NULL;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
|
||||||
|
std::vector<DXGI_SAMPLE_DESC> aa_modes; // supported AA modes of the current adapter
|
||||||
|
|
||||||
bool bgra_textures_supported;
|
bool bgra_textures_supported;
|
||||||
|
|
||||||
#define NUM_SUPPORTED_FEATURE_LEVELS 3
|
#define NUM_SUPPORTED_FEATURE_LEVELS 3
|
||||||
|
@ -60,8 +63,9 @@ unsigned int xres, yres;
|
||||||
|
|
||||||
bool bFrameInProgress = false;
|
bool bFrameInProgress = false;
|
||||||
|
|
||||||
HRESULT GetDXGIFuncPointers()
|
HRESULT LoadDXGI()
|
||||||
{
|
{
|
||||||
|
if (hDXGIDll) return S_OK;
|
||||||
hDXGIDll = LoadLibraryA("dxgi.dll");
|
hDXGIDll = LoadLibraryA("dxgi.dll");
|
||||||
if (!hDXGIDll)
|
if (!hDXGIDll)
|
||||||
{
|
{
|
||||||
|
@ -74,14 +78,28 @@ HRESULT GetDXGIFuncPointers()
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnloadDXGI()
|
HRESULT LoadD3D()
|
||||||
{
|
{
|
||||||
if(hDXGIDll) FreeLibrary(hDXGIDll);
|
if (hD3DDll) return S_OK;
|
||||||
PCreateDXGIFactory = NULL;
|
hD3DDll = LoadLibraryA("d3d11.dll");
|
||||||
|
if (!hD3DDll)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
PD3D11CreateDevice = (D3D11CREATEDEVICE)GetProcAddress(hD3DDll, "D3D11CreateDevice");
|
||||||
|
if (PD3D11CreateDevice == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDevice!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
|
PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll, "D3D11CreateDeviceAndSwapChain");
|
||||||
|
if (PD3D11CreateDeviceAndSwapChain == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT GetD3DFuncPointers()
|
HRESULT LoadD3DX()
|
||||||
{
|
{
|
||||||
|
if (hD3DXDll) return S_OK;
|
||||||
|
|
||||||
// try to load D3DX11 first to check whether we have proper runtime support
|
// try to load D3DX11 first to check whether we have proper runtime support
|
||||||
// try to use the dll the plugin was compiled against first - don't bother about debug runtimes
|
// try to use the dll the plugin was compiled against first - don't bother about debug runtimes
|
||||||
hD3DXDll = LoadLibraryA(StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
hD3DXDll = LoadLibraryA(StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
||||||
|
@ -112,22 +130,64 @@ HRESULT GetD3DFuncPointers()
|
||||||
PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW");
|
PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW");
|
||||||
if (PD3DX11SaveTextureToFileW == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileW!", "Critical error", MB_OK | MB_ICONERROR);
|
if (PD3DX11SaveTextureToFileW == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileW!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
// D3DX11 is fine, check DXGI and D3D11
|
|
||||||
HRESULT hr = GetDXGIFuncPointers();
|
|
||||||
if (FAILED(hr)) return hr;
|
|
||||||
|
|
||||||
hD3DDll = LoadLibraryA("d3d11.dll");
|
|
||||||
if (!hD3DDll)
|
|
||||||
{
|
|
||||||
MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll, "D3D11CreateDeviceAndSwapChain");
|
|
||||||
if (PD3D11CreateDeviceAndSwapChain == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnloadDXGI()
|
||||||
|
{
|
||||||
|
if(hDXGIDll) FreeLibrary(hDXGIDll);
|
||||||
|
hDXGIDll = NULL;
|
||||||
|
PCreateDXGIFactory = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadD3DX()
|
||||||
|
{
|
||||||
|
if(hD3DXDll) FreeLibrary(hD3DXDll);
|
||||||
|
hD3DXDll = NULL;
|
||||||
|
PD3DX11FilterTexture = NULL;
|
||||||
|
PD3DX11SaveTextureToFileA = NULL;
|
||||||
|
PD3DX11SaveTextureToFileW = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadD3D()
|
||||||
|
{
|
||||||
|
if(hD3DDll) FreeLibrary(hD3DDll);
|
||||||
|
hD3DDll = NULL;
|
||||||
|
PD3D11CreateDevice = NULL;
|
||||||
|
PD3D11CreateDeviceAndSwapChain = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes)
|
||||||
|
{
|
||||||
|
aa_modes.clear();
|
||||||
|
|
||||||
|
ID3D11Device* device;
|
||||||
|
ID3D11DeviceContext* context;
|
||||||
|
D3D_FEATURE_LEVEL feat_level;
|
||||||
|
HRESULT hr = PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, 0, D3D11_SDK_VERSION, &device, &feat_level, &context);
|
||||||
|
if (FAILED(hr)) return;
|
||||||
|
|
||||||
|
for (int samples = 0; samples < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++samples)
|
||||||
|
{
|
||||||
|
UINT quality_levels = 0;
|
||||||
|
device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, samples, &quality_levels);
|
||||||
|
if (quality_levels > 0) {
|
||||||
|
DXGI_SAMPLE_DESC desc;
|
||||||
|
desc.Count = samples;
|
||||||
|
for (desc.Quality = 0; desc.Quality < quality_levels; ++desc.Quality)
|
||||||
|
aa_modes.push_back(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context->Release();
|
||||||
|
device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_SAMPLE_DESC GetAAMode(int index)
|
||||||
|
{
|
||||||
|
return aa_modes[index];
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT Create(HWND wnd)
|
HRESULT Create(HWND wnd)
|
||||||
{
|
{
|
||||||
hWnd = wnd;
|
hWnd = wnd;
|
||||||
|
@ -138,8 +198,15 @@ HRESULT Create(HWND wnd)
|
||||||
xres = client.right - client.left;
|
xres = client.right - client.left;
|
||||||
yres = client.bottom - client.top;
|
yres = client.bottom - client.top;
|
||||||
|
|
||||||
hr = GetD3DFuncPointers();
|
hr = LoadDXGI();
|
||||||
if (FAILED(hr)) return hr;
|
if (SUCCEEDED(hr)) hr = LoadD3D();
|
||||||
|
if (SUCCEEDED(hr)) hr = LoadD3DX();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
UnloadDXGI();
|
||||||
|
UnloadD3D();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* adapter;
|
IDXGIAdapter* adapter;
|
||||||
|
@ -164,6 +231,10 @@ HRESULT Create(HWND wnd)
|
||||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get supported AA modes
|
||||||
|
aa_modes.clear();
|
||||||
|
EnumAAModes(adapter, aa_modes);
|
||||||
|
|
||||||
// this will need to be changed once multisampling gets implemented
|
// this will need to be changed once multisampling gets implemented
|
||||||
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
||||||
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
||||||
|
@ -260,14 +331,8 @@ void Close()
|
||||||
device = NULL;
|
device = NULL;
|
||||||
|
|
||||||
// unload DLLs
|
// unload DLLs
|
||||||
if(hD3DXDll) FreeLibrary(hD3DXDll);
|
UnloadD3DX();
|
||||||
PD3DX11FilterTexture = NULL;
|
UnloadD3D();
|
||||||
PD3DX11SaveTextureToFileA = NULL;
|
|
||||||
PD3DX11SaveTextureToFileW = NULL;
|
|
||||||
|
|
||||||
if(hD3DXDll) FreeLibrary(hD3DXDll);
|
|
||||||
PD3D11CreateDeviceAndSwapChain = NULL;
|
|
||||||
|
|
||||||
UnloadDXGI();
|
UnloadDXGI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,15 @@ class D3DTexture2D;
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
HRESULT GetDXGIFuncPointers();
|
HRESULT LoadDXGI();
|
||||||
|
HRESULT LoadD3D();
|
||||||
|
HRESULT LoadD3DX();
|
||||||
void UnloadDXGI();
|
void UnloadDXGI();
|
||||||
|
void UnloadD3D();
|
||||||
|
void UnloadD3DX();
|
||||||
|
|
||||||
|
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes);
|
||||||
|
DXGI_SAMPLE_DESC GetAAMode(int index);
|
||||||
|
|
||||||
HRESULT Create(HWND wnd);
|
HRESULT Create(HWND wnd);
|
||||||
void Close();
|
void Close();
|
||||||
|
@ -92,3 +99,5 @@ extern D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW;
|
||||||
|
|
||||||
typedef HRESULT (WINAPI* CREATEDXGIFACTORY)(REFIID, void**);
|
typedef HRESULT (WINAPI* CREATEDXGIFACTORY)(REFIID, void**);
|
||||||
extern CREATEDXGIFACTORY PCreateDXGIFactory;
|
extern CREATEDXGIFACTORY PCreateDXGIFactory;
|
||||||
|
typedef HRESULT (WINAPI* D3D11CREATEDEVICE)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
||||||
|
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
||||||
|
|
|
@ -92,12 +92,15 @@ ID3D11RenderTargetView* &D3DTexture2D::GetRTV() { return rtv; }
|
||||||
ID3D11DepthStencilView* &D3DTexture2D::GetDSV() { return dsv; }
|
ID3D11DepthStencilView* &D3DTexture2D::GetDSV() { return dsv; }
|
||||||
|
|
||||||
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind,
|
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind,
|
||||||
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format)
|
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format, bool multisampled)
|
||||||
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
||||||
{
|
{
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION_TEXTURE2D, srv_format);
|
D3D11_SRV_DIMENSION srv_dim = multisampled ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, dsv_format);
|
D3D11_DSV_DIMENSION dsv_dim = multisampled ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION_TEXTURE2D, rtv_format);
|
D3D11_RTV_DIMENSION rtv_dim = multisampled ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(srv_dim, srv_format);
|
||||||
|
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(dsv_dim, dsv_format);
|
||||||
|
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(rtv_dim, rtv_format);
|
||||||
if (bind & D3D11_BIND_SHADER_RESOURCE) D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
if (bind & D3D11_BIND_SHADER_RESOURCE) D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
||||||
if (bind & D3D11_BIND_RENDER_TARGET) D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
if (bind & D3D11_BIND_RENDER_TARGET) D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
||||||
if (bind & D3D11_BIND_DEPTH_STENCIL) D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
if (bind & D3D11_BIND_DEPTH_STENCIL) D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
||||||
// or let the texture automatically be created by D3DTexture2D::Create
|
// or let the texture automatically be created by D3DTexture2D::Create
|
||||||
|
|
||||||
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN);
|
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN, bool multisampled = false);
|
||||||
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
||||||
|
|
||||||
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
||||||
|
|
|
@ -33,27 +33,48 @@ D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
||||||
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
||||||
|
|
||||||
|
D3DTexture2D* &FramebufferManager::GetResolvedEFBColorTexture()
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
|
{
|
||||||
|
D3D::context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
return m_efb.resolved_color_tex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return m_efb.color_tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture()
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
|
{
|
||||||
|
D3D::context->ResolveSubresource(m_efb.resolved_color_tex->GetTex(), 0, m_efb.color_tex->GetTex(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
return m_efb.resolved_color_tex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return m_efb.depth_tex;
|
||||||
|
}
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager()
|
FramebufferManager::FramebufferManager()
|
||||||
{
|
{
|
||||||
m_efb.color_tex = NULL;
|
|
||||||
m_efb.color_staging_buf = NULL;
|
|
||||||
m_efb.depth_tex = NULL;
|
|
||||||
m_efb.depth_staging_buf = NULL;
|
|
||||||
m_efb.depth_read_texture = NULL;
|
|
||||||
|
|
||||||
unsigned int target_width = Renderer::GetFullTargetWidth();
|
unsigned int target_width = Renderer::GetFullTargetWidth();
|
||||||
unsigned int target_height = Renderer::GetFullTargetHeight();
|
unsigned int target_height = Renderer::GetFullTargetHeight();
|
||||||
|
DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode);
|
||||||
|
|
||||||
ID3D11Texture2D* buf;
|
ID3D11Texture2D* buf;
|
||||||
D3D11_TEXTURE2D_DESC texdesc;
|
D3D11_TEXTURE2D_DESC texdesc;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// create framebuffer color texture
|
// create framebuffer color texture
|
||||||
m_efb.color_tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
||||||
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
|
CHECK(hr==S_OK, "create EFB color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
|
m_efb.color_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1));
|
||||||
CHECK(m_efb.color_tex!=NULL, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
CHECK(m_efb.color_tex!=NULL, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
||||||
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
||||||
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
||||||
|
|
||||||
// create a staging texture for Renderer::AccessEFB
|
// create a staging texture for Renderer::AccessEFB
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
||||||
|
@ -62,10 +83,10 @@ FramebufferManager::FramebufferManager()
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
||||||
|
|
||||||
// EFB depth buffer
|
// EFB depth buffer
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, sample_desc.Count, sample_desc.Quality);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT);
|
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, (sample_desc.Count > 1));
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
||||||
|
@ -85,15 +106,37 @@ FramebufferManager::FramebufferManager()
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth staging buffer (hr=%#x)", hr);
|
CHECK(hr==S_OK, "create EFB depth staging buffer (hr=%#x)", hr);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
||||||
|
|
||||||
|
if (g_ActiveConfig.iMultisampleMode)
|
||||||
|
{
|
||||||
|
// create framebuffer resolve textures (color+depth)
|
||||||
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1);
|
||||||
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
|
m_efb.resolved_color_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
CHECK(m_efb.resolved_color_tex!=NULL, "create EFB color resolve texture (size: %dx%d)", target_width, target_height);
|
||||||
|
SAFE_RELEASE(buf);
|
||||||
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture");
|
||||||
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view");
|
||||||
|
|
||||||
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE);
|
||||||
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
|
CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
|
m_efb.resolved_depth_tex = new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R24_UNORM_X8_TYPELESS);
|
||||||
|
SAFE_RELEASE(buf);
|
||||||
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture");
|
||||||
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetSRV(), "EFB depth resolve texture shader resource view");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(m_efb.color_tex);
|
SAFE_RELEASE(m_efb.color_tex);
|
||||||
SAFE_RELEASE(m_efb.color_staging_buf);
|
SAFE_RELEASE(m_efb.color_staging_buf);
|
||||||
|
SAFE_RELEASE(m_efb.resolved_color_tex);
|
||||||
SAFE_RELEASE(m_efb.depth_tex);
|
SAFE_RELEASE(m_efb.depth_tex);
|
||||||
SAFE_RELEASE(m_efb.depth_staging_buf);
|
SAFE_RELEASE(m_efb.depth_staging_buf);
|
||||||
SAFE_RELEASE(m_efb.depth_read_texture);
|
SAFE_RELEASE(m_efb.depth_read_texture);
|
||||||
|
SAFE_RELEASE(m_efb.resolved_depth_tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
|
|
|
@ -80,6 +80,9 @@ public:
|
||||||
static D3DTexture2D* &GetEFBDepthReadTexture();
|
static D3DTexture2D* &GetEFBDepthReadTexture();
|
||||||
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
||||||
|
|
||||||
|
static D3DTexture2D* &GetResolvedEFBColorTexture();
|
||||||
|
static D3DTexture2D* &GetResolvedEFBDepthTexture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||||
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
|
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
|
||||||
|
@ -94,6 +97,9 @@ private:
|
||||||
D3DTexture2D* depth_tex;
|
D3DTexture2D* depth_tex;
|
||||||
ID3D11Texture2D* depth_staging_buf;
|
ID3D11Texture2D* depth_staging_buf;
|
||||||
D3DTexture2D* depth_read_texture;
|
D3DTexture2D* depth_read_texture;
|
||||||
|
|
||||||
|
D3DTexture2D* resolved_color_tex;
|
||||||
|
D3DTexture2D* resolved_depth_tex;
|
||||||
} m_efb;
|
} m_efb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
|
|
||||||
static int s_fps = 0;
|
static int s_fps = 0;
|
||||||
|
|
||||||
|
static u32 s_LastAA = 0;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
|
|
||||||
ID3D11Buffer* access_efb_cbuf = NULL;
|
ID3D11Buffer* access_efb_cbuf = NULL;
|
||||||
|
@ -329,6 +331,7 @@ Renderer::Renderer()
|
||||||
|
|
||||||
CalculateXYScale(dst_rect);
|
CalculateXYScale(dst_rect);
|
||||||
|
|
||||||
|
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
CalculateTargetSize();
|
CalculateTargetSize();
|
||||||
|
|
||||||
|
@ -492,6 +495,7 @@ void Renderer::SetColorMask()
|
||||||
// - GX_PokeZMode (TODO)
|
// - GX_PokeZMode (TODO)
|
||||||
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
{
|
{
|
||||||
|
// TODO: This function currently is broken if anti-aliasing is enabled
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
ID3D11Texture2D* read_tex;
|
ID3D11Texture2D* read_tex;
|
||||||
|
|
||||||
|
@ -542,7 +546,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL);
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(),
|
D3D::drawShadedTexQuad(FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV(),
|
||||||
&RectToLock,
|
&RectToLock,
|
||||||
Renderer::GetFullTargetWidth(),
|
Renderer::GetFullTargetWidth(),
|
||||||
Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetHeight(),
|
||||||
|
@ -572,7 +576,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
else if (type == PEEK_COLOR)
|
else if (type == PEEK_COLOR)
|
||||||
{
|
{
|
||||||
// we can directly copy to system memory here
|
// we can directly copy to system memory here
|
||||||
read_tex = FramebufferManager::GetEFBColorStagingBuffer();
|
read_tex = FramebufferManager::GetResolvedEFBColorTexture()->GetTex();
|
||||||
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
||||||
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBColorTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBColorTexture()->GetTex(), 0, &box);
|
||||||
|
|
||||||
|
@ -879,7 +883,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||||
D3DTexture2D* read_texture = FramebufferManager::GetEFBColorTexture();
|
D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture();
|
||||||
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
}
|
}
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
|
@ -956,8 +960,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// resize the back buffers NOW to avoid flickering
|
// resize the back buffers NOW to avoid flickering
|
||||||
if (xfbchanged || WindowResized ||
|
if (xfbchanged || WindowResized ||
|
||||||
s_LastEFBScale != g_ActiveConfig.iEFBScale)
|
s_LastEFBScale != g_ActiveConfig.iEFBScale ||
|
||||||
|
s_LastAA != g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
|
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
|
|
||||||
// TODO: Aren't we still holding a reference to the back buffer right now?
|
// TODO: Aren't we still holding a reference to the back buffer right now?
|
||||||
D3D::Reset();
|
D3D::Reset();
|
||||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||||
|
|
|
@ -147,7 +147,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
(bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
(bFromZBuffer) ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(),
|
||||||
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||||
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(),
|
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
|
@ -161,8 +161,13 @@ void DllConfig(void *_hParent)
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
InitBackendInfo();
|
InitBackendInfo();
|
||||||
|
|
||||||
HRESULT hr = D3D::GetDXGIFuncPointers();
|
HRESULT hr = D3D::LoadDXGI();
|
||||||
if (FAILED(hr)) return;
|
if (SUCCEEDED(hr)) hr = D3D::LoadD3D();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (!s_PluginInitialized) D3D::UnloadDXGI();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* ad;
|
IDXGIAdapter* ad;
|
||||||
|
@ -174,10 +179,27 @@ void DllConfig(void *_hParent)
|
||||||
DXGI_ADAPTER_DESC desc;
|
DXGI_ADAPTER_DESC desc;
|
||||||
// adapters
|
// adapters
|
||||||
g_Config.backend_info.Adapters.clear();
|
g_Config.backend_info.Adapters.clear();
|
||||||
|
g_Config.backend_info.AAModes.clear();
|
||||||
while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND)
|
while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND)
|
||||||
{
|
{
|
||||||
ad->GetDesc(&desc);
|
ad->GetDesc(&desc);
|
||||||
WideCharToMultiByte(/*CP_UTF8*/CP_ACP, 0, desc.Description, -1, tmpstr, 512, 0, false);
|
WideCharToMultiByte(/*CP_UTF8*/CP_ACP, 0, desc.Description, -1, tmpstr, 512, 0, false);
|
||||||
|
|
||||||
|
// TODO: These don't get updated on adapter change, yet
|
||||||
|
if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
std::vector<DXGI_SAMPLE_DESC> modes;
|
||||||
|
D3D::EnumAAModes(ad, modes);
|
||||||
|
for (unsigned int i = 0; i < modes.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i == 0) sprintf_s(buf, 32, "None");
|
||||||
|
else if (modes[i].Quality) sprintf_s(buf, 32, "%d samples (quality level %d)", modes[i].Count, modes[i].Quality);
|
||||||
|
else sprintf_s(buf, 32, "%d samples", modes[i].Count);
|
||||||
|
g_Config.backend_info.AAModes.push_back(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_Config.backend_info.Adapters.push_back(tmpstr);
|
g_Config.backend_info.Adapters.push_back(tmpstr);
|
||||||
ad->Release();
|
ad->Release();
|
||||||
}
|
}
|
||||||
|
@ -188,7 +210,11 @@ void DllConfig(void *_hParent)
|
||||||
diag->ShowModal();
|
diag->ShowModal();
|
||||||
diag->Destroy();
|
diag->Destroy();
|
||||||
|
|
||||||
D3D::UnloadDXGI();
|
if (!s_PluginInitialized)
|
||||||
|
{
|
||||||
|
D3D::UnloadDXGI();
|
||||||
|
D3D::UnloadD3D();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue