diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj index 6e3cae2695..0e7ab044aa 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj @@ -91,7 +91,7 @@ - + \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp index d04eb1c284..0e1989308a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp @@ -22,12 +22,18 @@ #include "VideoConfig.h" #include "Render.h" #include "XFStructs.h" +#include "StringUtil.h" #include #include #include using namespace std; +HINSTANCE hD3DXDll = NULL; +D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture = NULL; +D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA = NULL; +D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW = NULL; + namespace D3D { @@ -61,6 +67,38 @@ HRESULT Create(HWND wnd) xres = client.right - client.left; yres = client.bottom - client.top; + // 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()); + if (!hD3DXDll) + { + // if that fails, use the dll which should be available in every SDK which officially supports DX11. + hD3DXDll = LoadLibraryA("d3dx11_42.dll"); + if (!hD3DXDll) + { + MessageBoxA(NULL, "Failed to load d3dx11_42.dll, update your DX11 runtime, please", "Critical error", MB_OK | MB_ICONERROR); + return E_FAIL; + } + else + { + NOTICE_LOG(VIDEO, "Successfully loaded d3dx11_42.dll. If you're having trouble, try updating your DX runtime first."); + } + } + else + { + NOTICE_LOG(VIDEO, "Successfully loaded %s.", StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str()); + } + + PD3DX11FilterTexture = (D3DX11FILTERTEXTURETYPE)GetProcAddress(hD3DXDll, "D3DX11FilterTexture"); + if (PD3DX11FilterTexture == NULL) MessageBoxA(NULL, "GetProcAddress failed to D3DX11FilterTexture!", "Critical error", MB_OK | MB_ICONERROR); + + PD3DX11SaveTextureToFileA = (D3DX11SAVETEXTURETOFILEATYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileA"); + if (PD3DX11SaveTextureToFileA == NULL) MessageBoxA(NULL, "GetProcAddress failed to D3DX11SaveTextureToFileA!", "Critical error", MB_OK | MB_ICONERROR); + + PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW"); + if (PD3DX11SaveTextureToFileW == NULL) MessageBoxA(NULL, "GetProcAddress failed to D3DX11SaveTextureToFileW!", "Critical error", MB_OK | MB_ICONERROR); + + // D3DX11 is fine, initialize D3D11 IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; @@ -159,6 +197,12 @@ HRESULT Create(HWND wnd) void Close() { + // unload D3DX11 + FreeLibrary(hD3DXDll); + PD3DX11FilterTexture = NULL; + PD3DX11SaveTextureToFileA = NULL; + PD3DX11SaveTextureToFileW = NULL; + // release all bound resources context->ClearState(); SAFE_RELEASE(backbuf); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h index 3caeeeed18..4331b6e524 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include "Common.h" #include "D3DBlob.h" #include "GfxState.h" @@ -62,3 +62,24 @@ inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name) } } // namespace + + +// Used to not require the SDK and runtime versions to match: +// Linking with d3dx11.lib makes the most recent d3dx11_xx.dll of the +// compiler's SDK a requirement, but this plugin works with DX11 runtimes +// back to August 2009 even if the plugin was built with June 2010. +// Add any d3dx11 functions which you want to use here and load them in Create() +typedef HRESULT (WINAPI* D3DX11FILTERTEXTURETYPE)(ID3D11DeviceContext*, ID3D11Resource*, UINT, UINT); +typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEATYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCSTR); +typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEWTYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCWSTR); + +extern D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture; +extern D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA; +extern D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW; + +#ifdef UNICODE +#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileW +#else +#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileA +#endif + diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp index debb760fd9..b85cd2c662 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp @@ -504,8 +504,6 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture, ID3D11ShaderResourceView* texres = NULL; context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture - - } void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, @@ -565,8 +563,6 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, ID3D11ShaderResourceView* texres = NULL; context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture - - } void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout) @@ -600,8 +596,6 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS context->IASetVertexBuffers(0, 1, &clearvb, &stride, &offset); stateman->Apply(); context->Draw(4, 0); - - } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp index fe6b50e80e..9d30d2d80a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp @@ -34,6 +34,7 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC; } + memset(&blenddesc, 0, sizeof(blenddesc)); blenddesc.AlphaToCoverageEnable = FALSE; blenddesc.IndependentBlendEnable = FALSE; blenddesc.RenderTarget[0].BlendEnable = FALSE; @@ -45,6 +46,7 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + memset(&depthdesc, 0, sizeof(depthdesc)); depthdesc.DepthEnable = TRUE; depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthdesc.DepthFunc = D3D11_COMPARISON_LESS; @@ -248,6 +250,7 @@ void EmuGfxState::Reset() for (unsigned int k = 0;k < 8;k++) SAFE_RELEASE(shader_resources[k]); + context->PSSetShaderResources(0, 8, shader_resources); // unbind all textures if (apply_called) { stateman->PopBlendState(); @@ -318,9 +321,9 @@ template AutoState::~AutoState() StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {} -void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state));} -void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state));} -void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state));} +void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state)); } +void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state)); } +void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state)); } void StateManager::PopBlendState() { blendstates.pop(); } void StateManager::PopDepthState() { depthstates.pop(); } void StateManager::PopRasterizerState() { raststates.pop(); } @@ -335,7 +338,7 @@ void StateManager::Apply() D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF); } } - else D3D::context->OMSetBlendState(NULL, NULL, 0xFFFFFFFF); + else ERROR_LOG(VIDEO, "Tried to apply without blend state!"); if (!depthstates.empty()) { @@ -345,7 +348,7 @@ void StateManager::Apply() D3D::context->OMSetDepthStencilState(cur_depthstate, 0); } } - else D3D::context->OMSetDepthStencilState(NULL, 0); + else ERROR_LOG(VIDEO, "Tried to apply without depth state!"); if (!raststates.empty()) { @@ -355,7 +358,7 @@ void StateManager::Apply() D3D::context->RSSetState(cur_raststate); } } - else D3D::context->RSSetState(NULL); + else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!"); } -} // namespace +} // namespace \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index ba82aff1a0..1e18ea17f2 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -16,7 +16,6 @@ // http://code.google.com/p/dolphin-emu/ #include -#include #include "StringUtil.h" #include "Common.h" @@ -766,13 +765,13 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); D3D::stateman->PushDepthState(cleardepthstates[zEnable]); D3D::stateman->PushRasterizerState(clearraststate); - //D3D::stateman->PushBlendState(resetblendstate); temporarily comented till i found the cause of th blending error in mkwii - D3D::stateman->Apply(); + //D3D::stateman->PushBlendState(resetblendstate); temporarily commented until I find the cause of the blending issue in mkwii (see next line) + D3D::gfxstate->ApplyState(); // TODO (neobrain): find out whether this breaks/fixes anything or can just be dropped. Might obsolete the comment above this line D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout()); - + D3D::gfxstate->Reset(); D3D::stateman->PopDepthState(); D3D::stateman->PopRasterizerState(); - //D3D::stateman->PopBlendState(); +// D3D::stateman->PopBlendState(); UpdateViewport(); SetScissorRect(); } @@ -896,7 +895,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) D3D::context->Unmap(buftex, 0); // ready to be saved - hr = D3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, s_sScreenshotName); + hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, s_sScreenshotName); if (FAILED(hr)) PanicAlert("Failed to save screenshot"); buftex->Release(); s_bScreenshot = false; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 398e5516a2..f21313571d 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -312,7 +312,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u entry.isNonPow2 = false; entry.MipLevels = maxlevel; - if (TexLevels == 0) D3DX11FilterTexture(D3D::context, entry.texture->GetTex(), 0, D3DX11_DEFAULT); + if (TexLevels == 0) PD3DX11FilterTexture(D3D::context, entry.texture->GetTex(), 0, D3DX11_DEFAULT); else if (TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE) { unsigned int level = 1;