summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@googlemail.com>2010-11-23 19:58:02 +0000
committerNeoBrainX <NeoBrainX@googlemail.com>2010-11-23 19:58:02 +0000
commitd36ede020c122ec79fdf9872bf078f83a1b5621e (patch)
tree95cc3cad865feb3a3af1682e354496c4e826fddc /Source
parent6d93a6b6981cd4edfc70c884cca5592b88d9f9f1 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoUICommon/Src/VideoConfigDiag.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp115
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h11
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp11
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp63
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h6
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/Render.cpp15
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp2
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/main.cpp32
10 files changed, 209 insertions, 50 deletions
diff --git a/Source/Core/VideoUICommon/Src/VideoConfigDiag.h b/Source/Core/VideoUICommon/Src/VideoConfigDiag.h
index 35e833eb07..5f7dbdd889 100644
--- a/Source/Core/VideoUICommon/Src/VideoConfigDiag.h
+++ b/Source/Core/VideoUICommon/Src/VideoConfigDiag.h
@@ -51,7 +51,7 @@ public:
VideoConfigDiag(wxWindow* parent, const std::string &title, const std::string& ininame);
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_EfbCopy(wxCommandEvent &ev)
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp
index 43a5867002..81587fb526 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp
@@ -34,6 +34,7 @@ CREATEDXGIFACTORY PCreateDXGIFactory = 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**);
+D3D11CREATEDEVICE PD3D11CreateDevice = NULL;
D3D11CREATEDEVICEANDSWAPCHAIN PD3D11CreateDeviceAndSwapChain = NULL;
HINSTANCE hD3DDll = NULL;
@@ -47,6 +48,8 @@ D3D_FEATURE_LEVEL featlevel;
D3DTexture2D* backbuf = NULL;
HWND hWnd;
+std::vector<DXGI_SAMPLE_DESC> aa_modes; // supported AA modes of the current adapter
+
bool bgra_textures_supported;
#define NUM_SUPPORTED_FEATURE_LEVELS 3
@@ -60,8 +63,9 @@ unsigned int xres, yres;
bool bFrameInProgress = false;
-HRESULT GetDXGIFuncPointers()
+HRESULT LoadDXGI()
{
+ if (hDXGIDll) return S_OK;
hDXGIDll = LoadLibraryA("dxgi.dll");
if (!hDXGIDll)
{
@@ -74,14 +78,28 @@ HRESULT GetDXGIFuncPointers()
return S_OK;
}
-void UnloadDXGI()
+HRESULT LoadD3D()
{
- if(hDXGIDll) FreeLibrary(hDXGIDll);
- PCreateDXGIFactory = NULL;
+ if (hD3DDll) return S_OK;
+ 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 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());
@@ -112,20 +130,62 @@ HRESULT GetD3DFuncPointers()
PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW");
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;
+ return S_OK;
+}
- hD3DDll = LoadLibraryA("d3d11.dll");
- if (!hD3DDll)
+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)
{
- MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR);
- return E_FAIL;
+ 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);
+ }
}
- PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll, "D3D11CreateDeviceAndSwapChain");
- if (PD3D11CreateDeviceAndSwapChain == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR);
- return S_OK;
+ context->Release();
+ device->Release();
+}
+
+DXGI_SAMPLE_DESC GetAAMode(int index)
+{
+ return aa_modes[index];
}
HRESULT Create(HWND wnd)
@@ -138,8 +198,15 @@ HRESULT Create(HWND wnd)
xres = client.right - client.left;
yres = client.bottom - client.top;
- hr = GetD3DFuncPointers();
- if (FAILED(hr)) return hr;
+ hr = LoadDXGI();
+ if (SUCCEEDED(hr)) hr = LoadD3D();
+ if (SUCCEEDED(hr)) hr = LoadD3DX();
+ if (FAILED(hr))
+ {
+ UnloadDXGI();
+ UnloadD3D();
+ return hr;
+ }
IDXGIFactory* factory;
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);
}
+ // get supported AA modes
+ aa_modes.clear();
+ EnumAAModes(adapter, aa_modes);
+
// this will need to be changed once multisampling gets implemented
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
@@ -260,14 +331,8 @@ void Close()
device = NULL;
// unload DLLs
- if(hD3DXDll) FreeLibrary(hD3DXDll);
- PD3DX11FilterTexture = NULL;
- PD3DX11SaveTextureToFileA = NULL;
- PD3DX11SaveTextureToFileW = NULL;
-
- if(hD3DXDll) FreeLibrary(hD3DXDll);
- PD3D11CreateDeviceAndSwapChain = NULL;
-
+ UnloadD3DX();
+ UnloadD3D();
UnloadDXGI();
}
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h
index 94e5fa4648..e76617de15 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h
@@ -31,8 +31,15 @@ class D3DTexture2D;
namespace D3D
{
-HRESULT GetDXGIFuncPointers();
+HRESULT LoadDXGI();
+HRESULT LoadD3D();
+HRESULT LoadD3DX();
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);
void Close();
@@ -92,3 +99,5 @@ extern D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW;
typedef HRESULT (WINAPI* CREATEDXGIFACTORY)(REFIID, void**);
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;
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp
index 38b9fe4431..ee06bc1cf2 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp
@@ -92,12 +92,15 @@ ID3D11RenderTargetView* &D3DTexture2D::GetRTV() { return rtv; }
ID3D11DepthStencilView* &D3DTexture2D::GetDSV() { return dsv; }
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)
{
- D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION_TEXTURE2D, srv_format);
- D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, dsv_format);
- D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION_TEXTURE2D, rtv_format);
+ D3D11_SRV_DIMENSION srv_dim = multisampled ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
+ D3D11_DSV_DIMENSION dsv_dim = multisampled ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
+ 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_RENDER_TARGET) D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
if (bind & D3D11_BIND_DEPTH_STENCIL) D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h
index ddde3719e9..37479378d6 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h
@@ -31,7 +31,7 @@ public:
// 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
- 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);
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp
index 3d540fb571..8d6efb673d 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp
@@ -33,27 +33,48 @@ D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
-FramebufferManager::FramebufferManager()
+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()
{
- 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;
+ 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()
+{
unsigned int target_width = Renderer::GetFullTargetWidth();
unsigned int target_height = Renderer::GetFullTargetHeight();
+ DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode);
ID3D11Texture2D* buf;
D3D11_TEXTURE2D_DESC texdesc;
HRESULT hr;
// 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);
+ SAFE_RELEASE(buf);
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->GetRTV(), "EFB color texture render target view");
// 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);
@@ -62,10 +83,10 @@ FramebufferManager::FramebufferManager()
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
// 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);
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);
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");
@@ -85,15 +106,37 @@ FramebufferManager::FramebufferManager()
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
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)");
+
+ 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()
{
SAFE_RELEASE(m_efb.color_tex);
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_staging_buf);
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)
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h
index f8cebb8b56..2fadf16e68 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h
@@ -80,6 +80,9 @@ public:
static D3DTexture2D* &GetEFBDepthReadTexture();
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
+ static D3DTexture2D* &GetResolvedEFBColorTexture();
+ static D3DTexture2D* &GetResolvedEFBDepthTexture();
+
private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
@@ -94,6 +97,9 @@ private:
D3DTexture2D* depth_tex;
ID3D11Texture2D* depth_staging_buf;
D3DTexture2D* depth_read_texture;
+
+ D3DTexture2D* resolved_color_tex;
+ D3DTexture2D* resolved_depth_tex;
} m_efb;
};
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
index 8be2a4d5bc..fc850dce83 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
@@ -51,6 +51,8 @@
static int s_fps = 0;
+static u32 s_LastAA = 0;
+
static u32 s_blendMode;
ID3D11Buffer* access_efb_cbuf = NULL;
@@ -329,6 +331,7 @@ Renderer::Renderer()
CalculateXYScale(dst_rect);
+ s_LastAA = g_ActiveConfig.iMultisampleMode;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
CalculateTargetSize();
@@ -492,6 +495,7 @@ void Renderer::SetColorMask()
// - GX_PokeZMode (TODO)
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;
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->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL);
D3D::SetPointCopySampler();
- D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(),
+ D3D::drawShadedTexQuad(FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV(),
&RectToLock,
Renderer::GetFullTargetWidth(),
Renderer::GetFullTargetHeight(),
@@ -572,7 +576,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
else if (type == PEEK_COLOR)
{
// 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);
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
{
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());
}
// 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
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?
D3D::Reset();
s_backbuffer_width = D3D::GetBackBufferWidth();
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
index e3f3b67087..dafdbec132 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
@@ -147,7 +147,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
D3D::drawShadedTexQuad(
- (bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
+ (bFromZBuffer) ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(),
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(),
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
index c114d78f17..adb79f08a3 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
@@ -161,8 +161,13 @@ void DllConfig(void *_hParent)
#if defined(HAVE_WX) && HAVE_WX
InitBackendInfo();
- HRESULT hr = D3D::GetDXGIFuncPointers();
- if (FAILED(hr)) return;
+ HRESULT hr = D3D::LoadDXGI();
+ if (SUCCEEDED(hr)) hr = D3D::LoadD3D();
+ if (FAILED(hr))
+ {
+ if (!s_PluginInitialized) D3D::UnloadDXGI();
+ return;
+ }
IDXGIFactory* factory;
IDXGIAdapter* ad;
@@ -174,10 +179,27 @@ void DllConfig(void *_hParent)
DXGI_ADAPTER_DESC desc;
// adapters
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)
{
ad->GetDesc(&desc);
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);
ad->Release();
}
@@ -188,7 +210,11 @@ void DllConfig(void *_hParent)
diag->ShowModal();
diag->Destroy();
- D3D::UnloadDXGI();
+ if (!s_PluginInitialized)
+ {
+ D3D::UnloadDXGI();
+ D3D::UnloadD3D();
+ }
#endif
}