From 8244efcc02b1aed06214bc58e5503ca5d68b4e63 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 11 Jun 2011 19:37:21 +0000 Subject: [PATCH] Revert r7421 and r7422. Should fix issue 4413. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7592 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/LinearDiskCache.h | 47 ++- .../Plugin_VideoDX11/Plugin_VideoDX11.vcxproj | 2 + .../Plugin_VideoDX11.vcxproj.filters | 6 + .../Plugins/Plugin_VideoDX11/Src/D3DBase.cpp | 316 ++++++------------ Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h | 34 +- .../Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp | 69 ++++ Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h | 53 +++ .../Plugin_VideoDX11/Src/D3DShader.cpp | 265 +++++++++------ .../Plugins/Plugin_VideoDX11/Src/D3DShader.h | 64 ++-- .../Plugin_VideoDX11/Src/D3DTexture.cpp | 73 ++-- .../Plugins/Plugin_VideoDX11/Src/D3DTexture.h | 24 +- .../Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp | 242 +++++++------- Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.h | 188 +++-------- .../Src/FramebufferManager.cpp | 186 +++++------ .../Plugin_VideoDX11/Src/FramebufferManager.h | 47 ++- .../Plugins/Plugin_VideoDX11/Src/GfxState.cpp | 61 +++- .../Plugins/Plugin_VideoDX11/Src/GfxState.h | 55 +-- .../Src/LineGeometryShader.cpp | 42 ++- .../Plugin_VideoDX11/Src/LineGeometryShader.h | 14 +- .../Src/NativeVertexFormat.cpp | 24 +- .../Plugin_VideoDX11/Src/PSTextureEncoder.cpp | 221 +++++++----- .../Plugin_VideoDX11/Src/PSTextureEncoder.h | 43 ++- .../Plugin_VideoDX11/Src/PixelShaderCache.cpp | 168 +++++----- .../Plugin_VideoDX11/Src/PixelShaderCache.h | 12 +- .../Src/PointGeometryShader.cpp | 42 ++- .../Src/PointGeometryShader.h | 14 +- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 215 ++++++------ Source/Plugins/Plugin_VideoDX11/Src/Render.h | 4 - .../Plugin_VideoDX11/Src/Television.cpp | 24 +- .../Plugins/Plugin_VideoDX11/Src/Television.h | 15 +- .../Plugin_VideoDX11/Src/TextureCache.cpp | 57 ++-- .../Plugin_VideoDX11/Src/TextureCache.h | 6 +- .../Plugin_VideoDX11/Src/TextureEncoder.h | 9 +- .../Plugin_VideoDX11/Src/VertexManager.cpp | 74 ++-- .../Plugin_VideoDX11/Src/VertexManager.h | 7 +- .../Src/VertexShaderCache.cpp | 110 +++--- .../Plugin_VideoDX11/Src/VertexShaderCache.h | 34 +- .../Plugin_VideoDX11/Src/XFBEncoder.cpp | 130 ++++--- .../Plugins/Plugin_VideoDX11/Src/XFBEncoder.h | 35 +- Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 5 +- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 14 +- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 16 +- 42 files changed, 1647 insertions(+), 1420 deletions(-) create mode 100644 Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp create mode 100644 Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index 6ead5a8b7f..7a124aaa7b 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -20,7 +20,6 @@ #include "Common.h" #include -#include // Update this to the current SVN revision every time you change shader generation code. // We don't automatically get this from SVN_REV because that would mean regenerating the @@ -44,15 +43,12 @@ enum // value_type[value_size] value; //} -// Example reader: -// -//class LinearDiskCacheReader -//{ -//public: -// template -// void operator()(const K& key, u32 value_size, F get_data) const -// {...} -//}; +template +class LinearDiskCacheReader +{ +public: + virtual void Read(const K &key, const V *value, u32 value_size) = 0; +}; // Dead simple unsorted key-value store with append functionality. // No random read functionality, all reading is done in OpenAndRead. @@ -71,45 +67,48 @@ class LinearDiskCache { public: // return number of read entries - template - u32 OpenAndRead(const char* filename, LinearDiskCacheReader& reader) + u32 OpenAndRead(const char *filename, LinearDiskCacheReader &reader) { - using std::ios; + using std::ios_base; // close any currently opened file Close(); // try opening for reading/writing - m_file.open(filename, ios::in | ios::out | ios::binary | ios::app); + m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary | ios_base::app); if (m_file.is_open() && ValidateHeader()) { // good header, read some key/value pairs u32 num_entries = 0; - - u32 value_size; K key; - while (Read(&value_size) && Read(&key)) + + V *value = NULL; + u32 value_size; + + while (Read(&value_size)) { - std::streamoff const pos = m_file.tellg(); + delete[] value; + value = new V[value_size]; - // pass key and value_size to reader with callback function to read the data - reader(key, value_size, [this, &value_size](V* data){ Read(data, value_size); }); - - // seek past data (in case reader didn't read it for whatever reason) - m_file.seekg(pos + (value_size * sizeof(V)), ios::beg); + // read key/value and pass to reader + if (Read(&key) && Read(value, value_size)) + reader.Read(key, value, value_size); + else + break; ++num_entries; } m_file.clear(); + delete[] value; return num_entries; } // failed to open file for reading or bad header // close and recreate file Close(); - m_file.open(filename, ios::out | ios::trunc | ios::binary); + m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); WriteHeader(); return 0; } diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj index d5b9c2c0cf..f1f4d40457 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj @@ -191,6 +191,7 @@ + @@ -219,6 +220,7 @@ + diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters index fb72a8a2af..6492e887ca 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters @@ -6,6 +6,9 @@ D3D + + D3D + D3D @@ -66,6 +69,9 @@ D3D + + D3D + D3D diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp index 66f0bc11a0..1dcc6dd193 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp @@ -43,120 +43,20 @@ int dxgi_dll_ref = 0; 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; -D3D10CREATEBLOB PD3D10CreateBlob = NULL; - -HINSTANCE hD3DDll_10 = NULL; -HINSTANCE hD3DDll_11 = NULL; - +HINSTANCE hD3DDll = NULL; int d3d_dll_ref = 0; -// SharedPtr funcs -HRESULT D3D11CreateDeviceShared(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, - HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels, - UINT FeatureLevels, UINT SDKVersion, SharedPtr* _Device, - D3D_FEATURE_LEVEL *pFeatureLevel, SharedPtr* _ImmediateContext) -{ - ID3D11Device* device = nullptr; - ID3D11DeviceContext* context = nullptr; - - const HRESULT hr = PD3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, - FeatureLevels, SDKVersion, &device, pFeatureLevel, &context); - - if (_Device) - *_Device = SharedPtr::FromPtr(device); - - if (_ImmediateContext) - *_ImmediateContext = SharedPtr::FromPtr(context); - - return hr; -} - -HRESULT D3D11CreateDeviceAndSwapChainShared(IDXGIAdapter *pAdapter, - D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels, - UINT FeatureLevels, UINT SDKVersion, const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, - SharedPtr* _SwapChain, SharedPtr* _Device, - D3D_FEATURE_LEVEL *pFeatureLevel, SharedPtr* _ImmediateContext) -{ - ID3D11Device* device = nullptr; - IDXGISwapChain* chain = nullptr; - ID3D11DeviceContext* context = nullptr; - - const HRESULT hr = PD3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, - pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, &chain, &device, pFeatureLevel, &context); - - if (_Device) - *_Device = SharedPtr::FromPtr(device); - - if (_SwapChain) - *_SwapChain = SharedPtr::FromPtr(chain); - - if (_ImmediateContext) - *_ImmediateContext = SharedPtr::FromPtr(context); - - return hr; -} - -SharedPtr CreateTexture2DShared( - const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData) -{ - ID3D11Texture2D* texture = nullptr; - - D3D::g_device->CreateTexture2D(pDesc, pInitialData, &texture); - - return SharedPtr::FromPtr(texture); -} - -SharedPtr SwapChainGetBufferTexture2DShared(IDXGISwapChain* swapchain, UINT buffer) -{ - ID3D11Texture2D* buf = nullptr; - - swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); - - return SharedPtr::FromPtr(buf); -} - -SharedPtr CreateBlendStateShared(const D3D11_BLEND_DESC *pBlendStateDesc) -{ - ID3D11BlendState* state = nullptr; - - D3D::g_device->CreateBlendState(pBlendStateDesc, &state); - - return SharedPtr::FromPtr(state); -} - -SharedPtr CreateInputLayoutShared(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, - UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength) -{ - ID3D11InputLayout* layout = nullptr; - - D3D::g_device->CreateInputLayout(pInputElementDescs, NumElements, - pShaderBytecodeWithInputSignature, BytecodeLength, &layout); - - return SharedPtr::FromPtr(layout); -} - -SharedPtr CreateBufferShared(const D3D11_BUFFER_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData) -{ - ID3D11Buffer* buffer = nullptr; - - D3D::g_device->CreateBuffer(pDesc, pInitialData, &buffer); - - return SharedPtr::FromPtr(buffer); -} - namespace D3D { -SharedPtr g_device; -SharedPtr g_context; -SharedPtr g_swapchain; - +ID3D11Device* device = NULL; +ID3D11DeviceContext* context = NULL; +IDXGISwapChain* swapchain = NULL; D3D_FEATURE_LEVEL featlevel; -std::unique_ptr backbuf; +D3DTexture2D* backbuf = NULL; HWND hWnd; -std::vector g_aa_modes; // supported AA modes of the current adapter +std::vector aa_modes; // supported AA modes of the current adapter bool bgra_textures_supported; @@ -191,36 +91,21 @@ HRESULT LoadDXGI() HRESULT LoadD3D() { - if (d3d_dll_ref++ > 0) - return S_OK; + if (d3d_dll_ref++ > 0) return S_OK; - hD3DDll_10 = LoadLibraryA("d3d10.dll"); - if (!hD3DDll_10) - { - MessageBoxA(NULL, "Failed to load d3d10.dll", "Critical error", MB_OK | MB_ICONERROR); - --d3d_dll_ref; - return E_FAIL; - } - - hD3DDll_11 = LoadLibraryA("d3d11.dll"); - if (!hD3DDll_11) + if (hD3DDll) return S_OK; + hD3DDll = LoadLibraryA("d3d11.dll"); + if (!hD3DDll) { MessageBoxA(NULL, "Failed to load d3d11.dll", "Critical error", MB_OK | MB_ICONERROR); --d3d_dll_ref; return E_FAIL; } + PD3D11CreateDevice = (D3D11CREATEDEVICE)GetProcAddress(hD3DDll, "D3D11CreateDevice"); + if (PD3D11CreateDevice == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDevice!", "Critical error", MB_OK | MB_ICONERROR); - PD3D11CreateDevice = (D3D11CREATEDEVICE)GetProcAddress(hD3DDll_11, "D3D11CreateDevice"); - if (PD3D11CreateDevice == NULL) - MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDevice!", "Critical error", MB_OK | MB_ICONERROR); - - PD3D11CreateDeviceAndSwapChain = (D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(hD3DDll_11, "D3D11CreateDeviceAndSwapChain"); - if (PD3D11CreateDeviceAndSwapChain == NULL) - MessageBoxA(NULL, "GetProcAddress failed for D3D11CreateDeviceAndSwapChain!", "Critical error", MB_OK | MB_ICONERROR); - - PD3D10CreateBlob = (D3D10CREATEBLOB)GetProcAddress(hD3DDll_10, "D3D10CreateBlob"); - if (PD3D10CreateBlob == NULL) - MessageBoxA(NULL, "GetProcAddress failed for D3D10CreateBlob!", "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; } @@ -316,17 +201,13 @@ void UnloadD3DX() void UnloadD3D() { - if (!d3d_dll_ref || --d3d_dll_ref != 0) - return; - - FreeLibrary(hD3DDll_10); - FreeLibrary(hD3DDll_11); - - hD3DDll_10 = hD3DDll_11 = NULL; + if (!d3d_dll_ref) return; + if (--d3d_dll_ref != 0) return; + if(hD3DDll) FreeLibrary(hD3DDll); + hD3DDll = NULL; PD3D11CreateDevice = NULL; PD3D11CreateDeviceAndSwapChain = NULL; - PD3D10CreateBlob = NULL; } void UnloadD3DCompiler() @@ -341,48 +222,45 @@ void UnloadD3DCompiler() std::vector EnumAAModes(IDXGIAdapter* adapter) { - // NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources. - // Thus, we can't have MSAA with 10.0 level hardware. - D3D_FEATURE_LEVEL feat_level; - - SharedPtr device; - SharedPtr context; - - const HRESULT hr = D3D11CreateDeviceShared(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, - D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, - NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, std::addressof(device), &feat_level, std::addressof(context)); - std::vector aa_modes; + // NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources. + // Thus, we can't have MSAA with 10.0 level hardware. + ID3D11Device* device; + ID3D11DeviceContext* context; + D3D_FEATURE_LEVEL feat_level; + HRESULT hr = PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &device, &feat_level, &context); if (FAILED(hr) || feat_level == D3D_FEATURE_LEVEL_10_0) { DXGI_SAMPLE_DESC desc; desc.Count = 1; desc.Quality = 0; aa_modes.push_back(desc); + SAFE_RELEASE(context); + SAFE_RELEASE(device); } else { - for (UINT samples = 0; samples != D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++samples) + 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) - { + if (quality_levels > 0) { DXGI_SAMPLE_DESC desc; desc.Count = samples; - for (desc.Quality = 0; desc.Quality != quality_levels; ++desc.Quality) + for (desc.Quality = 0; desc.Quality < quality_levels; ++desc.Quality) aa_modes.push_back(desc); } } + context->Release(); + device->Release(); } - return aa_modes; } DXGI_SAMPLE_DESC GetAAMode(int index) { - return g_aa_modes[index]; + return aa_modes[index]; } HRESULT Create(HWND wnd) @@ -409,37 +287,31 @@ HRESULT Create(HWND wnd) } IDXGIFactory* factory; - hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); - if (FAILED(hr)) - MessageBox(wnd, _T("Failed to create IDXGIFactory object"), - _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); - IDXGIAdapter* adapter; + IDXGIOutput* output; + hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); + if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); - if (FAILED(hr)) - MessageBox(wnd, _T("Failed to enumerate adapters"), - _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable - IDXGIOutput* output; hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one hr = adapter->EnumOutputs(0, &output); - if (FAILED(hr)) - MessageBox(wnd, _T("Failed to enumerate outputs"), - _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes - g_aa_modes = EnumAAModes(adapter); - if (g_Config.iMultisampleMode >= (int)g_aa_modes.size()) + aa_modes = EnumAAModes(adapter); + if (g_Config.iMultisampleMode >= (int)aa_modes.size()) { g_Config.iMultisampleMode = 0; UpdateActiveConfig(); @@ -461,58 +333,49 @@ HRESULT Create(HWND wnd) mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL); - if (FAILED(hr)) - MessageBox(wnd, _T("Failed to find a supported video mode"), - _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); // forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported! swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; #if defined(_DEBUG) || defined(DEBUGFAST) - const D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG - | D3D11_CREATE_DEVICE_SINGLETHREADED); + D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED); #else - const D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED; + D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED; #endif - - SharedPtr device; - SharedPtr swapchain; - SharedPtr context; - - hr = D3D11CreateDeviceAndSwapChainShared(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags, - supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, - &swap_chain_desc, std::addressof(swapchain), std::addressof(device), &featlevel, std::addressof(context)); - - if (FAILED(hr) || !device || !swapchain || !context) + hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags, + supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, + D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, + &featlevel, &context); + if (FAILED(hr) || !device || !context || !swapchain) { - MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), - _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + SAFE_RELEASE(device); + SAFE_RELEASE(context); + SAFE_RELEASE(swapchain); return E_FAIL; } - - SetDebugObjectName(context, "device context"); - + SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); - auto const buf = SwapChainGetBufferTexture2DShared(swapchain, 0); - if (!buf) + ID3D11Texture2D* buf; + hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); + if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + SAFE_RELEASE(device); + SAFE_RELEASE(context); + SAFE_RELEASE(swapchain); return E_FAIL; } - - g_device = device; - g_context = context; - g_swapchain = swapchain; - - backbuf.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET)); - + backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); + SAFE_RELEASE(buf); CHECK(backbuf!=NULL, "Create back buffer texture"); - SetDebugObjectName(backbuf->GetTex(), "backbuffer texture"); - SetDebugObjectName(backbuf->GetRTV(), "backbuffer render target view"); + SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); + SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL); @@ -521,22 +384,30 @@ HRESULT Create(HWND wnd) device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; - stateman.reset(new StateManager); - + stateman = new StateManager; return S_OK; } void Close() { // release all bound resources - g_context->ClearState(); - backbuf.reset(); - g_swapchain.reset(); - stateman.reset(); - g_context->Flush(); // immediately destroy device objects + context->ClearState(); + SAFE_RELEASE(backbuf); + SAFE_RELEASE(swapchain); + SAFE_DELETE(stateman); + context->Flush(); // immediately destroy device objects - g_context.reset(); - g_device.reset(); + SAFE_RELEASE(context); + ULONG references = device->Release(); + if (references) + { + ERROR_LOG(VIDEO, "Unreleased references: %i.", references); + } + else + { + NOTICE_LOG(VIDEO, "Successfully released all device references!"); + } + device = NULL; // unload DLLs UnloadD3DX(); @@ -565,7 +436,7 @@ const char* PixelShaderVersionString() else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/ return "ps_4_0"; } -D3DTexture2D* GetBackBuffer() { return backbuf.get(); } +D3DTexture2D* &GetBackBuffer() { return backbuf; } unsigned int GetBackBufferWidth() { return xres; } unsigned int GetBackBufferHeight() { return yres; } @@ -598,27 +469,31 @@ unsigned int GetMaxTextureSize() void Reset() { // release all back buffer references - backbuf.reset(); + SAFE_RELEASE(backbuf); // resize swapchain buffers RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; - D3D::g_swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + D3D::swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0); // recreate back buffer texture - auto const buf = SwapChainGetBufferTexture2DShared(g_swapchain, 0); - if (!buf) + ID3D11Texture2D* buf; + HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); + if (FAILED(hr)) { MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); + SAFE_RELEASE(device); + SAFE_RELEASE(context); + SAFE_RELEASE(swapchain); return; } - - backbuf.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET)); + backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); + SAFE_RELEASE(buf); CHECK(backbuf!=NULL, "Create back buffer texture"); - SetDebugObjectName(backbuf->GetTex(), "backbuffer texture"); - SetDebugObjectName(backbuf->GetRTV(), "backbuffer render target view"); + SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); + SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); } bool BeginFrame() @@ -628,9 +503,8 @@ bool BeginFrame() PanicAlert("BeginFrame called although a frame is already in progress"); return false; } - bFrameInProgress = true; - return (g_device != NULL); + return (device != NULL); } void EndFrame() @@ -646,7 +520,7 @@ void EndFrame() void Present() { // TODO: Is 1 the correct value for vsyncing? - g_swapchain->Present((UINT)g_ActiveConfig.bVSync, 0); + swapchain->Present((UINT)g_ActiveConfig.bVSync, 0); } } // namespace D3D diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h index 1dfe7a3dbd..d18bbaecf6 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h @@ -17,35 +17,21 @@ #pragma once -#include - #include #include - -#include "D3DUtil.h" #include "Common.h" +#include namespace DX11 { #define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; } - -#define CHECK(cond, Message, ...) if (!(cond)) { \ - PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } +#define SAFE_DELETE(x) { delete (x); (x) = NULL; } +#define SAFE_DELETE_ARRAY(x) { delete[] (x); (x) = NULL; } +#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } class D3DTexture2D; -SharedPtr CreateTexture2DShared( - const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData); - -SharedPtr CreateBlendStateShared(const D3D11_BLEND_DESC *pBlendStateDesc); - -SharedPtr CreateInputLayoutShared(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, - UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength); - -SharedPtr CreateBufferShared(const D3D11_BUFFER_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData); - namespace D3D { @@ -64,10 +50,9 @@ DXGI_SAMPLE_DESC GetAAMode(int index); HRESULT Create(HWND wnd); void Close(); -extern SharedPtr g_device; -extern SharedPtr g_context; -extern SharedPtr g_swapchain; - +extern ID3D11Device* device; +extern ID3D11DeviceContext* context; +extern IDXGISwapChain* swapchain; extern bool bFrameInProgress; void Reset(); @@ -77,7 +62,7 @@ void Present(); unsigned int GetBackBufferWidth(); unsigned int GetBackBufferHeight(); -D3DTexture2D* GetBackBuffer(); +D3DTexture2D* &GetBackBuffer(); const char* PixelShaderVersionString(); const char* GeometryShaderVersionString(); const char* VertexShaderVersionString(); @@ -93,7 +78,6 @@ 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); #endif @@ -127,8 +111,6 @@ 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; -typedef HRESULT (WINAPI* D3D10CREATEBLOB)(SIZE_T NumBytes, LPD3D10BLOB *ppBuffer); -extern D3D10CREATEBLOB PD3D10CreateBlob; typedef HRESULT (WINAPI *D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**); extern D3DREFLECT PD3DReflect; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp new file mode 100644 index 0000000000..6700de5540 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include "D3DBlob.h" + +namespace DX11 +{ + +D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL) +{ + data = new u8[blob_size]; + if (init_data) memcpy(data, init_data, size); +} + +D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1) +{ + blob = d3dblob; + data = (u8*)blob->GetBufferPointer(); + size = (unsigned int)blob->GetBufferSize(); + d3dblob->AddRef(); +} + +D3DBlob::~D3DBlob() +{ + if (blob) blob->Release(); + else delete[] data; +} + +void D3DBlob::AddRef() +{ + ++ref; +} + +unsigned int D3DBlob::Release() +{ + if (--ref == 0) + { + delete this; + return 0; + } + return ref; +} + +unsigned int D3DBlob::Size() +{ + return size; +} + +u8* D3DBlob::Data() +{ + return data; +} + +} // namespace DX11 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h new file mode 100644 index 0000000000..b5c80662b8 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h @@ -0,0 +1,53 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +#include "CommonTypes.h" + +struct ID3D10Blob; + +namespace DX11 +{ + +// use this class instead ID3D10Blob or ID3D11Blob whenever possible +class D3DBlob +{ +public: + // memory will be copied into an own buffer + D3DBlob(unsigned int blob_size, const u8* init_data = NULL); + + // d3dblob will be AddRef'd + D3DBlob(ID3D10Blob* d3dblob); + + void AddRef(); + unsigned int Release(); + + unsigned int Size(); + u8* Data(); + +private: + ~D3DBlob(); + + unsigned int ref; + unsigned int size; + + u8* data; + ID3D10Blob* blob; +}; + +} // namespace \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp index 4412f91b4c..8e02a6db59 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp @@ -19,6 +19,7 @@ #include "VideoConfig.h" +#include "D3DBase.h" #include "D3DShader.h" namespace DX11 @@ -28,149 +29,217 @@ namespace D3D { // bytecode->shader -SharedPtr CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len) +ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len) { - ID3D11VertexShader* v_shader = nullptr; - HRESULT hr = D3D::g_device->CreateVertexShader(bytecode, len, NULL, &v_shader); + ID3D11VertexShader* v_shader; + HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, NULL, &v_shader); if (FAILED(hr)) - PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", - bytecode, len, __FILE__, __LINE__); - - return SharedPtr::FromPtr(v_shader); + { + PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__); + v_shader = NULL; + } + return v_shader; } -// bytecode->shader -SharedPtr CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len) +// code->bytecode +bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob) { - ID3D11GeometryShader* g_shader = nullptr; - HRESULT hr = D3D::g_device->CreateGeometryShader(bytecode, len, NULL, &g_shader); - if (FAILED(hr)) - PanicAlert("CreateGeometryShaderFromByteCode failed from %p (size %d) at %s %d\n", - bytecode, len, __FILE__, __LINE__); - - return SharedPtr::FromPtr(g_shader); -} - -// bytecode->shader -SharedPtr CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len) -{ - ID3D11PixelShader* p_shader = nullptr; - HRESULT hr = D3D::g_device->CreatePixelShader(bytecode, len, NULL, &p_shader); - if (FAILED(hr)) - PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__); - - return SharedPtr::FromPtr(p_shader); -} - -static SharedPtr CompileShader(const char* code, unsigned int len, - const char* ver_str, const D3D_SHADER_MACRO* pDefines = NULL) -{ - static const UINT shader_compilation_flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY + ID3D10Blob* shaderBuffer = NULL; + ID3D10Blob* errorBuffer = NULL; #if defined(_DEBUG) || defined(DEBUGFAST) - | D3D10_SHADER_DEBUG | D3D10_SHADER_WARNINGS_ARE_ERRORS; + UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS; #else - | D3D10_SHADER_OPTIMIZATION_LEVEL3 | D3D10_SHADER_SKIP_VALIDATION; + UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION; #endif - - ID3D10Blob* shaderBuffer = nullptr; - ID3D10Blob* errorBuffer = nullptr; - - HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", ver_str, - shader_compilation_flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL); - - if (FAILED(hr) && g_ActiveConfig.bShowShaderErrors) - { - std::string msg = (const char*)errorBuffer->GetBufferPointer(); - msg += "\n\n"; - msg += ver_str; - msg += "\n\n"; - msg += code; - MessageBoxA(0, msg.c_str(), "Error compiling shader", MB_ICONERROR); - } - + HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(), + flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL); + if (errorBuffer) { - INFO_LOG(VIDEO, "Shader %s compiler messages:\n%s\n", ver_str, + INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s\n", (const char*)errorBuffer->GetBufferPointer()); + } + if (FAILED(hr)) + { + if (g_ActiveConfig.bShowShaderErrors) + { + std::string msg = (char*)errorBuffer->GetBufferPointer(); + msg += "\n\n"; + msg += D3D::VertexShaderVersionString(); + msg += "\n\n"; + msg += code; + MessageBoxA(0, msg.c_str(), "Error compiling vertex shader", MB_ICONERROR); + } + + *blob = NULL; errorBuffer->Release(); } - - return SharedPtr::FromPtr(shaderBuffer); + else + { + *blob = new D3DBlob(shaderBuffer); + shaderBuffer->Release(); + } + return SUCCEEDED(hr); } -// code->bytecode -SharedPtr CompileVertexShader(const char* code, unsigned int len) +// bytecode->shader +ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len) { - return CompileShader(code, len, D3D::VertexShaderVersionString()); + ID3D11GeometryShader* g_shader; + HRESULT hr = D3D::device->CreateGeometryShader(bytecode, len, NULL, &g_shader); + if (FAILED(hr)) + { + PanicAlert("CreateGeometryShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__); + g_shader = NULL; + } + return g_shader; } // code->bytecode -SharedPtr CompileGeometryShader(const char* code, unsigned int len, +bool CompileGeometryShader(const char* code, unsigned int len, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines) { - return CompileShader(code, len, D3D::GeometryShaderVersionString(), pDefines); + ID3D10Blob* shaderBuffer = NULL; + ID3D10Blob* errorBuffer = NULL; + +#if defined(_DEBUG) || defined(DEBUGFAST) + UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS; +#else + UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION; +#endif + HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", D3D::GeometryShaderVersionString(), + flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL); + + if (errorBuffer) + { + INFO_LOG(VIDEO, "Geometry shader compiler messages:\n%s\n", + (const char*)errorBuffer->GetBufferPointer()); + } + + if (FAILED(hr)) + { + if (g_ActiveConfig.bShowShaderErrors) + { + std::string msg = (char*)errorBuffer->GetBufferPointer(); + msg += "\n\n"; + msg += D3D::GeometryShaderVersionString(); + msg += "\n\n"; + msg += code; + MessageBoxA(0, msg.c_str(), "Error compiling geometry shader", MB_ICONERROR); + } + + *blob = NULL; + errorBuffer->Release(); + } + else + { + *blob = new D3DBlob(shaderBuffer); + shaderBuffer->Release(); + } + return SUCCEEDED(hr); +} + +// bytecode->shader +ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len) +{ + ID3D11PixelShader* p_shader; + HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, NULL, &p_shader); + if (FAILED(hr)) + { + PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__); + p_shader = NULL; + } + return p_shader; } // code->bytecode -SharedPtr CompilePixelShader(const char* code, unsigned int len, +bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines) { - return CompileShader(code, len, D3D::PixelShaderVersionString(), pDefines); -} + ID3D10Blob* shaderBuffer = NULL; + ID3D10Blob* errorBuffer = NULL; -SharedPtr CompileAndCreateVertexShader(const char* code, unsigned int len, - SharedPtr* bytecode) -{ - auto const blob = CompileVertexShader(code, len); - if (blob) +#if defined(_DEBUG) || defined(DEBUGFAST) + UINT flags = D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS; +#else + UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3; +#endif + HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", D3D::PixelShaderVersionString(), + flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL); + + if (errorBuffer) { - if (bytecode) - *bytecode = blob; - return CreateVertexShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize()); + INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s", + (const char*)errorBuffer->GetBufferPointer()); + } + + if (FAILED(hr)) + { + if (g_ActiveConfig.bShowShaderErrors) + { + std::string msg = (char*)errorBuffer->GetBufferPointer(); + msg += "\n\n"; + msg += D3D::PixelShaderVersionString(); + msg += "\n\n"; + msg += code; + MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR); + } + + *blob = NULL; + errorBuffer->Release(); } else { - PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", - code, len, __FILE__, __LINE__); - return SharedPtr::FromPtr(nullptr); + *blob = new D3DBlob(shaderBuffer); + shaderBuffer->Release(); } + + return SUCCEEDED(hr); } -SharedPtr CompileAndCreateGeometryShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines, SharedPtr* bytecode) +ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, + unsigned int len) { - auto const blob = CompileGeometryShader(code, len, pDefines); - if (blob) + D3DBlob* blob = NULL; + if (CompileVertexShader(code, len, &blob)) { - if (bytecode) - *bytecode = blob; - return CreateGeometryShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize()); - } - else - { - PanicAlert("Failed to compile and create geometry shader from %p (size %d) at %s %d\n", - code, len, __FILE__, __LINE__); - return SharedPtr::FromPtr(nullptr); + ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob); + blob->Release(); + return v_shader; } + PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__); + return NULL; } -SharedPtr CompileAndCreatePixelShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines, SharedPtr* bytecode) +ID3D11GeometryShader* CompileAndCreateGeometryShader(const char* code, + unsigned int len, const D3D_SHADER_MACRO* pDefines) { - auto const blob = CompilePixelShader(code, len, pDefines); + D3DBlob* blob = NULL; + if (CompileGeometryShader(code, len, &blob, pDefines)) + { + ID3D11GeometryShader* g_shader = CreateGeometryShaderFromByteCode(blob); + blob->Release(); + return g_shader; + } + PanicAlert("Failed to compile and create geometry shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__); + return NULL; +} + +ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, + unsigned int len) +{ + D3DBlob* blob = NULL; + CompilePixelShader(code, len, &blob); if (blob) { - if (bytecode) - *bytecode = blob; - return CreatePixelShaderFromByteCode(blob->GetBufferPointer(), (unsigned int)blob->GetBufferSize()); - } - else - { - PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__); - return SharedPtr::FromPtr(nullptr); + ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob); + blob->Release(); + return p_shader; } + PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__); + return NULL; } } // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h index 4e2c00792b..8594e22851 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h @@ -18,47 +18,49 @@ #pragma once #include "D3DBase.h" +#include "D3DBlob.h" + +struct ID3D11PixelShader; +struct ID3D11VertexShader; namespace DX11 { namespace D3D { + ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len); + ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len); + ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len); -// returns bytecode -SharedPtr CompileVertexShader(const char* code, unsigned int len); -SharedPtr CompileGeometryShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines = NULL); -SharedPtr CompilePixelShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines = NULL); + // The returned bytecode buffers should be Release()d. + bool CompileVertexShader(const char* code, unsigned int len, + D3DBlob** blob); + bool CompileGeometryShader(const char* code, unsigned int len, + D3DBlob** blob, const D3D_SHADER_MACRO* pDefines = NULL); + bool CompilePixelShader(const char* code, unsigned int len, + D3DBlob** blob, const D3D_SHADER_MACRO* pDefines = NULL); -SharedPtr CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len); -SharedPtr CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len); -SharedPtr CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len); + // Utility functions + ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, + unsigned int len); + ID3D11GeometryShader* CompileAndCreateGeometryShader(const char* code, + unsigned int len, const D3D_SHADER_MACRO* pDefines = NULL); + ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, + unsigned int len); -inline SharedPtr CreateVertexShaderFromByteCode(SharedPtr bytecode) -{ - return CreateVertexShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize()); -} - -inline SharedPtr CreateGeometryShaderFromByteCode(SharedPtr bytecode) -{ - return CreateGeometryShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize()); -} - -inline SharedPtr CreatePixelShaderFromByteCode(SharedPtr bytecode) -{ - return CreatePixelShaderFromByteCode(bytecode->GetBufferPointer(), (unsigned int)bytecode->GetBufferSize()); -} - -// Utility functions, optionally return the bytecode if "bytecode" is non-null -SharedPtr CompileAndCreateVertexShader(const char* code, unsigned int len, - SharedPtr* bytecode = nullptr); -SharedPtr CompileAndCreateGeometryShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines = nullptr, SharedPtr* bytecode = nullptr); -SharedPtr CompileAndCreatePixelShader(const char* code, unsigned int len, - const D3D_SHADER_MACRO* pDefines = nullptr, SharedPtr* bytecode = nullptr); + inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode) + { return CreateVertexShaderFromByteCode(bytecode->Data(), bytecode->Size()); } + inline ID3D11GeometryShader* CreateGeometryShaderFromByteCode(D3DBlob* bytecode) + { return CreateGeometryShaderFromByteCode(bytecode->Data(), bytecode->Size()); } + inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode) + { return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size()); } + inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code) + { return CompileAndCreateVertexShader((const char*)code->Data(), code->Size()); } + inline ID3D11GeometryShader* CompileAndCreateGeometryShader(D3DBlob* code, const D3D_SHADER_MACRO* pDefines = NULL) + { return CompileAndCreateGeometryShader((const char*)code->Data(), code->Size(), pDefines); } + inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code) + { return CompileAndCreatePixelShader((const char*)code->Data(), code->Size()); } } } // namespace DX11 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp index a7e63229aa..25e8d223a3 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp @@ -29,7 +29,7 @@ void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned if (usage == D3D11_USAGE_DYNAMIC || usage == D3D11_USAGE_STAGING) { D3D11_MAPPED_SUBRESOURCE map; - D3D::g_context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map); if (4 * pitch == map.RowPitch) { memcpy(map.pData, buffer, map.RowPitch * height); @@ -39,43 +39,63 @@ void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned for (unsigned int y = 0; y < height; ++y) memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, 4 * pitch); } - D3D::g_context->Unmap(pTexture, level); + D3D::context->Unmap(pTexture, level); } else { D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1); - D3D::g_context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height); + D3D::context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height); } } } // namespace -std::unique_ptr D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, - D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels) +D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels) { + ID3D11Texture2D* pTexture = NULL; + HRESULT hr; + D3D11_CPU_ACCESS_FLAG cpuflags; - if (usage == D3D11_USAGE_STAGING) - cpuflags = (D3D11_CPU_ACCESS_FLAG)(D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ); - else if (usage == D3D11_USAGE_DYNAMIC) - cpuflags = D3D11_CPU_ACCESS_WRITE; - else - cpuflags = (D3D11_CPU_ACCESS_FLAG)0; - - const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags); - - auto texture = CreateTexture2DShared(&texdesc, NULL); - if (!texture) + if (usage == D3D11_USAGE_STAGING) cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE|(int)D3D11_CPU_ACCESS_READ); + else if (usage == D3D11_USAGE_DYNAMIC) cpuflags = D3D11_CPU_ACCESS_WRITE; + else cpuflags = (D3D11_CPU_ACCESS_FLAG)0; + D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags); + hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture); + if (FAILED(hr)) { - PanicAlert("Failed to create texture at %s, line %d\n", __FILE__, __LINE__); + PanicAlert("Failed to create texture at %s, line %d: hr=%#x\n", __FILE__, __LINE__, hr); return NULL; } - return std::unique_ptr(new D3DTexture2D(texture, bind)); + D3DTexture2D* ret = new D3DTexture2D(pTexture, bind); + SAFE_RELEASE(pTexture); + return ret; } -D3DTexture2D::D3DTexture2D(SharedPtr texptr, D3D11_BIND_FLAG bind, - DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format, bool multisampled) - : ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL) +void D3DTexture2D::AddRef() +{ + ++ref; +} + +UINT D3DTexture2D::Release() +{ + --ref; + if (ref == 0) + { + delete this; + return 0; + } + return ref; +} + +ID3D11Texture2D* &D3DTexture2D::GetTex() { return tex; } +ID3D11ShaderResourceView* &D3DTexture2D::GetSRV() { return srv; } +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, bool multisampled) + : ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL) { 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; @@ -83,12 +103,10 @@ D3DTexture2D::D3DTexture2D(SharedPtr texptr, D3D11_BIND_FLAG bi 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::g_device->CreateShaderResourceView(tex, &srv_desc, &srv); - if (bind & D3D11_BIND_RENDER_TARGET) - D3D::g_device->CreateRenderTargetView(tex, &rtv_desc, &rtv); - if (bind & D3D11_BIND_DEPTH_STENCIL) - D3D::g_device->CreateDepthStencilView(tex, &dsv_desc, &dsv); + 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); + tex->AddRef(); } D3DTexture2D::~D3DTexture2D() @@ -96,6 +114,7 @@ D3DTexture2D::~D3DTexture2D() SAFE_RELEASE(srv); SAFE_RELEASE(rtv); SAFE_RELEASE(dsv); + SAFE_RELEASE(tex); } } // namespace DX11 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h index 65775e494e..9df78d31bb 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.h @@ -34,22 +34,22 @@ 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(SharedPtr 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); + 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 std::unique_ptr 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 + void AddRef(); + UINT Release(); - ID3D11Texture2D* GetTex() { return tex; } - ID3D11ShaderResourceView*const& GetSRV() { return srv; } - ID3D11RenderTargetView*const& GetRTV() { return rtv; } - ID3D11DepthStencilView*const& GetDSV() { return dsv; } - - ~D3DTexture2D(); + ID3D11Texture2D* &GetTex(); + ID3D11ShaderResourceView* &GetSRV(); + ID3D11RenderTargetView* &GetRTV(); + ID3D11DepthStencilView* &GetDSV(); private: - SharedPtr tex; + ~D3DTexture2D(); + + ID3D11Texture2D* tex; ID3D11ShaderResourceView* srv; ID3D11RenderTargetView* rtv; ID3D11DepthStencilView* dsv; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp index e218db019e..81a4cf96a6 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp @@ -34,35 +34,36 @@ namespace D3D class UtilVertexBuffer { public: - UtilVertexBuffer(UINT size) - : offset(0), max_size(size) + UtilVertexBuffer(int size) : buf(NULL), offset(0), max_size(size) { - D3D11_BUFFER_DESC desc = CD3D11_BUFFER_DESC(max_size, D3D11_BIND_VERTEX_BUFFER, - D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_buf = CreateBufferShared(&desc, NULL); + D3D11_BUFFER_DESC desc = CD3D11_BUFFER_DESC(max_size, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + device->CreateBuffer(&desc, NULL, &buf); + } + ~UtilVertexBuffer() + { + buf->Release(); } // returns vertex offset to the new data - int AppendData(void* data, UINT size, UINT vertex_size) + int AppendData(void* data, int size, int vertex_size) { D3D11_MAPPED_SUBRESOURCE map; - if (offset + size >= max_size) + if(offset + size >= max_size) { // wrap buffer around and notify observers offset = 0; - g_context->Map(m_buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + context->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - for each (auto obs in observers) - *obs = true; + for(std::list::iterator it = observers.begin(); it != observers.end(); ++it) + **it = true; } else { - g_context->Map(m_buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); + context->Map(buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); } - - offset = ((offset+vertex_size - 1) / vertex_size) * vertex_size; // align offset to vertex_size bytes + offset = ((offset+vertex_size-1)/vertex_size)*vertex_size; // align offset to vertex_size bytes memcpy((u8*)map.pData + offset, data, size); - g_context->Unmap(m_buf, 0); + context->Unmap(buf, 0); offset += size; return (offset - size) / vertex_size; @@ -73,18 +74,18 @@ public: observers.push_back(observer); } - ID3D11Buffer*const& GetBuffer() { return m_buf; } + inline ID3D11Buffer* &GetBuffer() { return buf; } private: - SharedPtr m_buf; - UINT offset; - UINT max_size; + ID3D11Buffer* buf; + int offset; + int max_size; std::list observers; }; CD3DFont font; -std::unique_ptr util_vbuf; +UtilVertexBuffer* util_vbuf = NULL; #define MAX_NUM_VERTICES 50*6 struct FONT2DVERTEX { @@ -103,10 +104,13 @@ inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, floa return v; } -CD3DFont::CD3DFont() - : m_dwTexWidth(512), m_dwTexHeight(512) +CD3DFont::CD3DFont() : m_dwTexWidth(512), m_dwTexHeight(512) { m_pTexture = NULL; + m_pVB = NULL; + m_InputLayout = NULL; + m_pshader = NULL; + m_vshader = NULL; } const char fontpixshader[] = { @@ -220,20 +224,21 @@ int CD3DFont::Init() // Create a new texture for the font // possible optimization: store the converted data in a buffer and fill the texture on creation. // That way, we can use a static texture + ID3D11Texture2D* buftex; D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, m_dwTexWidth, m_dwTexHeight, - 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - - auto buftex = CreateTexture2DShared(&texdesc, NULL); - if (!buftex) + 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, + D3D11_CPU_ACCESS_WRITE); + hr = device->CreateTexture2D(&texdesc, NULL, &buftex); + if (FAILED(hr)) { PanicAlert("Failed to create font texture"); - return S_FALSE; + return hr; } - D3D::SetDebugObjectName(buftex, "texture of a CD3DFont object"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object"); // Lock the surface and write the alpha values for the set pixels D3D11_MAPPED_SUBRESOURCE texmap; - hr = g_context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap); + hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap); if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__); for (y = 0; y < m_dwTexHeight; y++) @@ -247,12 +252,10 @@ int CD3DFont::Init() } // Done updating texture, so clean up used objects - g_context->Unmap(buftex, 0); - hr = D3D::g_device->CreateShaderResourceView(buftex, NULL, &m_pTexture); - if (FAILED(hr)) - PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__); - - buftex.reset(); + context->Unmap(buftex, 0); + hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture); + if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__); + SAFE_RELEASE(buftex); SelectObject(hDC, hOldbmBitmap); DeleteObject(hbmBitmap); @@ -262,16 +265,15 @@ int CD3DFont::Init() // setup device objects for drawing m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader, sizeof(fontpixshader)); - if (!m_pshader) - PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(m_pshader, "pixel shader of a CD3DFont object"); + if (m_pshader == NULL) PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_pshader, "pixel shader of a CD3DFont object"); - SharedPtr vsbytecode; - m_vshader = D3D::CompileAndCreateVertexShader(fontvertshader, sizeof(fontvertshader), std::addressof(vsbytecode)); - - if (!m_vshader) - PanicAlert("Failed to compile/create vertex shader, %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(m_vshader, "vertex shader of a CD3DFont object"); + D3DBlob* vsbytecode; + D3D::CompileVertexShader(fontvertshader, sizeof(fontvertshader), &vsbytecode); + if (vsbytecode == NULL) PanicAlert("Failed to compile vertex shader, %s %d\n", __FILE__, __LINE__); + m_vshader = D3D::CreateVertexShaderFromByteCode(vsbytecode); + if (m_vshader == NULL) PanicAlert("Failed to create vertex shader, %s %d\n", __FILE__, __LINE__); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vshader, "vertex shader of a CD3DFont object"); const D3D11_INPUT_ELEMENT_DESC desc[] = { @@ -279,11 +281,9 @@ int CD3DFont::Init() { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - - m_InputLayout = CreateInputLayoutShared(desc, 3, vsbytecode->GetBufferPointer(), - vsbytecode->GetBufferSize()); - if (!m_InputLayout) - PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); + hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode->Data(), vsbytecode->Size(), &m_InputLayout); + if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); + SAFE_RELEASE(vsbytecode); D3D11_BLEND_DESC blenddesc; blenddesc.AlphaToCoverageEnable = FALSE; @@ -296,37 +296,34 @@ int CD3DFont::Init() blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - m_blendstate = CreateBlendStateShared(&blenddesc); - CHECK(m_blendstate, "Create font blend state"); - D3D::SetDebugObjectName(m_blendstate, "blend state of a CD3DFont object"); + hr = D3D::device->CreateBlendState(&blenddesc, &m_blendstate); + CHECK(hr==S_OK, "Create font blend state"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_blendstate, "blend state of a CD3DFont object"); - D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, - false, 0, 0.f, 0.f, false, false, false, false); - hr = D3D::g_device->CreateRasterizerState(&rastdesc, &m_raststate); + D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false); + hr = D3D::device->CreateRasterizerState(&rastdesc, &m_raststate); CHECK(hr==S_OK, "Create font rasterizer state"); - D3D::SetDebugObjectName(m_raststate, "rasterizer state of a CD3DFont object"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_raststate, "rasterizer state of a CD3DFont object"); - D3D11_BUFFER_DESC vbdesc = CD3D11_BUFFER_DESC(MAX_NUM_VERTICES * sizeof(FONT2DVERTEX), - D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_pVB = CreateBufferShared(&vbdesc, NULL); - if (!m_pVB) + D3D11_BUFFER_DESC vbdesc = CD3D11_BUFFER_DESC(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + if (FAILED(hr = device->CreateBuffer(&vbdesc, NULL, &m_pVB))) { PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__); return hr; } - D3D::SetDebugObjectName(m_pVB, "vertex buffer of a CD3DFont object"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_pVB, "vertex buffer of a CD3DFont object"); return S_OK; } int CD3DFont::Shutdown() { - m_pVB.reset(); + SAFE_RELEASE(m_pVB); SAFE_RELEASE(m_pTexture); - m_InputLayout.reset(); - m_pshader.reset(); - m_vshader.reset(); + SAFE_RELEASE(m_InputLayout); + SAFE_RELEASE(m_pshader); + SAFE_RELEASE(m_vshader); - m_blendstate.reset(); + SAFE_RELEASE(m_blendstate); SAFE_RELEASE(m_raststate); return S_OK; @@ -354,7 +351,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw int dwNumTriangles = 0L; D3D11_MAPPED_SUBRESOURCE vbmap; - HRESULT hr = g_context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap); + HRESULT hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap); if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__); pVertices = (D3D::FONT2DVERTEX*)vbmap.pData; @@ -363,12 +360,12 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw D3D::stateman->PushRasterizerState(m_raststate); D3D::stateman->Apply(); - D3D::g_context->PSSetShader(m_pshader, NULL, 0); - D3D::g_context->VSSetShader(m_vshader, NULL, 0); + D3D::context->PSSetShader(m_pshader, NULL, 0); + D3D::context->VSSetShader(m_vshader, NULL, 0); - D3D::g_context->IASetInputLayout(m_InputLayout); - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - D3D::g_context->PSSetShaderResources(0, 1, &m_pTexture); + D3D::context->IASetInputLayout(m_InputLayout); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + D3D::context->PSSetShaderResources(0, 1, &m_pTexture); float fStartX = sx; while (c = *strText++) @@ -405,14 +402,14 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6)) { - g_context->Unmap(m_pVB, 0); + context->Unmap(m_pVB, 0); - D3D::g_context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset); - D3D::g_context->Draw(3 * dwNumTriangles, 0); + D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset); + D3D::context->Draw(3 * dwNumTriangles, 0); dwNumTriangles = 0; D3D11_MAPPED_SUBRESOURCE vbmap; - hr = g_context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap); + hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap); if (FAILED(hr)) PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__); pVertices = (D3D::FONT2DVERTEX*)vbmap.pData; } @@ -420,11 +417,11 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw } // Unlock and render the vertex buffer - g_context->Unmap(m_pVB, 0); + context->Unmap(m_pVB, 0); if (dwNumTriangles > 0) { - D3D::g_context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset); - D3D::g_context->Draw(3 * dwNumTriangles, 0); + D3D::context->IASetVertexBuffers(0, 1, &m_pVB, &stride, &bufoffset); + D3D::context->Draw(3 * dwNumTriangles, 0); } D3D::stateman->PopBlendState(); D3D::stateman->PopRasterizerState(); @@ -470,25 +467,18 @@ bool stq_observer, stsq_observer, cq_observer, clearq_observer; void InitUtils() { - util_vbuf.reset(new UtilVertexBuffer(0x4000)); + util_vbuf = new UtilVertexBuffer(0x4000); - const float border[4] = { 0.f, 0.f, 0.f, 0.f }; - D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, - D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, - 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); - HRESULT hr = D3D::g_device->CreateSamplerState(&samDesc, &point_copy_sampler); - if (FAILED(hr)) - PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); - else - SetDebugObjectName(point_copy_sampler, "point copy sampler state"); + float border[4] = { 0.f, 0.f, 0.f, 0.f }; + D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); + HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler); + if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); + else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state"); - samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, - D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); - hr = D3D::g_device->CreateSamplerState(&samDesc, &linear_copy_sampler); - if (FAILED(hr)) - PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); - else - SetDebugObjectName(linear_copy_sampler, "linear copy sampler state"); + samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); + hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler); + if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); + else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state"); // cached data used to avoid unnecessarily reloading the vertex buffers memset(&tex_quad_data, 0, sizeof(tex_quad_data)); @@ -511,17 +501,17 @@ void ShutdownUtils() font.Shutdown(); SAFE_RELEASE(point_copy_sampler); SAFE_RELEASE(linear_copy_sampler); - util_vbuf.reset(); + SAFE_DELETE(util_vbuf); } void SetPointCopySampler() { - D3D::g_context->PSSetSamplers(0, 1, &point_copy_sampler); + D3D::context->PSSetSamplers(0, 1, &point_copy_sampler); } void SetLinearCopySampler() { - D3D::g_context->PSSetSamplers(0, 1, &linear_copy_sampler); + D3D::context->PSSetSamplers(0, 1, &linear_copy_sampler); } void drawShadedTexQuad(ID3D11ShaderResourceView* texture, @@ -565,17 +555,17 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture, UINT stride = sizeof(STQVertex); UINT offset = 0; - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - D3D::g_context->IASetInputLayout(layout); - D3D::g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); - D3D::g_context->PSSetShader(PShader, NULL, 0); - D3D::g_context->PSSetShaderResources(0, 1, &texture); - D3D::g_context->VSSetShader(Vshader, NULL, 0); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + D3D::context->IASetInputLayout(layout); + D3D::context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); + D3D::context->PSSetShader(PShader, NULL, 0); + D3D::context->PSSetShaderResources(0, 1, &texture); + D3D::context->VSSetShader(Vshader, NULL, 0); D3D::stateman->Apply(); - D3D::g_context->Draw(4, stq_offset); + D3D::context->Draw(4, stq_offset); ID3D11ShaderResourceView* texres = NULL; - g_context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture + context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture } void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, @@ -622,17 +612,17 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, UINT stride = sizeof(STSQVertex); UINT offset = 0; - g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); - g_context->IASetInputLayout(layout); - g_context->PSSetShaderResources(0, 1, &texture); - g_context->PSSetShader(PShader, NULL, 0); - g_context->VSSetShader(Vshader, NULL, 0); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); + context->IASetInputLayout(layout); + context->PSSetShaderResources(0, 1, &texture); + context->PSSetShader(PShader, NULL, 0); + context->VSSetShader(Vshader, NULL, 0); stateman->Apply(); - g_context->Draw(4, stsq_offset); + context->Draw(4, stsq_offset); ID3D11ShaderResourceView* texres = NULL; - g_context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture + context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture } // Fills a certain area of the current render target with the specified color @@ -661,17 +651,17 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2) draw_quad_data.col = Color; } - g_context->VSSetShader(VertexShaderCache::GetClearVertexShader(), NULL, 0); - g_context->PSSetShader(PixelShaderCache::GetClearProgram(), NULL, 0); - g_context->IASetInputLayout(VertexShaderCache::GetClearInputLayout()); + context->VSSetShader(VertexShaderCache::GetClearVertexShader(), NULL, 0); + context->PSSetShader(PixelShaderCache::GetClearProgram(), NULL, 0); + context->IASetInputLayout(VertexShaderCache::GetClearInputLayout()); UINT stride = sizeof(ColVertex); UINT offset = 0; - g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); stateman->Apply(); - g_context->Draw(4, cq_offset); + context->Draw(4, cq_offset); } void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout) @@ -691,16 +681,16 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS clear_quad_data.col = Color; clear_quad_data.z = z; } - g_context->VSSetShader(Vshader, NULL, 0); - g_context->PSSetShader(PShader, NULL, 0); - g_context->IASetInputLayout(layout); + context->VSSetShader(Vshader, NULL, 0); + context->PSSetShader(PShader, NULL, 0); + context->IASetInputLayout(layout); UINT stride = sizeof(ClearVertex); UINT offset = 0; - g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - g_context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); stateman->Apply(); - g_context->Draw(4, clearq_offset); + context->Draw(4, clearq_offset); } } // namespace D3D diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.h index f43a921ebe..7f069164ea 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.h @@ -23,150 +23,68 @@ namespace DX11 { -// simple "smart" pointer which calls AddRef/Release as needed -template -class SharedPtr -{ -public: - typedef T* pointer; - - static SharedPtr FromPtr(pointer ptr) - { - return SharedPtr(ptr); - } - - SharedPtr() - : data(nullptr) - {} - - SharedPtr(const SharedPtr& other) - : data(NULL) - { - *this = other; - } - - SharedPtr& operator=(const SharedPtr& other) - { - if (other.data) - other.data->AddRef(); - - reset(); - data = other.data; - - return *this; - } - - ~SharedPtr() - { - reset(); - } - - void reset() - { - if (data) - data->Release(); - - data = nullptr; - } - - // returning reference for dx functions needing pointer to pointer - operator pointer const&() const - { - return data; - } - - T& operator*() const - { - return *data; - } - - // overloading operator& for dx functions needing pointer to pointer - T*const* operator&() const - { - return &data; - } - - pointer operator->() const - { - return data; - } - - bool operator==(const SharedPtr& other) const - { - return data == other.data; - } - - bool operator!=(const SharedPtr& other) const - { - return !(*this == other); - } - -private: - explicit SharedPtr(pointer ptr) - : data(ptr) - {} - - pointer data; -}; - namespace D3D { + // Font creation flags + #define D3DFONT_BOLD 0x0001 + #define D3DFONT_ITALIC 0x0002 -// Font creation flags -static const u32 D3DFONT_BOLD = 0x0001; -static const u32 D3DFONT_ITALIC = 0x0002; + // Font rendering flags + #define D3DFONT_CENTERED 0x0001 -// Font rendering flags -static const u32 D3DFONT_CENTERED = 0x0001; + class CD3DFont + { + ID3D11ShaderResourceView* m_pTexture; + ID3D11Buffer* m_pVB; + ID3D11InputLayout* m_InputLayout; + ID3D11PixelShader* m_pshader; + ID3D11VertexShader* m_vshader; + ID3D11BlendState* m_blendstate; + ID3D11RasterizerState* m_raststate; + const int m_dwTexWidth; + const int m_dwTexHeight; + unsigned int m_LineHeight; + float m_fTexCoords[128-32][4]; -class CD3DFont -{ - ID3D11ShaderResourceView* m_pTexture; - SharedPtr m_pVB; - SharedPtr m_InputLayout; - SharedPtr m_pshader; - SharedPtr m_vshader; - SharedPtr m_blendstate; - ID3D11RasterizerState* m_raststate; - const int m_dwTexWidth; - const int m_dwTexHeight; - unsigned int m_LineHeight; - float m_fTexCoords[128-32][4]; + public: + CD3DFont(); + // 2D text drawing function + // Initializing and destroying device-dependent objects + int Init(); + int Shutdown(); + int DrawTextScaled(float x, float y, + float size, + float spacing, u32 dwColor, + const char* strText); + }; -public: - CD3DFont(); - // 2D text drawing function - // Initializing and destroying device-dependent objects - int Init(); - int Shutdown(); - int DrawTextScaled(float x, float y, float size, - float spacing, u32 dwColor, const char* strText); -}; + extern CD3DFont font; -extern CD3DFont font; + void InitUtils(); + void ShutdownUtils(); -void InitUtils(); -void ShutdownUtils(); - -void SetPointCopySampler(); -void SetLinearCopySampler(); - -void drawShadedTexQuad(ID3D11ShaderResourceView* texture, - const D3D11_RECT* rSource, - int SourceWidth, int SourceHeight, - ID3D11PixelShader* PShader, ID3D11VertexShader* VShader, - ID3D11InputLayout* layout, float Gamma = 1.0f); - -void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, - const MathUtil::Rectangle* rSource, - int SourceWidth, int SourceHeight, - const MathUtil::Rectangle* rDest, - ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, - ID3D11InputLayout* layout, float Gamma = 1.0f); - -void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout); -void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); + void SetPointCopySampler(); + void SetLinearCopySampler(); + void drawShadedTexQuad(ID3D11ShaderResourceView* texture, + const D3D11_RECT* rSource, + int SourceWidth, + int SourceHeight, + ID3D11PixelShader* PShader, + ID3D11VertexShader* VShader, + ID3D11InputLayout* layout, + float Gamma = 1.0f); + void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, + const MathUtil::Rectangle* rSource, + int SourceWidth, + int SourceHeight, + const MathUtil::Rectangle* rDest, + ID3D11PixelShader* PShader, + ID3D11VertexShader* Vshader, + ID3D11InputLayout* layout, + float Gamma = 1.0f); + void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout); + void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); } } \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp index a052567102..0389085fae 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp @@ -23,155 +23,153 @@ #include "PixelShaderCache.h" #include "Render.h" #include "VertexShaderCache.h" +#include "XFBEncoder.h" #include "HW/Memmap.h" -namespace DX11 -{ +namespace DX11 { + +static XFBEncoder s_xfbEncoder; FramebufferManager::Efb FramebufferManager::m_efb; -D3DTexture2D* FramebufferManager::GetResolvedEFBColorTexture() +D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; } +ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } + +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; } + +D3DTexture2D* &FramebufferManager::GetResolvedEFBColorTexture() { if (g_ActiveConfig.iMultisampleMode) { - D3D::g_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.get(); + 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.get(); + return m_efb.color_tex; } -D3DTexture2D* FramebufferManager::GetResolvedEFBDepthTexture() +D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture() { if (g_ActiveConfig.iMultisampleMode) { - D3D::g_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.get(); + 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.get(); + return m_efb.depth_tex; } FramebufferManager::FramebufferManager() { - const unsigned int target_width = Renderer::GetTargetWidth(); - const unsigned int target_height = Renderer::GetTargetHeight(); + unsigned int target_width = Renderer::GetTargetWidth(); + unsigned int target_height = Renderer::GetTargetHeight(); DXGI_SAMPLE_DESC sample_desc = D3D::GetAAMode(g_ActiveConfig.iMultisampleMode); + ID3D11Texture2D* buf; + D3D11_TEXTURE2D_DESC texdesc; + HRESULT hr; + // EFB color texture - primary render target - { - auto 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); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(buf, "create EFB color texture (size: %dx%d)", target_width, target_height); - m_efb.color_tex.reset(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))); + 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); - D3D::SetDebugObjectName(m_efb.color_tex->GetTex(), "EFB color texture"); - D3D::SetDebugObjectName(m_efb.color_tex->GetSRV(), "EFB color texture shader resource view"); - D3D::SetDebugObjectName(m_efb.color_tex->GetRTV(), "EFB color texture render target view"); - } + SAFE_RELEASE(buf); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture"); + 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"); // Temporary EFB color texture - used in ReinterpretPixelData - { - auto 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, 1, 0); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(buf, "create EFB color temp texture (size: %dx%d)", target_width, target_height); - m_efb.color_temp_tex.reset(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)); + 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, 1, 0); + hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf); + CHECK(hr==S_OK, "create EFB color temp texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); + m_efb.color_temp_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); CHECK(m_efb.color_temp_tex!=NULL, "create EFB color temp texture (size: %dx%d)", target_width, target_height); - D3D::SetDebugObjectName(m_efb.color_temp_tex->GetTex(), "EFB color temp texture"); - D3D::SetDebugObjectName(m_efb.color_temp_tex->GetSRV(), "EFB color temp texture shader resource view"); - D3D::SetDebugObjectName(m_efb.color_temp_tex->GetRTV(), "EFB color temp texture render target view"); - } + SAFE_RELEASE(buf); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetTex(), "EFB color temp texture"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetSRV(), "EFB color temp texture shader resource view"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_temp_tex->GetRTV(), "EFB color temp texture render target view"); // AccessEFB - Sysmem buffer used to retrieve the pixel data from color_tex - { - auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ); - m_efb.color_staging_buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(m_efb.color_staging_buf, "create EFB color staging buffer"); - D3D::SetDebugObjectName(m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)"); - } + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ); + hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf); + CHECK(hr==S_OK, "create EFB color staging buffer (hr=%#x)", hr); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)"); // EFB depth buffer - primary depth buffer - { - auto 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); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(buf, "create EFB depth texture (size: %dx%d)", target_width, target_height); - m_efb.depth_tex.reset(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))); - D3D::SetDebugObjectName(m_efb.depth_tex->GetTex(), "EFB depth texture"); - D3D::SetDebugObjectName(m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view"); - D3D::SetDebugObjectName(m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view"); - } + 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, 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"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view"); // Render buffer for AccessEFB (depth data) - { - auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(buf, "create EFB depth read texture"); - m_efb.depth_read_texture.reset(new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET)); - D3D::SetDebugObjectName(m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)"); - D3D::SetDebugObjectName(m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)"); - } + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET); + hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf); + CHECK(hr==S_OK, "create EFB depth read texture (hr=%#x)", hr); + m_efb.depth_read_texture = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); + SAFE_RELEASE(buf); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)"); // AccessEFB - Sysmem buffer used to retrieve the pixel data from depth_read_texture - { - auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ); - m_efb.depth_staging_buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(m_efb.depth_staging_buf, "create EFB depth staging buffer"); - D3D::SetDebugObjectName(m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)"); - } + texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ); + 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) { // Framebuffer resolve textures (color+depth) - { - auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, target_width, target_height, - 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - m_efb.resolved_color_tex.reset(new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM)); + 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); - D3D::SetDebugObjectName(m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture"); - D3D::SetDebugObjectName(m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view"); - } + 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"); - { - auto texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_SHADER_RESOURCE); - auto const buf = CreateTexture2DShared(&texdesc, NULL); - CHECK(buf, "create EFB depth resolve texture (size: %dx%d)", target_width, target_height); - m_efb.resolved_depth_tex.reset(new D3DTexture2D(buf, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R24_UNORM_X8_TYPELESS)); - D3D::SetDebugObjectName(m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture"); - D3D::SetDebugObjectName(m_efb.resolved_depth_tex->GetSRV(), "EFB depth 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"); } else { m_efb.resolved_color_tex = NULL; m_efb.resolved_depth_tex = NULL; } + + s_xfbEncoder.Init(); } FramebufferManager::~FramebufferManager() { - m_efb.color_tex.reset(); - m_efb.color_staging_buf.reset(); + s_xfbEncoder.Shutdown(); - m_efb.depth_tex.reset(); - m_efb.depth_staging_buf.reset(); - m_efb.depth_read_texture.reset(); - - m_efb.color_temp_tex.reset(); - - m_efb.resolved_color_tex.reset(); - m_efb.resolved_depth_tex.reset(); + SAFE_RELEASE(m_efb.color_tex); + SAFE_RELEASE(m_efb.color_temp_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,float Gamma) { u8* dst = Memory::GetPointer(xfbAddr); - m_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma); + s_xfbEncoder.Encode(dst, fbWidth, fbHeight, sourceRc, Gamma); } XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) @@ -216,8 +214,8 @@ void XFBSource::CopyEFB(float Gamma) // Copy EFB data to XFB and restore render target again const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); - D3D::g_context->RSSetViewports(1, &vp); - D3D::g_context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); + D3D::context->RSSetViewports(1, &vp); + D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::SetLinearCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), @@ -225,7 +223,7 @@ void XFBSource::CopyEFB(float Gamma) PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(),Gamma); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h index 35bca0538b..83db4370db 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.h @@ -23,7 +23,6 @@ #include "FramebufferManagerBase.h" #include "D3DTexture.h" -#include "XFBEncoder.h" namespace DX11 { @@ -61,16 +60,15 @@ namespace DX11 { struct XFBSource : public XFBSourceBase { - XFBSource(std::unique_ptr&& _tex) - : tex(std::move(_tex)) - {} + XFBSource(D3DTexture2D *_tex) : tex(_tex) {} + ~XFBSource() { tex->Release(); } void Draw(const MathUtil::Rectangle &sourcerc, const MathUtil::Rectangle &drawrc, int width, int height) const; void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void CopyEFB(float Gamma); - std::unique_ptr const tex; + D3DTexture2D* const tex; }; class FramebufferManager : public FramebufferManagerBase @@ -79,21 +77,22 @@ public: FramebufferManager(); ~FramebufferManager(); - static D3DTexture2D* GetEFBColorTexture() { return m_efb.color_tex.get(); } - static ID3D11Texture2D* GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } + static D3DTexture2D* &GetEFBColorTexture(); + static ID3D11Texture2D* &GetEFBColorStagingBuffer(); - static D3DTexture2D* GetEFBDepthTexture() { return m_efb.depth_tex.get(); } - static D3DTexture2D* GetEFBDepthReadTexture() { return m_efb.depth_read_texture.get(); } - static ID3D11Texture2D* GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; } + static D3DTexture2D* &GetEFBDepthTexture(); + static D3DTexture2D* &GetEFBDepthReadTexture(); + static ID3D11Texture2D* &GetEFBDepthStagingBuffer(); - static D3DTexture2D* GetResolvedEFBColorTexture(); - static D3DTexture2D* GetResolvedEFBDepthTexture(); + static D3DTexture2D* &GetResolvedEFBColorTexture(); + static D3DTexture2D* &GetResolvedEFBDepthTexture(); - static D3DTexture2D* GetEFBColorTempTexture() { return m_efb.color_temp_tex.get(); } - + static D3DTexture2D* &GetEFBColorTempTexture() { return m_efb.color_temp_tex; } static void SwapReinterpretTexture() { - std::swap(m_efb.color_temp_tex, m_efb.color_tex); + D3DTexture2D* swaptex = GetEFBColorTempTexture(); + m_efb.color_temp_tex = GetEFBColorTexture(); + m_efb.color_tex = swaptex; } private: @@ -104,20 +103,18 @@ private: static struct Efb { - std::unique_ptr color_tex; - SharedPtr color_staging_buf; + D3DTexture2D* color_tex; + ID3D11Texture2D* color_staging_buf; - std::unique_ptr depth_tex; - SharedPtr depth_staging_buf; - std::unique_ptr depth_read_texture; + D3DTexture2D* depth_tex; + ID3D11Texture2D* depth_staging_buf; + D3DTexture2D* depth_read_texture; - std::unique_ptr color_temp_tex; + D3DTexture2D* color_temp_tex; - std::unique_ptr resolved_color_tex; - std::unique_ptr resolved_depth_tex; + D3DTexture2D* resolved_color_tex; + D3DTexture2D* resolved_depth_tex; } m_efb; - - XFBEncoder m_xfbEncoder; }; } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp index f8bba79d65..c5175d1275 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp @@ -26,19 +26,66 @@ namespace DX11 namespace D3D { -std::unique_ptr stateman; +StateManager* stateman; + + +template AutoState::AutoState(const T* object) : state(object) +{ + ((IUnknown*)state)->AddRef(); +} + +template AutoState::AutoState(const AutoState &source) +{ + state = source.GetPtr(); + ((T*)state)->AddRef(); +} + +template AutoState::~AutoState() +{ + if(state) ((T*)state)->Release(); + state = NULL; +} + +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::PopBlendState() { blendstates.pop(); } +void StateManager::PopDepthState() { depthstates.pop(); } +void StateManager::PopRasterizerState() { raststates.pop(); } void StateManager::Apply() { - if (blendstates.empty() || depthstates.empty() || raststates.empty()) + if (!blendstates.empty()) { - ERROR_LOG(VIDEO, "Tried to apply without complete state!"); - return; + if (cur_blendstate != blendstates.top().GetPtr()) + { + cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr(); + D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF); + } } + else ERROR_LOG(VIDEO, "Tried to apply without blend state!"); - D3D::g_context->OMSetBlendState(blendstates.top(), NULL, 0xFFFFFFFF); - D3D::g_context->OMSetDepthStencilState(depthstates.top(), 0); - D3D::g_context->RSSetState(raststates.top()); + if (!depthstates.empty()) + { + if (cur_depthstate != depthstates.top().GetPtr()) + { + cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr(); + D3D::context->OMSetDepthStencilState(cur_depthstate, 0); + } + } + else ERROR_LOG(VIDEO, "Tried to apply without depth state!"); + + if (!raststates.empty()) + { + if (cur_raststate != raststates.top().GetPtr()) + { + cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr(); + D3D::context->RSSetState(cur_raststate); + } + } + else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!"); } } // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h index d7b1c2e6b2..4af093df9e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h @@ -19,7 +19,9 @@ #include -#include "D3DUtil.h" +struct ID3D11BlendState; +struct ID3D11DepthStencilState; +struct ID3D11RasterizerState; namespace DX11 { @@ -27,35 +29,37 @@ namespace DX11 namespace D3D { -typedef SharedPtr AutoBlendState; -typedef SharedPtr AutoDepthStencilState; -typedef SharedPtr AutoRasterizerState; +template class AutoState +{ +public: + AutoState(const T* object); + AutoState(const AutoState &source); + ~AutoState(); + + const inline T* GetPtr() const { return state; } + +private: + const T* state; +}; + +typedef AutoState AutoBlendState; +typedef AutoState AutoDepthStencilState; +typedef AutoState AutoRasterizerState; class StateManager { public: + StateManager(); + // call any of these to change the affected states - void PushBlendState(const AutoBlendState& state) - { - blendstates.push(state); - } - - void PushDepthState(ID3D11DepthStencilState* state) - { - state->AddRef(); - depthstates.push(AutoDepthStencilState::FromPtr(state)); - } - - void PushRasterizerState(ID3D11RasterizerState* state) - { - state->AddRef(); - raststates.push(AutoRasterizerState::FromPtr(state)); - } + void PushBlendState(const ID3D11BlendState* state); + void PushDepthState(const ID3D11DepthStencilState* state); + void PushRasterizerState(const ID3D11RasterizerState* state); // call these after drawing - void PopBlendState() { blendstates.pop(); } - void PopDepthState() { depthstates.pop(); } - void PopRasterizerState() { raststates.pop(); } + void PopBlendState(); + void PopDepthState(); + void PopRasterizerState(); // call this before any drawing operation if states could have changed meanwhile void Apply(); @@ -64,9 +68,12 @@ private: std::stack blendstates; std::stack depthstates; std::stack raststates; + ID3D11BlendState* cur_blendstate; + ID3D11DepthStencilState* cur_depthstate; + ID3D11RasterizerState* cur_raststate; }; -extern std::unique_ptr stateman; +extern StateManager* stateman; } // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index eff9a9847e..25f3712eb1 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -138,19 +138,39 @@ static const char LINE_GS_COMMON[] = ; LineGeometryShader::LineGeometryShader() - : m_ready(false) + : m_ready(false), m_paramsBuffer(NULL) +{ } + +void LineGeometryShader::Init() { + m_ready = false; + + HRESULT hr; + // Create constant buffer for uploading data to geometry shader - + D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(LineGSParams_Padded), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_paramsBuffer = CreateBufferShared(&bd, NULL); - CHECK(m_paramsBuffer, "create line geometry shader params buffer"); + hr = D3D::device->CreateBuffer(&bd, NULL, &m_paramsBuffer); + CHECK(SUCCEEDED(hr), "create line geometry shader params buffer"); D3D::SetDebugObjectName(m_paramsBuffer, "line geometry shader params buffer"); m_ready = true; } +void LineGeometryShader::Shutdown() +{ + m_ready = false; + + for (ComboMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) + { + SAFE_RELEASE(it->second); + } + m_shaders.clear(); + + SAFE_RELEASE(m_paramsBuffer); +} + bool LineGeometryShader::SetShader(u32 components, float lineWidth, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable) { @@ -177,13 +197,12 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, { "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() }, { NULL, NULL } }; - - auto const newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); + ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); if (!newShader) { WARN_LOG(VIDEO, "Line geometry shader for components 0x%.08X failed to compile", components); // Add dummy shader to prevent trying to compile again - m_shaders[components].reset(); + m_shaders[components] = NULL; return false; } @@ -195,18 +214,19 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, if (shaderIt->second) { D3D11_MAPPED_SUBRESOURCE map; - HRESULT hr = D3D::g_context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { LineGSParams* params = (LineGSParams*)map.pData; params->LineWidth = lineWidth; + params->TexOffset = texOffset; params->VpWidth = vpWidth; params->VpHeight = vpHeight; for (int i = 0; i < 8; ++i) params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f; - D3D::g_context->Unmap(m_paramsBuffer, 0); + D3D::context->Unmap(m_paramsBuffer, 0); } else ERROR_LOG(VIDEO, "Failed to map line gs params buffer"); @@ -214,8 +234,8 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f", lineWidth, texOffset, vpWidth, vpHeight); - D3D::g_context->GSSetShader(shaderIt->second, NULL, 0); - D3D::g_context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); + D3D::context->GSSetShader(shaderIt->second, NULL, 0); + D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); return true; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h index 0b266109c2..cec5a781c4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h @@ -19,7 +19,9 @@ #define _LINEGEOMETRYSHADER_H #include "VideoCommon.h" -#include "D3DUtil.h" + +struct ID3D11Buffer; +struct ID3D11GeometryShader; namespace DX11 { @@ -28,21 +30,27 @@ namespace DX11 // vertex format. class LineGeometryShader { + public: + LineGeometryShader(); + void Init(); + void Shutdown(); // Returns true on success, false on failure bool SetShader(u32 components, float lineWidth, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable); private: + bool m_ready; - SharedPtr m_paramsBuffer; + ID3D11Buffer* m_paramsBuffer; - typedef std::map> ComboMap; + typedef std::map ComboMap; ComboMap m_shaders; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp index 71e58baee4..bfa70948da 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp @@ -17,6 +17,7 @@ // http://code.google.com/p/dolphin-emu/ #include "D3DBase.h" +#include "D3DBlob.h" #include "NativeVertexFormat.h" #include "VertexManager.h" #include "VertexShaderCache.h" @@ -29,11 +30,12 @@ class D3DVertexFormat : public NativeVertexFormat D3D11_INPUT_ELEMENT_DESC m_elems[32]; UINT m_num_elems; - SharedPtr m_vs_bytecode; - SharedPtr m_layout; + DX11::D3DBlob* m_vs_bytecode; + ID3D11InputLayout* m_layout; public: - D3DVertexFormat() : m_num_elems(0) {} + D3DVertexFormat() : m_num_elems(0), m_vs_bytecode(NULL), m_layout(NULL) {} + ~D3DVertexFormat() { SAFE_RELEASE(m_vs_bytecode); SAFE_RELEASE(m_layout); } void Initialize(const PortableVertexDeclaration &_vtx_decl); void SetupVertexPointers(); @@ -139,15 +141,17 @@ void D3DVertexFormat::SetupVertexPointers() { if (m_vs_bytecode != DX11::VertexShaderCache::GetActiveShaderBytecode()) { - m_vs_bytecode = DX11::VertexShaderCache::GetActiveShaderBytecode(); + SAFE_RELEASE(m_vs_bytecode); + SAFE_RELEASE(m_layout); - m_layout = CreateInputLayoutShared(m_elems, m_num_elems, - m_vs_bytecode->GetBufferPointer(), m_vs_bytecode->GetBufferSize()); - if (!m_layout) - PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); - DX11::D3D::SetDebugObjectName(m_layout, "input layout used to emulate the GX pipeline"); + m_vs_bytecode = DX11::VertexShaderCache::GetActiveShaderBytecode(); + m_vs_bytecode->AddRef(); + + HRESULT hr = DX11::D3D::device->CreateInputLayout(m_elems, m_num_elems, m_vs_bytecode->Data(), m_vs_bytecode->Size(), &m_layout); + if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); + DX11::D3D::SetDebugObjectName((ID3D11DeviceChild*)m_layout, "input layout used to emulate the GX pipeline"); } - DX11::D3D::g_context->IASetInputLayout(m_layout); + DX11::D3D::context->IASetInputLayout(m_layout); } } // namespace DX11 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.cpp index 1e27c16a34..aa96aac51d 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.cpp @@ -846,6 +846,24 @@ static const char EFB_ENCODE_PS[] = "}\n" ; +PSTextureEncoder::PSTextureEncoder() + : m_ready(false), m_out(NULL), m_outRTV(NULL), m_outStage(NULL), + m_encodeParams(NULL), + m_quad(NULL), m_vShader(NULL), m_quadLayout(NULL), + m_efbEncodeBlendState(NULL), m_efbEncodeDepthState(NULL), + m_efbEncodeRastState(NULL), m_efbSampler(NULL), + m_dynamicShader(NULL), m_classLinkage(NULL) +{ + for (size_t i = 0; i < 4; ++i) + m_fetchClass[i] = NULL; + for (size_t i = 0; i < 2; ++i) + m_scaledFetchClass[i] = NULL; + for (size_t i = 0; i < 2; ++i) + m_intensityClass[i] = NULL; + for (size_t i = 0; i < 16; ++i) + m_generatorClass[i] = NULL; +} + static const D3D11_INPUT_ELEMENT_DESC QUAD_LAYOUT_DESC[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; @@ -856,22 +874,11 @@ static const struct QuadVertex float posY; } QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }; -PSTextureEncoder::PSTextureEncoder() - : m_ready(false), m_outRTV(NULL), - m_efbEncodeDepthState(NULL), - m_efbEncodeRastState(NULL), m_efbSampler(NULL), - m_classLinkage(NULL) +void PSTextureEncoder::Init() { m_ready = false; - for (size_t i = 0; i < 4; ++i) - m_fetchClass[i] = NULL; - for (size_t i = 0; i < 2; ++i) - m_scaledFetchClass[i] = NULL; - for (size_t i = 0; i < 2; ++i) - m_intensityClass[i] = NULL; - for (size_t i = 0; i < 16; ++i) - m_generatorClass[i] = NULL; + HRESULT hr; // Create output texture RGBA format @@ -879,15 +886,15 @@ PSTextureEncoder::PSTextureEncoder() D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_R32G32B32A32_UINT, EFB_WIDTH, EFB_HEIGHT/4, 1, 1, D3D11_BIND_RENDER_TARGET); - m_out = CreateTexture2DShared(&t2dd, NULL); - CHECK(m_out, "create efb encode output texture"); + hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_out); + CHECK(SUCCEEDED(hr), "create efb encode output texture"); D3D::SetDebugObjectName(m_out, "efb encoder output texture"); // Create output render target view D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out, D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R32G32B32A32_UINT); - HRESULT hr = D3D::g_device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV); + hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV); CHECK(SUCCEEDED(hr), "create efb encode output render target view"); D3D::SetDebugObjectName(m_outRTV, "efb encoder output rtv"); @@ -896,16 +903,16 @@ PSTextureEncoder::PSTextureEncoder() t2dd.Usage = D3D11_USAGE_STAGING; t2dd.BindFlags = 0; t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - m_outStage = CreateTexture2DShared(&t2dd, NULL); - CHECK(m_outStage, "create efb encode output staging buffer"); + hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_outStage); + CHECK(SUCCEEDED(hr), "create efb encode output staging buffer"); D3D::SetDebugObjectName(m_outStage, "efb encoder output staging buffer"); // Create constant buffer for uploading data to shaders D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams), D3D11_BIND_CONSTANT_BUFFER); - m_encodeParams = CreateBufferShared(&bd, NULL); - CHECK(m_encodeParams, "create efb encode params buffer"); + hr = D3D::device->CreateBuffer(&bd, NULL, &m_encodeParams); + CHECK(SUCCEEDED(hr), "create efb encode params buffer"); D3D::SetDebugObjectName(m_encodeParams, "efb encoder params buffer"); // Create vertex quad @@ -914,23 +921,33 @@ PSTextureEncoder::PSTextureEncoder() D3D11_USAGE_IMMUTABLE); D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 }; - m_quad = CreateBufferShared(&bd, &srd); - CHECK(m_quad, "create efb encode quad vertex buffer"); + hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad); + CHECK(SUCCEEDED(hr), "create efb encode quad vertex buffer"); D3D::SetDebugObjectName(m_quad, "efb encoder quad vertex buffer"); // Create vertex shader - SharedPtr bytecode; - m_vShader = D3D::CompileAndCreateVertexShader(EFB_ENCODE_VS, sizeof(EFB_ENCODE_VS), std::addressof(bytecode)); - CHECK(m_vShader, "compile/create efb encode vertex shader"); + + D3DBlob* bytecode = NULL; + if (!D3D::CompileVertexShader(EFB_ENCODE_VS, sizeof(EFB_ENCODE_VS), &bytecode)) + { + ERROR_LOG(VIDEO, "EFB encode vertex shader failed to compile"); + return; + } + + hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), NULL, &m_vShader); + CHECK(SUCCEEDED(hr), "create efb encode vertex shader"); D3D::SetDebugObjectName(m_vShader, "efb encoder vertex shader"); // Create input layout for vertex quad using bytecode from vertex shader - m_quadLayout = CreateInputLayoutShared(QUAD_LAYOUT_DESC, - sizeof(QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC), - bytecode->GetBufferPointer(), bytecode->GetBufferSize()); - CHECK(m_quadLayout, "create efb encode quad vertex layout"); + + hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC, + sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC), + bytecode->Data(), bytecode->Size(), &m_quadLayout); + CHECK(SUCCEEDED(hr), "create efb encode quad vertex layout"); D3D::SetDebugObjectName(m_quadLayout, "efb encoder quad layout"); + bytecode->Release(); + // Create pixel shader #ifdef USE_DYNAMIC_MODE @@ -941,46 +958,44 @@ PSTextureEncoder::PSTextureEncoder() return; // Create blend state - { - auto const bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - m_efbEncodeBlendState = CreateBlendStateShared(&bld); + + D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); + hr = D3D::device->CreateBlendState(&bld, &m_efbEncodeBlendState); CHECK(SUCCEEDED(hr), "create efb encode blend state"); D3D::SetDebugObjectName(m_efbEncodeBlendState, "efb encoder blend state"); - } // Create depth state - { - auto dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT()); + + D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT()); dsd.DepthEnable = FALSE; - hr = D3D::g_device->CreateDepthStencilState(&dsd, &m_efbEncodeDepthState); + hr = D3D::device->CreateDepthStencilState(&dsd, &m_efbEncodeDepthState); CHECK(SUCCEEDED(hr), "create efb encode depth state"); D3D::SetDebugObjectName(m_efbEncodeDepthState, "efb encoder depth state"); - } // Create rasterizer state - { - auto rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); + + D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); rd.CullMode = D3D11_CULL_NONE; rd.DepthClipEnable = FALSE; - hr = D3D::g_device->CreateRasterizerState(&rd, &m_efbEncodeRastState); + hr = D3D::device->CreateRasterizerState(&rd, &m_efbEncodeRastState); CHECK(SUCCEEDED(hr), "create efb encode rast state"); D3D::SetDebugObjectName(m_efbEncodeRastState, "efb encoder rast state"); - } // Create efb texture sampler - { - auto sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); + + D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - hr = D3D::g_device->CreateSamplerState(&sd, &m_efbSampler); + hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler); CHECK(SUCCEEDED(hr), "create efb encode texture sampler"); D3D::SetDebugObjectName(m_efbSampler, "efb encoder texture sampler"); - } m_ready = true; } -PSTextureEncoder::~PSTextureEncoder() +void PSTextureEncoder::Shutdown() { + m_ready = false; + for (size_t i = 0; i < 4; ++i) SAFE_RELEASE(m_fetchClass[i]); for (size_t i = 0; i < 2; ++i) @@ -989,13 +1004,29 @@ PSTextureEncoder::~PSTextureEncoder() SAFE_RELEASE(m_intensityClass[i]); for (size_t i = 0; i < 16; ++i) SAFE_RELEASE(m_generatorClass[i]); + m_linkageArray.clear(); SAFE_RELEASE(m_classLinkage); + SAFE_RELEASE(m_dynamicShader); + + for (ComboMap::iterator it = m_staticShaders.begin(); + it != m_staticShaders.end(); ++it) + { + SAFE_RELEASE(it->second); + } + m_staticShaders.clear(); SAFE_RELEASE(m_efbSampler); SAFE_RELEASE(m_efbEncodeRastState); SAFE_RELEASE(m_efbEncodeDepthState); + SAFE_RELEASE(m_efbEncodeBlendState); + SAFE_RELEASE(m_quadLayout); + SAFE_RELEASE(m_vShader); + SAFE_RELEASE(m_quad); + SAFE_RELEASE(m_encodeParams); + SAFE_RELEASE(m_outStage); SAFE_RELEASE(m_outRTV); + SAFE_RELEASE(m_out); } size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, @@ -1052,7 +1083,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, if (SetStaticShader(dstFormat, srcFormat, isIntensity, scaleByHalf)) #endif { - D3D::g_context->VSSetShader(m_vShader, NULL, 0); + D3D::context->VSSetShader(m_vShader, NULL, 0); D3D::stateman->PushBlendState(m_efbEncodeBlendState); D3D::stateman->PushDepthState(m_efbEncodeDepthState); @@ -1060,13 +1091,13 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, D3D::stateman->Apply(); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(cacheLinesPerRow*2), FLOAT(numBlocksY)); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); - D3D::g_context->IASetInputLayout(m_quadLayout); - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + D3D::context->IASetInputLayout(m_quadLayout); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); UINT stride = sizeof(QuadVertex); UINT offset = 0; - D3D::g_context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset); + D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset); EFBRectangle fullSrcRect; fullSrcRect.left = 0; @@ -1084,55 +1115,55 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, params.TexTop = float(targetRect.top) / g_renderer->GetTargetHeight(); params.TexRight = float(targetRect.right) / g_renderer->GetTargetWidth(); params.TexBottom = float(targetRect.bottom) / g_renderer->GetTargetHeight(); - D3D::g_context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0); + D3D::context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0); - D3D::g_context->VSSetConstantBuffers(0, 1, &m_encodeParams); + D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams); - D3D::g_context->OMSetRenderTargets(1, &m_outRTV, NULL); + D3D::context->OMSetRenderTargets(1, &m_outRTV, NULL); ID3D11ShaderResourceView* pEFB = (srcFormat == PIXELFMT_Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : - // FIXME: Instead of resolving EFB, it would be better to pick out a - // single sample from each pixel. The game may break if it isn't - // expecting the blurred edges around multisampled shapes. - FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); + // FIXME: Instead of resolving EFB, it would be better to pick out a + // single sample from each pixel. The game may break if it isn't + // expecting the blurred edges around multisampled shapes. + FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); - D3D::g_context->PSSetConstantBuffers(0, 1, &m_encodeParams); - D3D::g_context->PSSetShaderResources(0, 1, &pEFB); - D3D::g_context->PSSetSamplers(0, 1, &m_efbSampler); + D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams); + D3D::context->PSSetShaderResources(0, 1, &pEFB); + D3D::context->PSSetSamplers(0, 1, &m_efbSampler); // Encode! - D3D::g_context->Draw(4, 0); + D3D::context->Draw(4, 0); // Copy to staging buffer D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, cacheLinesPerRow*2, numBlocksY, 1); - D3D::g_context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); + D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); // Clean up state IUnknown* nullDummy = NULL; - D3D::g_context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy); - D3D::g_context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy); - D3D::g_context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); + D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy); + D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy); + D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); - D3D::g_context->OMSetRenderTargets(0, NULL, NULL); + D3D::context->OMSetRenderTargets(0, NULL, NULL); - D3D::g_context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); + D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); D3D::stateman->PopRasterizerState(); D3D::stateman->PopDepthState(); D3D::stateman->PopBlendState(); - D3D::g_context->PSSetShader(NULL, NULL, 0); - D3D::g_context->VSSetShader(NULL, NULL, 0); + D3D::context->PSSetShader(NULL, NULL, 0); + D3D::context->VSSetShader(NULL, NULL, 0); // Transfer staging buffer to GameCube/Wii RAM D3D11_MAPPED_SUBRESOURCE map = { 0 }; - hr = D3D::g_context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); + hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); CHECK(SUCCEEDED(hr), "map staging buffer"); u8* src = (u8*)map.pData; @@ -1143,7 +1174,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, src += map.RowPitch; } - D3D::g_context->Unmap(m_outStage, 0); + D3D::context->Unmap(m_outStage, 0); encodeSize = bpmem.copyMipMapStrideChannels*32 * numBlocksY; } @@ -1151,7 +1182,8 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, // Restore API g_renderer->RestoreAPIState(); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + D3D::context->OMSetRenderTargets(1, + &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); return encodeSize; @@ -1206,15 +1238,15 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF case 0xC: generatorFuncName = "Generate_C"; break; default: WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum); - m_staticShaders[key].reset(); + m_staticShaders[key] = NULL; return false; - break; } INFO_LOG(VIDEO, "Compiling efb encoding shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d", dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); // Shader permutation not found, so compile it + D3DBlob* bytecode = NULL; D3D_SHADER_MACRO macros[] = { { "IMP_FETCH", FETCH_FUNC_NAMES[fetchNum] }, { "IMP_SCALEDFETCH", SCALEDFETCH_FUNC_NAMES[scaledFetchNum] }, @@ -1222,30 +1254,29 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF { "IMP_GENERATOR", generatorFuncName }, { NULL, NULL } }; - - auto const bytecode = D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), macros); - if (!bytecode) + if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros)) { WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d failed to compile", dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); // Add dummy shader to map to prevent trying to compile over and // over again - m_staticShaders[key].reset(); + m_staticShaders[key] = NULL; return false; } - ID3D11PixelShader* newShader = nullptr; - HRESULT hr = D3D::g_device->CreatePixelShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), NULL, &newShader); + ID3D11PixelShader* newShader; + HRESULT hr = D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), NULL, &newShader); CHECK(SUCCEEDED(hr), "create efb encoder pixel shader"); - it = m_staticShaders.insert(std::make_pair(key, SharedPtr::FromPtr(newShader))).first; + it = m_staticShaders.insert(std::make_pair(key, newShader)).first; + bytecode->Release(); } if (it != m_staticShaders.end()) { if (it->second) { - D3D::g_context->PSSetShader(it->second, NULL, 0); + D3D::context->PSSetShader(it->second, NULL, 0); return true; } else @@ -1257,24 +1288,32 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF bool PSTextureEncoder::InitDynamicMode() { - const D3D_SHADER_MACRO macros[] = { + HRESULT hr; + + D3D_SHADER_MACRO macros[] = { { "DYNAMIC_MODE", NULL }, { NULL, NULL } }; - HRESULT hr = D3D::g_device->CreateClassLinkage(&m_classLinkage); + D3DBlob* bytecode = NULL; + if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros)) + { + ERROR_LOG(VIDEO, "EFB encode pixel shader failed to compile"); + return false; + } + + hr = D3D::device->CreateClassLinkage(&m_classLinkage); CHECK(SUCCEEDED(hr), "create efb encode class linkage"); D3D::SetDebugObjectName(m_classLinkage, "efb encoder class linkage"); - SharedPtr bytecode; - m_dynamicShader = D3D::CompileAndCreatePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), macros, std::addressof(bytecode)); - CHECK(m_dynamicShader, "compile/create efb encode pixel shader"); + hr = D3D::device->CreatePixelShader(bytecode->Data(), bytecode->Size(), m_classLinkage, &m_dynamicShader); + CHECK(SUCCEEDED(hr), "create efb encode pixel shader"); D3D::SetDebugObjectName(m_dynamicShader, "efb encoder pixel shader"); // Use D3DReflect ID3D11ShaderReflection* reflect = NULL; - hr = PD3DReflect(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&reflect); + hr = PD3DReflect(bytecode->Data(), bytecode->Size(), IID_ID3D11ShaderReflection, (void**)&reflect); CHECK(SUCCEEDED(hr), "reflect on efb encoder shader"); // Get number of slots and create dynamic linkage array @@ -1311,6 +1350,7 @@ bool PSTextureEncoder::InitDynamicMode() m_generatorClass[i] = NULL; reflect->Release(); + bytecode->Release(); return true; } @@ -1348,7 +1388,6 @@ bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat, default: WARN_LOG(VIDEO, "No generator available for dst format 0x%X; aborting", generatorNum); return false; - break; } // Make sure class instances are available @@ -1397,7 +1436,7 @@ bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat, if (m_generatorSlot != UINT(-1)) m_linkageArray[m_generatorSlot] = m_generatorClass[generatorNum]; - D3D::g_context->PSSetShader(m_dynamicShader, + D3D::context->PSSetShader(m_dynamicShader, m_linkageArray.empty() ? NULL : &m_linkageArray[0], (UINT)m_linkageArray.size()); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.h b/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.h index 67dbced893..490cd69ef5 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PSTextureEncoder.h @@ -19,32 +19,48 @@ #define _PSTEXTUREENCODER_H #include "TextureEncoder.h" -#include "D3DUtil.h" + +struct ID3D11Texture2D; +struct ID3D11RenderTargetView; +struct ID3D11Buffer; +struct ID3D11InputLayout; +struct ID3D11VertexShader; +struct ID3D11PixelShader; +struct ID3D11ClassLinkage; +struct ID3D11ClassInstance; +struct ID3D11BlendState; +struct ID3D11DepthStencilState; +struct ID3D11RasterizerState; +struct ID3D11SamplerState; namespace DX11 { class PSTextureEncoder : public TextureEncoder { -public: - PSTextureEncoder(); - ~PSTextureEncoder(); +public: + + PSTextureEncoder(); + + void Init(); + void Shutdown(); size_t Encode(u8* dst, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); private: + bool m_ready; - SharedPtr m_out; + ID3D11Texture2D* m_out; ID3D11RenderTargetView* m_outRTV; - SharedPtr m_outStage; - SharedPtr m_encodeParams; - SharedPtr m_quad; - SharedPtr m_vShader; - SharedPtr m_quadLayout; - SharedPtr m_efbEncodeBlendState; + ID3D11Texture2D* m_outStage; + ID3D11Buffer* m_encodeParams; + ID3D11Buffer* m_quad; + ID3D11VertexShader* m_vShader; + ID3D11InputLayout* m_quadLayout; + ID3D11BlendState* m_efbEncodeBlendState; ID3D11DepthStencilState* m_efbEncodeDepthState; ID3D11RasterizerState* m_efbEncodeRastState; ID3D11SamplerState* m_efbSampler; @@ -64,7 +80,7 @@ private: | (scaleByHalf ? (1<<0) : 0); } - typedef std::map> ComboMap; + typedef std::map ComboMap; ComboMap m_staticShaders; @@ -75,7 +91,7 @@ private: bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat, bool isIntensity, bool scaleByHalf); - SharedPtr m_dynamicShader; + ID3D11PixelShader* m_dynamicShader; ID3D11ClassLinkage* m_classLinkage; // Interface slots @@ -95,6 +111,7 @@ private: ID3D11ClassInstance* m_generatorClass[16]; std::vector m_linkageArray; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index d1b20cd3a4..5418923bf8 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -44,14 +44,13 @@ const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry; LinearDiskCache g_ps_disk_cache; -SharedPtr s_ColorMatrixProgram[2]; -SharedPtr s_ColorCopyProgram[2]; -SharedPtr s_DepthMatrixProgram[2]; -SharedPtr s_ClearProgram; -SharedPtr s_rgba6_to_rgb8[2]; -SharedPtr s_rgb8_to_rgba6[2]; - -SharedPtr pscbuf; +ID3D11PixelShader* s_ColorMatrixProgram[2] = {NULL}; +ID3D11PixelShader* s_ColorCopyProgram[2] = {NULL}; +ID3D11PixelShader* s_DepthMatrixProgram[2] = {NULL}; +ID3D11PixelShader* s_ClearProgram = NULL; +ID3D11PixelShader* s_rgba6_to_rgb8[2] = {NULL}; +ID3D11PixelShader* s_rgb8_to_rgba6[2] = {NULL}; +ID3D11Buffer* pscbuf = NULL; const char clear_program_code[] = { "void main(\n" @@ -243,7 +242,6 @@ const char reint_rgb8_to_rgba6_msaa[] = { "}\n" }; - ID3D11PixelShader* PixelShaderCache::ReinterpRGBA6ToRGB8(bool multisampled) { if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) @@ -298,65 +296,50 @@ ID3D11PixelShader* PixelShaderCache::ReinterpRGB8ToRGBA6(bool multisampled) ID3D11PixelShader* PixelShaderCache::GetColorCopyProgram(bool multisampled) { - if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) - { - return s_ColorCopyProgram[0]; - } - else if (!s_ColorCopyProgram[1]) + if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_ColorCopyProgram[0]; + else if (s_ColorCopyProgram[1]) return s_ColorCopyProgram[1]; + else { // create MSAA shader for current AA mode char buf[1024]; - const int l = sprintf_s(buf, 1024, color_copy_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); - + int l = sprintf_s(buf, 1024, color_copy_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); s_ColorCopyProgram[1] = D3D::CompileAndCreatePixelShader(buf, l); - - CHECK(s_ColorCopyProgram[1], "Create color copy MSAA pixel shader"); - D3D::SetDebugObjectName(s_ColorCopyProgram[1], "color copy MSAA pixel shader"); + CHECK(s_ColorCopyProgram[1]!=NULL, "Create color copy MSAA pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[1], "color copy MSAA pixel shader"); + return s_ColorCopyProgram[1]; } - - return s_ColorCopyProgram[1]; } ID3D11PixelShader* PixelShaderCache::GetColorMatrixProgram(bool multisampled) { - if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) - { - return s_ColorMatrixProgram[0]; - } - else if (!s_ColorMatrixProgram[1]) + if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_ColorMatrixProgram[0]; + else if (s_ColorMatrixProgram[1]) return s_ColorMatrixProgram[1]; + else { // create MSAA shader for current AA mode char buf[1024]; - const int l = sprintf_s(buf, 1024, color_matrix_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); - + int l = sprintf_s(buf, 1024, color_matrix_program_code_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); s_ColorMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l); - - CHECK(s_ColorMatrixProgram[1], "Create color matrix MSAA pixel shader"); - D3D::SetDebugObjectName(s_ColorMatrixProgram[1], "color matrix MSAA pixel shader"); + CHECK(s_ColorMatrixProgram[1]!=NULL, "Create color matrix MSAA pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[1], "color matrix MSAA pixel shader"); + return s_ColorMatrixProgram[1]; } - - return s_ColorMatrixProgram[1]; } ID3D11PixelShader* PixelShaderCache::GetDepthMatrixProgram(bool multisampled) { - if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) - { - return s_DepthMatrixProgram[0]; - } - else if (!s_DepthMatrixProgram[1]) + if (!multisampled || D3D::GetAAMode(g_ActiveConfig.iMultisampleMode).Count == 1) return s_DepthMatrixProgram[0]; + else if (s_DepthMatrixProgram[1]) return s_DepthMatrixProgram[1]; + else { // create MSAA shader for current AA mode char buf[1024]; - const int l = sprintf_s(buf, 1024, depth_matrix_program_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); - + int l = sprintf_s(buf, 1024, depth_matrix_program_msaa, D3D::GetAAMode(g_ActiveConfig.iMultisampleMode)); s_DepthMatrixProgram[1] = D3D::CompileAndCreatePixelShader(buf, l); - - CHECK(s_DepthMatrixProgram[1], "Create depth matrix MSAA pixel shader"); - D3D::SetDebugObjectName(s_DepthMatrixProgram[1], "depth matrix MSAA pixel shader"); + CHECK(s_DepthMatrixProgram[1]!=NULL, "Create depth matrix MSAA pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[1], "depth matrix MSAA pixel shader"); + return s_DepthMatrixProgram[1]; } - - return s_DepthMatrixProgram[1]; } ID3D11PixelShader* PixelShaderCache::GetClearProgram() @@ -364,31 +347,27 @@ ID3D11PixelShader* PixelShaderCache::GetClearProgram() return s_ClearProgram; } -ID3D11Buffer*const& PixelShaderCache::GetConstantBuffer() +ID3D11Buffer* &PixelShaderCache::GetConstantBuffer() { // TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up if (pscbufchanged) { D3D11_MAPPED_SUBRESOURCE map; - D3D::g_context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D::context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); memcpy(map.pData, psconstants, sizeof(psconstants)); - D3D::g_context->Unmap(pscbuf, 0); + D3D::context->Unmap(pscbuf, 0); pscbufchanged = false; } return pscbuf; } // this class will load the precompiled shaders into our cache -class PixelShaderCacheInserter +class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - template - void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const + void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size) { - std::unique_ptr value(new u8[value_size]); - get_data(value.get()); - - PixelShaderCache::InsertByteCode(key, value.get(), value_size); + PixelShaderCache::InsertByteCode(key, value, value_size); } }; @@ -396,29 +375,29 @@ void PixelShaderCache::Init() { unsigned int cbsize = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - pscbuf = CreateBufferShared(&cbdesc, NULL); - CHECK(pscbuf, "Create pixel shader constant buffer"); - D3D::SetDebugObjectName(pscbuf, "pixel shader constant buffer used to emulate the GX pipeline"); + D3D::device->CreateBuffer(&cbdesc, NULL, &pscbuf); + CHECK(pscbuf!=NULL, "Create pixel shader constant buffer"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "pixel shader constant buffer used to emulate the GX pipeline"); // used when drawing clear quads s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code)); - CHECK(s_ClearProgram, "Create clear pixel shader"); - D3D::SetDebugObjectName(s_ClearProgram, "clear pixel shader"); + CHECK(s_ClearProgram!=NULL, "Create clear pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader"); // used when copying/resolving the color buffer s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code)); - CHECK(s_ColorCopyProgram[0], "Create color copy pixel shader"); - D3D::SetDebugObjectName(s_ColorCopyProgram[0], "color copy pixel shader"); + CHECK(s_ColorCopyProgram[0]!=NULL, "Create color copy pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader"); // used for color conversion s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code)); - CHECK(s_ColorMatrixProgram[0], "Create color matrix pixel shader"); - D3D::SetDebugObjectName(s_ColorMatrixProgram[0], "color matrix pixel shader"); + CHECK(s_ColorMatrixProgram[0]!=NULL, "Create color matrix pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader"); // used for depth copy s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program)); - CHECK(s_DepthMatrixProgram[0], "Create depth matrix pixel shader"); - D3D::SetDebugObjectName(s_DepthMatrixProgram[0], "depth matrix pixel shader"); + CHECK(s_DepthMatrixProgram[0]!=NULL, "Create depth matrix pixel shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader"); Clear(); @@ -430,39 +409,41 @@ void PixelShaderCache::Init() char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - - g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter()); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + PixelShaderCacheInserter inserter; + g_ps_disk_cache.OpenAndRead(cache_filename, inserter); } // ONLY to be used during shutdown. void PixelShaderCache::Clear() { + for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) + iter->second.Destroy(); PixelShaders.clear(); } // Used in Swap() when AA mode has changed void PixelShaderCache::InvalidateMSAAShaders() { - s_ColorCopyProgram[1].reset(); - s_ColorMatrixProgram[1].reset(); - s_DepthMatrixProgram[1].reset(); - s_rgb8_to_rgba6[1].reset(); - s_rgba6_to_rgb8[1].reset(); + SAFE_RELEASE(s_ColorCopyProgram[1]); + SAFE_RELEASE(s_ColorMatrixProgram[1]); + SAFE_RELEASE(s_DepthMatrixProgram[1]); + SAFE_RELEASE(s_rgb8_to_rgba6[1]); + SAFE_RELEASE(s_rgba6_to_rgb8[1]); } void PixelShaderCache::Shutdown() { - pscbuf.reset(); + SAFE_RELEASE(pscbuf); - s_ClearProgram.reset(); + SAFE_RELEASE(s_ClearProgram); for (int i = 0; i < 2; ++i) { - s_ColorCopyProgram[i].reset(); - s_ColorMatrixProgram[i].reset(); - s_DepthMatrixProgram[i].reset(); - s_rgba6_to_rgb8[i].reset(); - s_rgb8_to_rgba6[i].reset(); + SAFE_RELEASE(s_ColorCopyProgram[i]); + SAFE_RELEASE(s_ColorMatrixProgram[i]); + SAFE_RELEASE(s_DepthMatrixProgram[i]); + SAFE_RELEASE(s_rgba6_to_rgb8[i]); + SAFE_RELEASE(s_rgb8_to_rgba6[i]); } Clear(); @@ -470,7 +451,7 @@ void PixelShaderCache::Shutdown() g_ps_disk_cache.Close(); } -bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components) +bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PIXELSHADERUID uid; GetPixelShaderId(&uid, dstAlphaMode); @@ -495,14 +476,14 @@ bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components) last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); - return (!!entry.shader); + return (entry.shader != NULL); } // Need to compile a new shader const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components); - auto const pbytecode = D3D::CompilePixelShader(code, (unsigned int)strlen(code)); - if (!pbytecode) + D3DBlob* pbytecode; + if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode)) { PanicAlert("Failed to compile Pixel Shader:\n\n%s", code); GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); @@ -510,25 +491,25 @@ bool PixelShaderCache::LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components) } // Insert the bytecode into the caches - g_ps_disk_cache.Append(uid, (u8*)pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize()); + g_ps_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size()); g_ps_disk_cache.Sync(); - bool result = InsertByteCode(uid, pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize()); + bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size()); + pbytecode->Release(); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); return result; } bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen) { - auto const shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); - if (!shader) + ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); + if (shader == NULL) { PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__); - // INCSTAT(stats.numPixelShadersFailed); return false; } // TODO: Somehow make the debug name a bit more specific - D3D::SetDebugObjectName(shader, "a pixel shader of PixelShaderCache"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache"); // Make an entry in the table PSCacheEntry newentry; @@ -537,6 +518,11 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* byt PixelShaders[uid] = newentry; last_entry = &PixelShaders[uid]; + if (!shader) { + // INCSTAT(stats.numPixelShadersFailed); + return false; + } + INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); return true; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h index 5377ad47a8..046f551657 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h @@ -33,12 +33,11 @@ public: static void Init(); static void Clear(); static void Shutdown(); - - static bool LoadShader(DSTALPHA_MODE dstAlphaMode, u32 components); + static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen); - static SharedPtr GetActiveShader() { return last_entry->shader; } - static ID3D11Buffer*const& GetConstantBuffer(); + static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; } + static ID3D11Buffer* &GetConstantBuffer(); static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled); static ID3D11PixelShader* GetColorCopyProgram(bool multisampled); @@ -52,10 +51,11 @@ public: private: struct PSCacheEntry { - SharedPtr shader; + ID3D11PixelShader* shader; int frameCount; - PSCacheEntry() : frameCount(0) {} + PSCacheEntry() : shader(NULL), frameCount(0) {} + void Destroy() { SAFE_RELEASE(shader); } }; typedef std::map PSCache; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index b83c9ee8d7..fcf3315802 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -132,19 +132,39 @@ static const char POINT_GS_COMMON[] = ; PointGeometryShader::PointGeometryShader() - : m_ready(false) + : m_ready(false), m_paramsBuffer(NULL) +{ } + +void PointGeometryShader::Init() { + m_ready = false; + + HRESULT hr; + // Create constant buffer for uploading data to geometry shader D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(PointGSParams_Padded), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_paramsBuffer = CreateBufferShared(&bd, NULL); - CHECK(m_paramsBuffer, "create point geometry shader params buffer"); + hr = D3D::device->CreateBuffer(&bd, NULL, &m_paramsBuffer); + CHECK(SUCCEEDED(hr), "create point geometry shader params buffer"); D3D::SetDebugObjectName(m_paramsBuffer, "point geometry shader params buffer"); m_ready = true; } +void PointGeometryShader::Shutdown() +{ + m_ready = false; + + for (ComboMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) + { + SAFE_RELEASE(it->second); + } + m_shaders.clear(); + + SAFE_RELEASE(m_paramsBuffer); +} + bool PointGeometryShader::SetShader(u32 components, float pointSize, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable) { @@ -171,13 +191,12 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, { "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() }, { NULL, NULL } }; - - auto const newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); + ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros); if (!newShader) { WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components); // Add dummy shader to prevent trying to compile again - m_shaders[components].reset(); + m_shaders[components] = NULL; return false; } @@ -189,27 +208,28 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, if (shaderIt->second) { D3D11_MAPPED_SUBRESOURCE map; - HRESULT hr = D3D::g_context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (SUCCEEDED(hr)) { PointGSParams* params = (PointGSParams*)map.pData; params->PointSize = pointSize; + params->TexOffset = texOffset; params->VpWidth = vpWidth; params->VpHeight = vpHeight; for (int i = 0; i < 8; ++i) params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f; - D3D::g_context->Unmap(m_paramsBuffer, 0); + D3D::context->Unmap(m_paramsBuffer, 0); } else ERROR_LOG(VIDEO, "Failed to map point gs params buffer"); - + DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f", pointSize, texOffset, vpWidth, vpHeight); - D3D::g_context->GSSetShader(shaderIt->second, NULL, 0); - D3D::g_context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); + D3D::context->GSSetShader(shaderIt->second, NULL, 0); + D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); return true; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h index eb9422b4fa..f6da45e050 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h @@ -19,7 +19,9 @@ #define _POINTGEOMETRYSHADER_H #include "VideoCommon.h" -#include "D3DUtil.h" + +struct ID3D11Buffer; +struct ID3D11GeometryShader; namespace DX11 { @@ -28,21 +30,27 @@ namespace DX11 // vertex format. class PointGeometryShader { + public: + PointGeometryShader(); + void Init(); + void Shutdown(); // Returns true on success, false on failure bool SetShader(u32 components, float pointSize, float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable); private: + bool m_ready; - SharedPtr m_paramsBuffer; + ID3D11Buffer* m_paramsBuffer; - typedef std::map> ComboMap; + typedef std::map ComboMap; ComboMap m_shaders; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index bc8f7e6ca1..e9dd941611 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -40,6 +40,7 @@ #include "VertexShaderCache.h" #include "Core.h" #include "OnFrame.h" +#include "Television.h" #include "Host.h" namespace DX11 @@ -51,10 +52,12 @@ static u32 s_LastAA = 0; static u32 s_blendMode; -SharedPtr access_efb_cbuf; -SharedPtr clearblendstates[4]; +static Television s_television; + +ID3D11Buffer* access_efb_cbuf = NULL; +ID3D11BlendState* clearblendstates[4] = {NULL}; ID3D11DepthStencilState* cleardepthstates[3] = {NULL}; -SharedPtr resetblendstate; +ID3D11BlendState* resetblendstate = NULL; ID3D11DepthStencilState* resetdepthstate = NULL; ID3D11RasterizerState* resetraststate = NULL; @@ -214,6 +217,8 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] = void SetupDeviceObjects() { + s_television.Init(); + g_framebuffer_manager = new FramebufferManager; HRESULT hr; @@ -222,9 +227,9 @@ void SetupDeviceObjects() D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(20*sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; - access_efb_cbuf = CreateBufferShared(&cbdesc, &data); - CHECK(access_efb_cbuf, "Create constant buffer for Renderer::AccessEFB"); - D3D::SetDebugObjectName(access_efb_cbuf, "constant buffer for Renderer::AccessEFB"); + hr = D3D::device->CreateBuffer(&cbdesc, &data, &access_efb_cbuf); + CHECK(hr==S_OK, "Create constant buffer for Renderer::AccessEFB"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)access_efb_cbuf, "constant buffer for Renderer::AccessEFB"); D3D11_DEPTH_STENCIL_DESC ddesc; ddesc.DepthEnable = FALSE; @@ -233,18 +238,18 @@ void SetupDeviceObjects() ddesc.StencilEnable = FALSE; ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]); + hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]); CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen"); ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; ddesc.DepthEnable = TRUE; - hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]); + hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]); CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen"); ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - hr = D3D::g_device->CreateDepthStencilState(&ddesc, &cleardepthstates[2]); + hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[2]); CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen"); - D3D::SetDebugObjectName(cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)"); - D3D::SetDebugObjectName(cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)"); - D3D::SetDebugObjectName(cleardepthstates[2], "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[2], "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)"); D3D11_BLEND_DESC blenddesc; blenddesc.AlphaToCoverageEnable = FALSE; @@ -257,23 +262,24 @@ void SetupDeviceObjects() blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - resetblendstate = CreateBlendStateShared(&blenddesc); - CHECK(resetblendstate, "Create blend state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(resetblendstate, "blend state for Renderer::ResetAPIState"); + hr = D3D::device->CreateBlendState(&blenddesc, &resetblendstate); + CHECK(hr==S_OK, "Create blend state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)resetblendstate, "blend state for Renderer::ResetAPIState"); clearblendstates[0] = resetblendstate; + resetblendstate->AddRef(); - blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED - | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; - clearblendstates[1] = CreateBlendStateShared(&blenddesc); + blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE; + hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[1]); + CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen"); blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA; - clearblendstates[2] = CreateBlendStateShared(&blenddesc); + hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[2]); + CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen"); blenddesc.RenderTarget[0].RenderTargetWriteMask = 0; - clearblendstates[3] = CreateBlendStateShared(&blenddesc); - - CHECK(clearblendstates[1] && clearblendstates[2] && clearblendstates[3], "Create blend state for Renderer::ClearScreen"); + hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]); + CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen"); ddesc.DepthEnable = FALSE; ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; @@ -281,14 +287,14 @@ void SetupDeviceObjects() ddesc.StencilEnable = FALSE; ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - hr = D3D::g_device->CreateDepthStencilState(&ddesc, &resetdepthstate); + hr = D3D::device->CreateDepthStencilState(&ddesc, &resetdepthstate); CHECK(hr==S_OK, "Create depth state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(resetdepthstate, "depth stencil state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)resetdepthstate, "depth stencil state for Renderer::ResetAPIState"); D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false); - hr = D3D::g_device->CreateRasterizerState(&rastdesc, &resetraststate); + hr = D3D::device->CreateRasterizerState(&rastdesc, &resetraststate); CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState"); - D3D::SetDebugObjectName(resetraststate, "rasterizer state for Renderer::ResetAPIState"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState"); } // Kill off all POOL_DEFAULT device objects. @@ -296,17 +302,19 @@ void TeardownDeviceObjects() { delete g_framebuffer_manager; - access_efb_cbuf.reset(); - - for (int i = 0; i != 4; ++i) - clearblendstates[i].reset(); - + SAFE_RELEASE(access_efb_cbuf); + SAFE_RELEASE(clearblendstates[0]); + SAFE_RELEASE(clearblendstates[1]); + SAFE_RELEASE(clearblendstates[2]); + SAFE_RELEASE(clearblendstates[3]); SAFE_RELEASE(cleardepthstates[0]); SAFE_RELEASE(cleardepthstates[1]); SAFE_RELEASE(cleardepthstates[2]); - resetblendstate.reset(); + SAFE_RELEASE(resetblendstate); SAFE_RELEASE(resetdepthstate); SAFE_RELEASE(resetraststate); + + s_television.Shutdown(); } Renderer::Renderer() @@ -318,8 +326,6 @@ Renderer::Renderer() D3D::Create(EmuWindow::GetWnd()); - m_television.reset(new Television); - s_backbuffer_width = D3D::GetBackBufferWidth(); s_backbuffer_height = D3D::GetBackBufferHeight(); @@ -373,20 +379,17 @@ Renderer::Renderer() // Clear EFB textures float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f }; - D3D::g_context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor); - D3D::g_context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); + D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), ClearColor); + D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); - D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, - (float)s_target_width, (float)s_target_height); - D3D::g_context->RSSetViewports(1, &vp); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_target_width, (float)s_target_height); + D3D::context->RSSetViewports(1, &vp); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); D3D::BeginFrame(); } Renderer::~Renderer() { - m_television.reset(); - TeardownDeviceObjects(); D3D::EndFrame(); D3D::Present(); @@ -476,15 +479,14 @@ bool Renderer::SetScissorRect() if (rc.right >= rc.left && rc.bottom >= rc.top) { - D3D::g_context->RSSetScissorRects(1, rc.AsRECT()); + D3D::context->RSSetScissorRects(1, rc.AsRECT()); return true; } else { //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom); - *rc.AsRECT() = CD3D11_RECT(0, 0, - s_target_width, s_target_height); - D3D::g_context->RSSetScissorRects(1, rc.AsRECT()); + *rc.AsRECT() = CD3D11_RECT(0.f, 0.f, s_target_width, s_target_height); + D3D::context->RSSetScissorRects(1, rc.AsRECT()); return false; } } @@ -563,9 +565,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // depth buffers can only be completely CopySubresourceRegion'ed, so we're using drawShadedTexQuad instead D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 1.f, 1.f); - D3D::g_context->RSSetViewports(1, &vp); - D3D::g_context->PSSetConstantBuffers(0, 1, &access_efb_cbuf); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL); + D3D::context->RSSetViewports(1, &vp); + D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV(), NULL); D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(), &RectToLock, @@ -575,17 +577,17 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); // copy to system memory D3D11_BOX box = CD3D11_BOX(0, 0, 0, 1, 1, 1); read_tex = FramebufferManager::GetEFBDepthStagingBuffer(); - D3D::g_context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBDepthReadTexture()->GetTex(), 0, &box); + D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FramebufferManager::GetEFBDepthReadTexture()->GetTex(), 0, &box); RestoreAPIState(); // restore game state // read the data from system memory - D3D::g_context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); + D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); float val = *(float*)map.pData; u32 ret = 0; @@ -598,7 +600,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { ret = ((u32)(val * 0xffffff)); } - D3D::g_context->Unmap(read_tex, 0); + D3D::context->Unmap(read_tex, 0); // TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear return ret; @@ -608,14 +610,14 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // we can directly copy to system memory here read_tex = FramebufferManager::GetEFBColorStagingBuffer(); D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1); - D3D::g_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); // read the data from system memory - D3D::g_context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); + D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); u32 ret = 0; if(map.pData) ret = *(u32*)map.pData; - D3D::g_context->Unmap(read_tex, 0); + D3D::context->Unmap(read_tex, 0); // check what to do with the alpha channel (GX_PokeAlphaRead) PixelEngine::UPEAlphaReadReg alpha_read_mode; @@ -645,7 +647,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // TODO: The first five PE registers may change behavior of EFB pokes, this isn't implemented, yet. ResetAPIState(); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL); D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, @@ -713,9 +715,11 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) int X = intendedX; if (X < 0) X = 0; + int Y = intendedY; if (Y < 0) Y = 0; + int Wd = intendedWd; if (X + Wd > GetTargetWidth()) Wd = GetTargetWidth() - X; @@ -733,7 +737,7 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection) D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht, 0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; 1.f); // xfregs.viewport.farZ / 16777216.0f; - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); } void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) @@ -753,7 +757,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE // Update the view port for clearing the picture TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), 0.f, 1.f); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); // Color is passed in bgra mode so we need to convert it to rgba u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); @@ -783,18 +787,16 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) g_renderer->ResetAPIState(); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)g_renderer->GetTargetWidth(), (float)g_renderer->GetTargetHeight()); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV(), NULL); D3D::SetPointCopySampler(); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &source, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), pixel_shader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); g_renderer->RestoreAPIState(); FramebufferManager::SwapReinterpretTexture(); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } void SetSrcBlend(D3D11_BLEND val) @@ -874,15 +876,15 @@ void Renderer::SetBlendMode(bool forceUpdate) bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc) { // copy back buffer to system memory + ID3D11Texture2D* buftex; D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE); - auto const buftex = CreateTexture2DShared(&tex_desc, NULL); - if (!buftex) - PanicAlert("Failed to create screenshot buffer texture"); - D3D::g_context->CopyResource(buftex, D3D::GetBackBuffer()->GetTex()); + HRESULT hr = D3D::device->CreateTexture2D(&tex_desc, NULL, &buftex); + if (FAILED(hr)) PanicAlert("Failed to create screenshot buffer texture"); + D3D::context->CopyResource(buftex, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); // D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves D3D11_MAPPED_SUBRESOURCE map; - D3D::g_context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map); + D3D::context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map); for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y) { u8* ptr = (u8*)map.pData + y * map.RowPitch + 3; @@ -892,10 +894,12 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle ptr += 4; } } - D3D::g_context->Unmap(buftex, 0); + D3D::context->Unmap(buftex, 0); // ready to be saved - HRESULT hr = PD3DX11SaveTextureToFileA(D3D::g_context, buftex, D3DX11_IFF_PNG, filename.c_str()); + hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, filename.c_str()); + buftex->Release(); + return SUCCEEDED(hr); } @@ -926,9 +930,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons TargetRectangle dst_rect; ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f }; - D3D::g_context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), ClearColor); + D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), ClearColor); int X = dst_rect.left; int Y = dst_rect.top; @@ -944,8 +948,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; vp = CD3D11_VIEWPORT((float)X, (float)Y, (float)Width, (float)Height); - D3D::g_context->RSSetViewports(1, &vp); - D3D::g_context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); + D3D::context->RSSetViewports(1, &vp); + D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); // activate linear filtering for the buffer copies D3D::SetLinearCopySampler(); @@ -953,10 +957,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB) { // TODO: Television should be used to render Virtual XFB mode as well. - m_television->Submit(xfbAddr, fbWidth, fbHeight); - m_television->Render(); + s_television.Submit(xfbAddr, fbWidth, fbHeight); + s_television.Render(); } - else if (g_ActiveConfig.bUseXFB) + else if(g_ActiveConfig.bUseXFB) { const XFBSourceBase* xfbSource; @@ -1011,11 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture(); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), - Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), - PixelShaderCache::GetColorCopyProgram(false), - VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout(), Gamma); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(false),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma); } // done with drawing the game stuff, good moment to save a screenshot @@ -1129,19 +1129,19 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_LastEFBScale = g_ActiveConfig.iEFBScale; CalculateTargetSize(); - D3D::g_context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); delete g_framebuffer_manager; g_framebuffer_manager = new FramebufferManager; float clear_col[4] = { 0.f, 0.f, 0.f, 1.f }; - D3D::g_context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), clear_col); - D3D::g_context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); + D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(), clear_col); + D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); } // begin next frame Renderer::RestoreAPIState(); D3D::BeginFrame(); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); VertexShaderManager::SetViewportChanged(); Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); @@ -1189,26 +1189,25 @@ void Renderer::ApplyState(bool bUseDstAlpha) gx_state.blenddc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; } - { - auto const blstate = CreateBlendStateShared(&gx_state.blenddc); - if (!blstate) - PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); + ID3D11BlendState* blstate; + hr = D3D::device->CreateBlendState(&gx_state.blenddc, &blstate); + if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); D3D::stateman->PushBlendState(blstate); - D3D::SetDebugObjectName(blstate, "blend state used to emulate the GX pipeline"); - } + D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "blend state used to emulate the GX pipeline"); + SAFE_RELEASE(blstate); ID3D11DepthStencilState* depth_state; - hr = D3D::g_device->CreateDepthStencilState(&gx_state.depthdc, &depth_state); - if (SUCCEEDED(hr)) D3D::SetDebugObjectName(depth_state, "depth-stencil state used to emulate the GX pipeline"); + hr = D3D::device->CreateDepthStencilState(&gx_state.depthdc, &depth_state); + if (SUCCEEDED(hr)) D3D::SetDebugObjectName((ID3D11DeviceChild*)depth_state, "depth-stencil state used to emulate the GX pipeline"); else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__); D3D::stateman->PushDepthState(depth_state); SAFE_RELEASE(depth_state); gx_state.rastdc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; ID3D11RasterizerState* raststate; - hr = D3D::g_device->CreateRasterizerState(&gx_state.rastdc, &raststate); + hr = D3D::device->CreateRasterizerState(&gx_state.rastdc, &raststate); if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(raststate, "rasterizer state used to emulate the GX pipeline"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)raststate, "rasterizer state used to emulate the GX pipeline"); D3D::stateman->PushRasterizerState(raststate); SAFE_RELEASE(raststate); @@ -1219,13 +1218,13 @@ void Renderer::ApplyState(bool bUseDstAlpha) //if (shader_resources[stage]) { if(g_ActiveConfig.iMaxAnisotropy > 0) gx_state.sampdc[stage].Filter = D3D11_FILTER_ANISOTROPIC; - hr = D3D::g_device->CreateSamplerState(&gx_state.sampdc[stage], &samplerstate[stage]); + hr = D3D::device->CreateSamplerState(&gx_state.sampdc[stage], &samplerstate[stage]); if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage); - else D3D::SetDebugObjectName(samplerstate[stage], "sampler state used to emulate the GX pipeline"); + else D3D::SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "sampler state used to emulate the GX pipeline"); } // else samplerstate[stage] = NULL; } - D3D::g_context->PSSetSamplers(0, 8, samplerstate); + D3D::context->PSSetSamplers(0, 8, samplerstate); for (unsigned int stage = 0; stage < 8; stage++) SAFE_RELEASE(samplerstate[stage]); @@ -1238,17 +1237,17 @@ void Renderer::ApplyState(bool bUseDstAlpha) SetLogicOpMode(); } - D3D::g_context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer()); - D3D::g_context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer()); + D3D::context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer()); + D3D::context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer()); - D3D::g_context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0); - D3D::g_context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0); + D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0); + D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0); } void Renderer::RestoreState() { ID3D11ShaderResourceView* shader_resources[8] = { NULL }; - D3D::g_context->PSSetShaderResources(0, 8, shader_resources); + D3D::context->PSSetShaderResources(0, 8, shader_resources); D3D::stateman->PopBlendState(); D3D::stateman->PopDepthState(); @@ -1261,9 +1260,9 @@ void Renderer::ApplyCullDisable() rastDesc.CullMode = D3D11_CULL_NONE; ID3D11RasterizerState* raststate; - HRESULT hr = D3D::g_device->CreateRasterizerState(&rastDesc, &raststate); + HRESULT hr = D3D::device->CreateRasterizerState(&rastDesc, &raststate); if (FAILED(hr)) PanicAlert("Failed to create culling-disabled rasterizer state at %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(raststate, "rasterizer state (culling disabled) used to emulate the GX pipeline"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)raststate, "rasterizer state (culling disabled) used to emulate the GX pipeline"); D3D::stateman->PushRasterizerState(raststate); SAFE_RELEASE(raststate); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 7e6b4594b5..5d1c24bc23 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -3,7 +3,6 @@ #define _RENDER_H_ #include "RenderBase.h" -#include "Television.h" namespace DX11 { @@ -61,9 +60,6 @@ public: void SetVSConstant4fv(unsigned int const_number, const float *f); void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f); void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f); - -private: - std::unique_ptr m_television; }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Television.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Television.cpp index 26cacd3782..bed7d8e632 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Television.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Television.cpp @@ -71,35 +71,43 @@ static const char YUYV_DECODER_PS[] = ; Television::Television() - : m_yuyvTextureSRV(NULL) + : m_yuyvTexture(NULL), m_yuyvTextureSRV(NULL), m_pShader(NULL) +{ } + +void Television::Init() { + HRESULT hr; + // Create YUYV texture for real XFB mode // This texture format is designed for YUYV data. D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_G8R8_G8B8_UNORM, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 1, 1); - m_yuyvTexture = CreateTexture2DShared(&t2dd, NULL); - CHECK(m_yuyvTexture, "create tv yuyv texture"); + hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_yuyvTexture); + CHECK(SUCCEEDED(hr), "create tv yuyv texture"); D3D::SetDebugObjectName(m_yuyvTexture, "tv yuyv texture"); // Create shader resource view for YUYV texture D3D11_SHADER_RESOURCE_VIEW_DESC srvd = CD3D11_SHADER_RESOURCE_VIEW_DESC( - m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_G8R8_G8B8_UNORM); - HRESULT hr = D3D::g_device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV); + m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D, + DXGI_FORMAT_G8R8_G8B8_UNORM); + hr = D3D::device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV); CHECK(SUCCEEDED(hr), "create tv yuyv texture srv"); D3D::SetDebugObjectName(m_yuyvTextureSRV, "tv yuyv texture srv"); // Create YUYV-decoding pixel shader m_pShader = D3D::CompileAndCreatePixelShader(YUYV_DECODER_PS, sizeof(YUYV_DECODER_PS)); - CHECK(m_pShader, "compile and create yuyv decoder pixel shader"); + CHECK(m_pShader != NULL, "compile and create yuyv decoder pixel shader"); D3D::SetDebugObjectName(m_pShader, "yuyv decoder pixel shader"); } -Television::~Television() +void Television::Shutdown() { + SAFE_RELEASE(m_pShader); SAFE_RELEASE(m_yuyvTextureSRV); + SAFE_RELEASE(m_yuyvTexture); } void Television::Submit(u32 xfbAddr, u32 width, u32 height) @@ -111,7 +119,7 @@ void Television::Submit(u32 xfbAddr, u32 width, u32 height) // Load data from GameCube RAM to YUYV texture u8* yuyvSrc = Memory::GetPointer(xfbAddr); D3D11_BOX box = CD3D11_BOX(0, 0, 0, width, height, 1); - D3D::g_context->UpdateSubresource(m_yuyvTexture, 0, &box, yuyvSrc, 2*width, 2*width*height); + D3D::context->UpdateSubresource(m_yuyvTexture, 0, &box, yuyvSrc, 2*width, 2*width*height); } void Television::Render() diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Television.h b/Source/Plugins/Plugin_VideoDX11/Src/Television.h index e1c16c63c5..0b9a346a7c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Television.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Television.h @@ -20,16 +20,22 @@ #include "VideoCommon.h" -#include "D3DUtil.h" +struct ID3D11Texture2D; +struct ID3D11ShaderResourceView; +struct ID3D11PixelShader; namespace DX11 { class Television { + public: + Television(); - ~Television(); + + void Init(); + void Shutdown(); // Submit video data to be drawn. This will change the current state of the // TV. xfbAddr points to YUYV data stored in GameCube/Wii RAM, but the XFB @@ -48,9 +54,10 @@ private: // Used for real XFB mode - SharedPtr m_yuyvTexture; + ID3D11Texture2D* m_yuyvTexture; ID3D11ShaderResourceView* m_yuyvTextureSRV; - SharedPtr m_pShader; + ID3D11PixelShader* m_pShader; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 542cb2bf0e..39018c83bc 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -31,18 +31,23 @@ namespace DX11 { -static std::unique_ptr g_encoder; +static TextureEncoder* g_encoder = NULL; const size_t MAX_COPY_BUFFERS = 25; -static SharedPtr efbcopycbuf[MAX_COPY_BUFFERS]; +ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 }; + +TextureCache::TCacheEntry::~TCacheEntry() +{ + texture->Release(); +} void TextureCache::TCacheEntry::Bind(unsigned int stage) { - D3D::g_context->PSSetShaderResources(stage, 1, &texture->GetSRV()); + D3D::context->PSSetShaderResources(stage, 1, &texture->GetSRV()); } bool TextureCache::TCacheEntry::Save(const char filename[]) { - return SUCCEEDED(PD3DX11SaveTextureToFileA(D3D::g_context, texture->GetTex(), D3DX11_IFF_PNG, filename)); + return SUCCEEDED(PD3DX11SaveTextureToFileA(D3D::context, texture->GetTex(), D3DX11_IFF_PNG, filename)); } void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, @@ -51,7 +56,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage); if (autogen_mips) - PD3DX11FilterTexture(D3D::g_context, texture->GetTex(), 0, D3DX11_DEFAULT); + PD3DX11FilterTexture(D3D::context, texture->GetTex(), 0, D3DX11_DEFAULT); } TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, @@ -76,16 +81,18 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access); - auto const pTexture = CreateTexture2DShared(&texdesc, data); - CHECK(pTexture, "Create texture of the TextureCache"); + ID3D11Texture2D *pTexture; + const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture); + CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); - std::unique_ptr tx(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); - auto const entry = new TCacheEntry(std::move(tx)); + TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); entry->usage = usage; // TODO: better debug names - D3D::SetDebugObjectName(entry->texture->GetTex(), "a texture of the TextureCache"); - D3D::SetDebugObjectName(entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache"); + + SAFE_RELEASE(pTexture); return entry; } @@ -101,7 +108,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); // set transformation if (NULL == efbcopycbuf[cbufid]) @@ -109,11 +116,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; - efbcopycbuf[cbufid] = CreateBufferShared(&cbdesc, &data); - CHECK(efbcopycbuf[cbufid], "Create efb copy constant buffer %d", cbufid); - D3D::SetDebugObjectName(efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); + HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); + CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); + D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } - D3D::g_context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]); + D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); @@ -125,7 +132,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo else D3D::SetPointCopySampler(); - D3D::g_context->OMSetRenderTargets(1, &texture->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL); // Create texture copy D3D::drawShadedTexQuad( @@ -134,7 +141,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo (srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); - D3D::g_context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); } @@ -143,7 +150,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo { u8* dst = Memory::GetPointer(dstAddr); size_t encodeSize = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf); - hash = GetHash64(dst, (int)encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples); + hash = GetHash64(dst, encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples); if (g_ActiveConfig.bEFBCopyCacheEnable) { // If the texture in RAM is already in the texture cache, @@ -152,7 +159,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo return; } - TextureCache::MakeRangeDynamic(dstAddr, (u32)encodeSize); + TextureCache::MakeRangeDynamic(dstAddr, encodeSize); } } @@ -167,12 +174,18 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture( TextureCache::TextureCache() { // FIXME: Is it safe here? - g_encoder.reset(new PSTextureEncoder); + g_encoder = new PSTextureEncoder; + g_encoder->Init(); } TextureCache::~TextureCache() { - g_encoder.reset(); + for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k) + SAFE_RELEASE(efbcopycbuf[k]); + + g_encoder->Shutdown(); + delete g_encoder; + g_encoder = NULL; } } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h index 02fc6b3cf5..89c0c66447 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h @@ -33,11 +33,12 @@ public: private: struct TCacheEntry : TCacheEntryBase { - std::unique_ptr const texture; + D3DTexture2D *const texture; D3D11_USAGE usage; - TCacheEntry(std::unique_ptr&& _tex) : texture(std::move(_tex)) {} + TCacheEntry(D3DTexture2D *_tex) : texture(_tex) {} + ~TCacheEntry(); void Load(unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int levels, bool autogen_mips = false); @@ -55,6 +56,7 @@ private: unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt); TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h); + u64 EncodeToRamFromTexture(u32 address, void* source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) {return 0;}; }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureEncoder.h b/Source/Plugins/Plugin_VideoDX11/Src/TextureEncoder.h index 34ab85d313..8cfa923911 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureEncoder.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureEncoder.h @@ -116,13 +116,18 @@ static const UINT MAX_BYTES_PER_ENCODE = MAX_BYTES_PER_BLOCK_ROW*(EFB_HEIGHT/4); class TextureEncoder { -public: - virtual ~TextureEncoder() {} +public: + + virtual ~TextureEncoder() { } + + virtual void Init() = 0; + virtual void Shutdown() = 0; // Returns size in bytes of encoded block of memory virtual size_t Encode(u8* dst, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) = 0; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 09cd73e48f..e1e40047e4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -42,21 +42,21 @@ namespace DX11 const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE*2 * 16; const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; -VertexManager::VertexManager() +void VertexManager::CreateDeviceObjects() { D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_indexBuffer = CreateBufferShared(&bufdesc, NULL); - CHECK(m_indexBuffer, "Failed to create index buffer."); - D3D::SetDebugObjectName(m_indexBuffer, "index buffer of VertexManager"); + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffer)), + "Failed to create index buffer."); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffer, "index buffer of VertexManager"); bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufdesc.ByteWidth = VBUFFER_SIZE; - m_vertexBuffer = CreateBufferShared(&bufdesc, NULL); - CHECK(m_vertexBuffer, "Failed to create vertex buffer."); - D3D::SetDebugObjectName(m_vertexBuffer, "vertex buffer of VertexManager"); + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffer)), + "Failed to create vertex buffer."); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffer, "vertex buffer of VertexManager"); m_indexBufferCursor = 0; m_vertexBufferCursor = 0; @@ -65,6 +65,28 @@ VertexManager::VertexManager() m_triangleDrawIndex = 0; m_lineDrawIndex = 0; m_pointDrawIndex = 0; + + m_lineShader.Init(); + m_pointShader.Init(); +} + +void VertexManager::DestroyDeviceObjects() +{ + m_pointShader.Shutdown(); + m_lineShader.Shutdown(); + + SAFE_RELEASE(m_vertexBuffer); + SAFE_RELEASE(m_indexBuffer); +} + +VertexManager::VertexManager() +{ + CreateDeviceObjects(); +} + +VertexManager::~VertexManager() +{ + DestroyDeviceObjects(); } void VertexManager::LoadBuffers() @@ -75,16 +97,16 @@ void VertexManager::LoadBuffers() if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) { // Wrap around - D3D::g_context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); m_vertexBufferCursor = 0; } else { // Append data - D3D::g_context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); + D3D::context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); } memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); - D3D::g_context->Unmap(m_vertexBuffer, 0); + D3D::context->Unmap(m_vertexBuffer, 0); m_vertexDrawOffset = m_vertexBufferCursor; m_vertexBufferCursor += vSize; @@ -93,13 +115,13 @@ void VertexManager::LoadBuffers() if (m_indexBufferCursor + iCount >= IBUFFER_SIZE/2) { // Wrap around - D3D::g_context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); m_indexBufferCursor = 0; } else { // Append data - D3D::g_context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); + D3D::context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); } m_triangleDrawIndex = m_indexBufferCursor; m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); @@ -107,7 +129,7 @@ void VertexManager::LoadBuffers() memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, 2*IndexGenerator::GetTriangleindexLen()); memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, 2*IndexGenerator::GetLineindexLen()); memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, 2*IndexGenerator::GetPointindexLen()); - D3D::g_context->Unmap(m_indexBuffer, 0); + D3D::context->Unmap(m_indexBuffer, 0); m_indexBufferCursor += iCount; } @@ -117,13 +139,13 @@ static const float LINE_PT_TEX_OFFSETS[8] = { void VertexManager::Draw(UINT stride) { - D3D::g_context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset); - D3D::g_context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); + D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &m_vertexDrawOffset); + D3D::context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); if (IndexGenerator::GetNumTriangles() > 0) { - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - D3D::g_context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } // Disable culling for lines and points @@ -137,17 +159,18 @@ void VertexManager::Draw(UINT stride) float vpHeight = -2.0f * xfregs.viewport.ht; bool texOffsetEnable[8]; + for (int i = 0; i < 8; ++i) texOffsetEnable[i] = bpmem.texcoords[i].s.line_offset; if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth, texOffset, vpWidth, vpHeight, texOffsetEnable)) { - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - D3D::g_context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); - D3D::g_context->GSSetShader(NULL, NULL, 0); + D3D::context->GSSetShader(NULL, NULL, 0); } } if (IndexGenerator::GetNumPoints() > 0) @@ -158,17 +181,18 @@ void VertexManager::Draw(UINT stride) float vpHeight = -2.0f * xfregs.viewport.ht; bool texOffsetEnable[8]; + for (int i = 0; i < 8; ++i) texOffsetEnable[i] = bpmem.texcoords[i].s.point_offset; if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize, texOffset, vpWidth, vpHeight, texOffsetEnable)) { - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - D3D::g_context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); - D3D::g_context->GSSetShader(NULL, NULL, 0); + D3D::context->GSSetShader(NULL, NULL, 0); } } if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0) @@ -223,14 +247,14 @@ void VertexManager::vFlush() bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - if (!PixelShaderCache::LoadShader( + if (!PixelShaderCache::SetShader( useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; } - if (!VertexShaderCache::LoadShader(g_nativeVertexFmt->m_components)) + if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h index e2f58a8117..a387be5155 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h @@ -29,10 +29,13 @@ class VertexManager : public ::VertexManager { public: VertexManager(); + ~VertexManager(); NativeVertexFormat* CreateNativeVertexFormat(); private: + void CreateDeviceObjects(); + void DestroyDeviceObjects(); void LoadBuffers(); void Draw(UINT stride); // temp @@ -44,8 +47,8 @@ private: UINT m_triangleDrawIndex; UINT m_lineDrawIndex; UINT m_pointDrawIndex; - SharedPtr m_indexBuffer; - SharedPtr m_vertexBuffer; + ID3D11Buffer* m_indexBuffer; + ID3D11Buffer* m_vertexBuffer; LineGeometryShader m_lineShader; PointGeometryShader m_pointShader; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 0ac6cbb563..041caba28c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -36,13 +36,12 @@ bool vscbufchanged = true; namespace DX11 { VertexShaderCache::VSCache VertexShaderCache::vshaders; -const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry; +const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; -static SharedPtr SimpleVertexShader; -static SharedPtr ClearVertexShader; - -static SharedPtr SimpleLayout; -static SharedPtr ClearLayout; +static ID3D11VertexShader* SimpleVertexShader = NULL; +static ID3D11VertexShader* ClearVertexShader = NULL; +static ID3D11InputLayout* SimpleLayout = NULL; +static ID3D11InputLayout* ClearLayout = NULL; LinearDiskCache g_vs_disk_cache; @@ -51,34 +50,32 @@ ID3D11VertexShader* VertexShaderCache::GetClearVertexShader() { return ClearVert ID3D11InputLayout* VertexShaderCache::GetSimpleInputLayout() { return SimpleLayout; } ID3D11InputLayout* VertexShaderCache::GetClearInputLayout() { return ClearLayout; } -SharedPtr vscbuf; +ID3D11Buffer* vscbuf = NULL; -ID3D11Buffer*const& VertexShaderCache::GetConstantBuffer() +ID3D11Buffer* &VertexShaderCache::GetConstantBuffer() { // TODO: divide the global variables of the generated shaders into about 5 constant buffers to speed this up if (vscbufchanged) { D3D11_MAPPED_SUBRESOURCE map; - D3D::g_context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D::context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); memcpy(map.pData, vsconstants, sizeof(vsconstants)); - D3D::g_context->Unmap(vscbuf, 0); + D3D::context->Unmap(vscbuf, 0); vscbufchanged = false; } return vscbuf; } // this class will load the precompiled shaders into our cache -class VertexShaderCacheInserter +class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - template - void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const + void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size) { - ID3D10Blob* blob = nullptr; - PD3D10CreateBlob(value_size, &blob); - get_data((u8*)blob->GetBufferPointer()); // read data from file into blob + D3DBlob* blob = new D3DBlob(value_size, value); + VertexShaderCache::InsertByteCode(key, blob); + blob->Release(); - VertexShaderCache::InsertByteCode(key, SharedPtr::FromPtr(blob)); } }; @@ -130,29 +127,26 @@ void VertexShaderCache::Init() unsigned int cbsize = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - vscbuf = CreateBufferShared(&cbdesc, NULL); - CHECK(vscbuf, "Create vertex shader constant buffer (size=%u)", cbsize); - D3D::SetDebugObjectName(vscbuf, "vertex shader constant buffer used to emulate the GX pipeline"); + HRESULT hr = D3D::device->CreateBuffer(&cbdesc, NULL, &vscbuf); + CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", cbsize); + D3D::SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "vertex shader constant buffer used to emulate the GX pipeline"); - { - auto const blob = D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code)); - SimpleLayout = CreateInputLayoutShared(simpleelems, 2, blob->GetBufferPointer(), blob->GetBufferSize()); + D3DBlob* blob; + D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob); + D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout); SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob); - if (SimpleLayout == NULL || !SimpleVertexShader) - PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(SimpleVertexShader, "simple vertex shader"); - D3D::SetDebugObjectName(SimpleLayout, "simple input layout"); - } + if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); + blob->Release(); + D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout"); - { - auto const blob = D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code)); - ClearLayout = CreateInputLayoutShared(clearelems, 2, blob->GetBufferPointer(), blob->GetBufferSize()); + D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob); + D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout); ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob); - if (ClearLayout == NULL || !ClearVertexShader) - PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); - D3D::SetDebugObjectName(ClearVertexShader, "clear vertex shader"); - D3D::SetDebugObjectName(ClearLayout, "clear input layout"); - } + if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); + blob->Release(); + D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout"); Clear(); @@ -177,39 +171,41 @@ void VertexShaderCache::Init() char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - - g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter()); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + VertexShaderCacheInserter inserter; + g_vs_disk_cache.OpenAndRead(cache_filename, inserter); } void VertexShaderCache::Clear() { + for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) + iter->second.Destroy(); vshaders.clear(); } void VertexShaderCache::Shutdown() { - vscbuf.reset(); + SAFE_RELEASE(vscbuf); - SimpleVertexShader.reset(); - ClearVertexShader.reset(); + SAFE_RELEASE(SimpleVertexShader); + SAFE_RELEASE(ClearVertexShader); - SimpleLayout.reset(); - ClearLayout.reset(); + SAFE_RELEASE(SimpleLayout); + SAFE_RELEASE(ClearLayout); Clear(); g_vs_disk_cache.Sync(); g_vs_disk_cache.Close(); } -bool VertexShaderCache::LoadShader(u32 components) +bool VertexShaderCache::SetShader(u32 components) { VERTEXSHADERUID uid; GetVertexShaderId(&uid, components); if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (!!vshaders[uid].shader); + return (vshaders[uid].shader != NULL); } memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); @@ -222,37 +218,39 @@ bool VertexShaderCache::LoadShader(u32 components) last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (!!entry.shader); + return (entry.shader != NULL); } const char *code = GenerateVertexShaderCode(components, API_D3D11); - auto const pbytecode = D3D::CompileVertexShader(code, (int)strlen(code)); - if (!pbytecode) + D3DBlob* pbytecode = NULL; + D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode); + + if (pbytecode == NULL) { PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code); GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; } - g_vs_disk_cache.Append(uid, (u8*)pbytecode->GetBufferPointer(), (u32)pbytecode->GetBufferSize()); + g_vs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size()); g_vs_disk_cache.Sync(); bool result = InsertByteCode(uid, pbytecode); + pbytecode->Release(); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return result; } -bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, SharedPtr bcodeblob) +bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob) { - auto const shader = D3D::CreateVertexShaderFromByteCode(bcodeblob); - if (!shader) + ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob); + if (shader == NULL) { - PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", - bcodeblob->GetBufferPointer(), bcodeblob->GetBufferSize(), __FILE__, __LINE__); + PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", bcodeblob->Data(), bcodeblob->Size(), __FILE__, __LINE__); return false; } // TODO: Somehow make the debug name a bit more specific - D3D::SetDebugObjectName(shader, "a vertex shader of VertexShaderCache"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache"); // Make an entry in the table VSCacheEntry entry; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h index 7d34cafd01..3c7dadd3e7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h @@ -20,12 +20,12 @@ #include -#include "D3DUtil.h" +#include "D3DBase.h" +#include "D3DBlob.h" class VERTEXSHADERUID; -namespace DX11 -{ +namespace DX11 { class VertexShaderCache { @@ -33,33 +33,37 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool LoadShader(u32 components); + static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader - static SharedPtr GetActiveShader() { return last_entry->shader; } - static SharedPtr GetActiveShaderBytecode() { return last_entry->bytecode; } - static ID3D11Buffer*const& GetConstantBuffer(); + static ID3D11VertexShader* GetActiveShader() { return last_entry->shader; } + static D3DBlob* GetActiveShaderBytecode() { return last_entry->bytecode; } + static ID3D11Buffer* &GetConstantBuffer(); static ID3D11VertexShader* GetSimpleVertexShader(); static ID3D11VertexShader* GetClearVertexShader(); static ID3D11InputLayout* GetSimpleInputLayout(); static ID3D11InputLayout* GetClearInputLayout(); - static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, SharedPtr bcodeblob); + static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob); private: struct VSCacheEntry { - SharedPtr shader; - SharedPtr bytecode; // needed to initialize the input layout + ID3D11VertexShader* shader; + D3DBlob* bytecode; // needed to initialize the input layout int frameCount; - VSCacheEntry() - : frameCount(0) - {} - - void SetByteCode(SharedPtr blob) + VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {} + void SetByteCode(D3DBlob* blob) { + SAFE_RELEASE(bytecode); bytecode = blob; + blob->AddRef(); + } + void Destroy() + { + SAFE_RELEASE(shader); + SAFE_RELEASE(bytecode); } }; typedef std::map VSCache; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.cpp b/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.cpp index 07969fb837..991f1c31ed 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.cpp @@ -18,6 +18,7 @@ #include "XFBEncoder.h" #include "D3DBase.h" +#include "D3DBlob.h" #include "D3DShader.h" #include "Render.h" #include "GfxState.h" @@ -143,10 +144,16 @@ static const struct QuadVertex } QUAD_VERTS[4] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }; XFBEncoder::XFBEncoder() - : m_outRTV(NULL), - m_xfbEncodeDepthState(NULL), + : m_out(NULL), m_outRTV(NULL), m_outStage(NULL), m_encodeParams(NULL), + m_quad(NULL), m_vShader(NULL), m_quadLayout(NULL), m_pShader(NULL), + m_xfbEncodeBlendState(NULL), m_xfbEncodeDepthState(NULL), m_xfbEncodeRastState(NULL), m_efbSampler(NULL) +{ } + +void XFBEncoder::Init() { + HRESULT hr; + // Create output texture // The pixel shader can generate one YUYV entry per pixel. One YUYV entry @@ -154,15 +161,15 @@ XFBEncoder::XFBEncoder() D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1, D3D11_BIND_RENDER_TARGET); - m_out = CreateTexture2DShared(&t2dd, NULL); - CHECK(m_out, "create xfb encoder output texture"); + hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_out); + CHECK(SUCCEEDED(hr), "create xfb encoder output texture"); D3D::SetDebugObjectName(m_out, "xfb encoder output texture"); // Create output render target view D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out, D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM); - HRESULT hr = D3D::g_device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV); + hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV); CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv"); D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv"); @@ -171,16 +178,16 @@ XFBEncoder::XFBEncoder() t2dd.Usage = D3D11_USAGE_STAGING; t2dd.BindFlags = 0; t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - m_outStage = CreateTexture2DShared(&t2dd, NULL); - CHECK(m_outStage, "create xfb encoder output staging buffer"); + hr = D3D::device->CreateTexture2D(&t2dd, NULL, &m_outStage); + CHECK(SUCCEEDED(hr), "create xfb encoder output staging buffer"); D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer"); // Create constant buffer for uploading params to shaders D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams), D3D11_BIND_CONSTANT_BUFFER); - m_encodeParams = CreateBufferShared(&bd, NULL); - CHECK(m_encodeParams, "create xfb encode params buffer"); + hr = D3D::device->CreateBuffer(&bd, NULL, &m_encodeParams); + CHECK(SUCCEEDED(hr), "create xfb encode params buffer"); D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer"); // Create vertex quad @@ -189,24 +196,35 @@ XFBEncoder::XFBEncoder() D3D11_USAGE_IMMUTABLE); D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 }; - m_quad = CreateBufferShared(&bd, &srd); - CHECK(m_quad, "create xfb encode quad vertex buffer"); + hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad); + CHECK(SUCCEEDED(hr), "create xfb encode quad vertex buffer"); D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer"); // Create vertex shader - SharedPtr bytecode; - m_vShader = D3D::CompileAndCreateVertexShader(XFB_ENCODE_VS, sizeof(XFB_ENCODE_VS), std::addressof(bytecode)); - CHECK(m_vShader, "compile/create xfb encode vertex shader"); + + D3DBlob* bytecode = NULL; + if (!D3D::CompileVertexShader(XFB_ENCODE_VS, sizeof(XFB_ENCODE_VS), &bytecode)) + { + ERROR_LOG(VIDEO, "XFB encode vertex shader failed to compile"); + return; + } + + hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), NULL, &m_vShader); + CHECK(SUCCEEDED(hr), "create xfb encode vertex shader"); D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader"); // Create input layout for vertex quad using bytecode from vertex shader - m_quadLayout = CreateInputLayoutShared(QUAD_LAYOUT_DESC, - sizeof(QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC), - bytecode->GetBufferPointer(), bytecode->GetBufferSize()); - CHECK(m_quadLayout, "create xfb encode quad vertex layout"); + + hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC, + sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC), + bytecode->Data(), bytecode->Size(), &m_quadLayout); + CHECK(SUCCEEDED(hr), "create xfb encode quad vertex layout"); D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout"); + bytecode->Release(); + // Create pixel shader + m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS, sizeof(XFB_ENCODE_PS)); if (!m_pShader) { @@ -217,44 +235,52 @@ XFBEncoder::XFBEncoder() // Create blend state - auto bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); - m_xfbEncodeBlendState = CreateBlendStateShared(&bld); - CHECK(m_xfbEncodeBlendState, "create xfb encode blend state"); + D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); + hr = D3D::device->CreateBlendState(&bld, &m_xfbEncodeBlendState); + CHECK(SUCCEEDED(hr), "create xfb encode blend state"); D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state"); // Create depth state - auto dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT()); + D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT()); dsd.DepthEnable = FALSE; - hr = D3D::g_device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState); + hr = D3D::device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState); CHECK(SUCCEEDED(hr), "create xfb encode depth state"); D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state"); // Create rasterizer state - auto rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); + D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); rd.CullMode = D3D11_CULL_NONE; rd.DepthClipEnable = FALSE; - hr = D3D::g_device->CreateRasterizerState(&rd, &m_xfbEncodeRastState); + hr = D3D::device->CreateRasterizerState(&rd, &m_xfbEncodeRastState); CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state"); D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state"); // Create EFB texture sampler - auto sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); + D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); // FIXME: Should we really use point sampling here? sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - hr = D3D::g_device->CreateSamplerState(&sd, &m_efbSampler); + hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler); CHECK(SUCCEEDED(hr), "create xfb encode texture sampler"); D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler"); } -XFBEncoder::~XFBEncoder() +void XFBEncoder::Shutdown() { SAFE_RELEASE(m_efbSampler); SAFE_RELEASE(m_xfbEncodeRastState); SAFE_RELEASE(m_xfbEncodeDepthState); + SAFE_RELEASE(m_xfbEncodeBlendState); + SAFE_RELEASE(m_pShader); + SAFE_RELEASE(m_quadLayout); + SAFE_RELEASE(m_vShader); + SAFE_RELEASE(m_quad); + SAFE_RELEASE(m_encodeParams); + SAFE_RELEASE(m_outStage); SAFE_RELEASE(m_outRTV); + SAFE_RELEASE(m_out); } void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma) @@ -267,8 +293,8 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR // Set up all the state for XFB encoding - D3D::g_context->PSSetShader(m_pShader, NULL, 0); - D3D::g_context->VSSetShader(m_vShader, NULL, 0); + D3D::context->PSSetShader(m_pShader, NULL, 0); + D3D::context->VSSetShader(m_vShader, NULL, 0); D3D::stateman->PushBlendState(m_xfbEncodeBlendState); D3D::stateman->PushDepthState(m_xfbEncodeDepthState); @@ -276,13 +302,13 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR D3D::stateman->Apply(); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(width/2), FLOAT(height)); - D3D::g_context->RSSetViewports(1, &vp); + D3D::context->RSSetViewports(1, &vp); - D3D::g_context->IASetInputLayout(m_quadLayout); - D3D::g_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + D3D::context->IASetInputLayout(m_quadLayout); + D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); UINT stride = sizeof(QuadVertex); UINT offset = 0; - D3D::g_context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset); + D3D::context->IASetVertexBuffers(0, 1, &m_quad, &stride, &offset); TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(srcRect); @@ -294,50 +320,50 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR params.TexRight = FLOAT(targetRect.right) / g_renderer->GetTargetWidth(); params.TexBottom = FLOAT(targetRect.bottom) / g_renderer->GetTargetHeight(); params.Gamma = gamma; - D3D::g_context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0); + D3D::context->UpdateSubresource(m_encodeParams, 0, NULL, ¶ms, 0, 0); - D3D::g_context->VSSetConstantBuffers(0, 1, &m_encodeParams); + D3D::context->VSSetConstantBuffers(0, 1, &m_encodeParams); - D3D::g_context->OMSetRenderTargets(1, &m_outRTV, NULL); + D3D::context->OMSetRenderTargets(1, &m_outRTV, NULL); ID3D11ShaderResourceView* pEFB = FramebufferManager::GetEFBColorTexture()->GetSRV(); - D3D::g_context->PSSetConstantBuffers(0, 1, &m_encodeParams); - D3D::g_context->PSSetShaderResources(0, 1, &pEFB); - D3D::g_context->PSSetSamplers(0, 1, &m_efbSampler); + D3D::context->PSSetConstantBuffers(0, 1, &m_encodeParams); + D3D::context->PSSetShaderResources(0, 1, &pEFB); + D3D::context->PSSetSamplers(0, 1, &m_efbSampler); // Encode! - D3D::g_context->Draw(4, 0); + D3D::context->Draw(4, 0); // Copy to staging buffer D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, width/2, height, 1); - D3D::g_context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); + D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); // Clean up state IUnknown* nullDummy = NULL; - D3D::g_context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy); - D3D::g_context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy); - D3D::g_context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); + D3D::context->PSSetSamplers(0, 1, (ID3D11SamplerState**)&nullDummy); + D3D::context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&nullDummy); + D3D::context->PSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); - D3D::g_context->OMSetRenderTargets(0, NULL, NULL); + D3D::context->OMSetRenderTargets(0, NULL, NULL); - D3D::g_context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); + D3D::context->VSSetConstantBuffers(0, 1, (ID3D11Buffer**)&nullDummy); D3D::stateman->PopRasterizerState(); D3D::stateman->PopDepthState(); D3D::stateman->PopBlendState(); - D3D::g_context->PSSetShader(NULL, NULL, 0); - D3D::g_context->VSSetShader(NULL, NULL, 0); + D3D::context->PSSetShader(NULL, NULL, 0); + D3D::context->VSSetShader(NULL, NULL, 0); // Transfer staging buffer to GameCube/Wii RAM D3D11_MAPPED_SUBRESOURCE map = { 0 }; - hr = D3D::g_context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); + hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); CHECK(SUCCEEDED(hr), "map staging buffer"); u8* src = (u8*)map.pData; @@ -348,12 +374,12 @@ void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcR src += map.RowPitch; } - D3D::g_context->Unmap(m_outStage, 0); + D3D::context->Unmap(m_outStage, 0); // Restore API g_renderer->RestoreAPIState(); - D3D::g_context->OMSetRenderTargets(1, + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.h b/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.h index 69e1249900..000c833dbf 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/XFBEncoder.h @@ -20,32 +20,47 @@ #include "VideoCommon.h" -#include "D3DUtil.h" +struct ID3D11Texture2D; +struct ID3D11RenderTargetView; +struct ID3D11Buffer; +struct ID3D11VertexShader; +struct ID3D11PixelShader; +struct ID3D11InputLayout; +struct ID3D11BlendState; +struct ID3D11DepthStencilState; +struct ID3D11RasterizerState; +struct ID3D11SamplerState; namespace DX11 { class XFBEncoder { + public: + XFBEncoder(); - ~XFBEncoder(); + + void Init(); + void Shutdown(); void Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma); private: - SharedPtr m_out; + + ID3D11Texture2D* m_out; ID3D11RenderTargetView* m_outRTV; - SharedPtr m_outStage; - SharedPtr m_encodeParams; - SharedPtr m_quad; - SharedPtr m_vShader; - SharedPtr m_quadLayout; - SharedPtr m_pShader; - SharedPtr m_xfbEncodeBlendState; + ID3D11Texture2D* m_outStage; + ID3D11Buffer* m_encodeParams; + ID3D11Buffer* m_quad; + ID3D11VertexShader* m_vShader; + ID3D11InputLayout* m_quadLayout; + ID3D11PixelShader* m_pShader; + ID3D11BlendState* m_xfbEncodeBlendState; ID3D11DepthStencilState* m_xfbEncodeDepthState; ID3D11RasterizerState* m_xfbEncodeRastState; ID3D11SamplerState* m_efbSampler; + }; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index dc761ec082..0c975f5fa4 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -115,8 +115,9 @@ void InitBackendInfo() if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter) { char buf[32]; - auto const modes = DX11::D3D::EnumAAModes(ad); - for (size_t i = 0; i < modes.size(); ++i) + std::vector modes; + modes = DX11::D3D::EnumAAModes(ad); + 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); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 1a7b61db0f..c168ffc69b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -66,16 +66,12 @@ static LPDIRECT3DPIXELSHADER9 s_ClearProgram = NULL; static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL; static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL; -class PixelShaderCacheInserter +class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - template - void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const + void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size) { - std::unique_ptr value(new u8[value_size]); - get_data(value.get()); - - PixelShaderCache::InsertByteCode(key, value.get(), value_size, false); + PixelShaderCache::InsertByteCode(key, value, value_size, false); } }; @@ -285,8 +281,8 @@ void PixelShaderCache::Init() char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - - g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter()); + PixelShaderCacheInserter inserter; + g_ps_disk_cache.OpenAndRead(cache_filename, inserter); } // ONLY to be used during shutdown. diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 49ed34443f..e5c889b54b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -57,16 +57,12 @@ LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() } // this class will load the precompiled shaders into our cache -class VertexShaderCacheInserter +class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - template - void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const + void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size) { - std::unique_ptr value(new u8[value_size]); - get_data(value.get()); - - VertexShaderCache::InsertByteCode(key, value.get(), value_size, false); + VertexShaderCache::InsertByteCode(key, value, value_size, false); } }; @@ -152,9 +148,9 @@ void VertexShaderCache::Init() char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - - g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter()); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + VertexShaderCacheInserter inserter; + g_vs_disk_cache.OpenAndRead(cache_filename, inserter); } void VertexShaderCache::Clear()