diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj index da59800ec8..af6fc88931 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj @@ -91,7 +91,7 @@ + + + + diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp index ec9716a7f0..c6f146e751 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp @@ -106,10 +106,10 @@ EmuGfxState::~EmuGfxState() } // TODO: No need to store the whole bytecode, signature might be enough (?) -void EmuGfxState::SetVShader(ID3D11VertexShader* shader, ID3D10Blob* bcode) +void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode) { // TODO: vshaderchanged actually just needs to be true if the signature changed - if (bcode && vsbytecode != bcode->GetBufferPointer()) vshaderchanged = true; + if (bcode && vsbytecode != bcode) vshaderchanged = true; SAFE_RELEASE(vsbytecode); SAFE_RELEASE(vertexshader); @@ -164,7 +164,7 @@ void EmuGfxState::ApplyState() if (vshaderchanged) { if (inp_layout) inp_layout->Release(); - hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->GetBufferPointer(), vsbytecode->GetBufferSize(), &inp_layout); + hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout); if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState"); vshaderchanged = false; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h index 06a219a990..7a5f7b166e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h @@ -17,20 +17,9 @@ #pragma once -#include -#include - #include - #include "Common.h" - -#include -#include -#include -using std::vector; -using std::list; -using std::map; -using std::pair; +#include "D3DBlob.h" #define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; } @@ -41,9 +30,9 @@ namespace D3D HRESULT Create(HWND wnd); void Close(); -extern ID3D11Device *device; -extern ID3D11DeviceContext *context; -extern IDXGISwapChain *swapchain; +extern ID3D11Device* device; +extern ID3D11DeviceContext* context; +extern IDXGISwapChain* swapchain; extern bool bFrameInProgress; void Reset(); @@ -54,13 +43,13 @@ void Present(); unsigned int GetBackBufferWidth(); unsigned int GetBackBufferHeight(); D3DTexture2D* &GetBackBuffer(); -const char *PixelShaderVersionString(); -const char *VertexShaderVersionString(); +const char* PixelShaderVersionString(); +const char* VertexShaderVersionString(); // Ihis function will assign a name to the given resource. // The DirectX debug layer will make it easier to identify resources that way, // e.g. when listing up all resources who have unreleased references. -inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char *name) +inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name) { #if defined(_DEBUG) || defined(DEBUGFAST) resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name); @@ -74,10 +63,10 @@ public: EmuGfxState(); ~EmuGfxState(); - void SetVShader(ID3D11VertexShader *shader, ID3D10Blob *bcode); - void SetPShader(ID3D11PixelShader *shader); - void SetInputElements(const D3D11_INPUT_ELEMENT_DESC *elems, UINT num); - void SetShaderResource(int stage, ID3D11ShaderResourceView *srv); + void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode); + void SetPShader(ID3D11PixelShader* shader); + void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num); + void SetShaderResource(int stage, ID3D11ShaderResourceView* srv); void ApplyState(); // apply current state void AlphaPass(); // only modify the current state to enable the alpha pass @@ -126,9 +115,9 @@ public: private: ID3D11VertexShader* vertexshader; - ID3D10Blob* vsbytecode; + D3DBlob* vsbytecode; ID3D11PixelShader* pixelshader; - ID3D10Blob* psbytecode; + D3DBlob* psbytecode; bool vshaderchanged; ID3D11Buffer* vscbuf; @@ -142,6 +131,6 @@ private: D3D11_BLEND_DESC blenddesc; }; -extern EmuGfxState *gfxstate; +extern EmuGfxState* gfxstate; } // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp new file mode 100644 index 0000000000..579487aa53 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.cpp @@ -0,0 +1,63 @@ +// 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 "D3DBlob.h" + +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 = 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; +} diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h new file mode 100644 index 0000000000..fabfdf4b53 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBlob.h @@ -0,0 +1,47 @@ +// 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 +#include "Common.h" + +// 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; +}; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp index e06b53d378..2cde29a35d 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp @@ -39,7 +39,7 @@ ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int } // code->bytecode -bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob) +bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob) { ID3D10Blob* shaderBuffer = NULL; ID3D10Blob* errorBuffer = NULL; @@ -52,7 +52,7 @@ bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob) HRESULT hr = D3DCompile(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer); - if (FAILED(hr)) + if (FAILED(hr) || errorBuffer) { std::string msg = (char*)errorBuffer->GetBufferPointer(); msg += "\n\n"; @@ -60,11 +60,13 @@ bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob) MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR); *blob = NULL; + errorBuffer->Release(); + } + else + { + *blob = new D3DBlob(shaderBuffer); + shaderBuffer->Release(); } - else *blob = shaderBuffer; - - //cleanup - if (errorBuffer) errorBuffer->Release(); return SUCCEEDED(hr); } @@ -82,7 +84,7 @@ ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int le } // code->bytecode -bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob) +bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob) { ID3D10Blob* shaderBuffer = NULL; ID3D10Blob* errorBuffer = NULL; @@ -95,7 +97,7 @@ bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob) HRESULT hr = D3DCompile(code, len, NULL, NULL, NULL, "main", D3D::PixelShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer); - if (FAILED(hr)) + if (FAILED(hr) || errorBuffer) { std::string msg = (char*)errorBuffer->GetBufferPointer(); msg += "\n\n"; @@ -103,17 +105,19 @@ bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob) MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR); *blob = NULL; + errorBuffer->Release(); + } + else + { + *blob = new D3DBlob(shaderBuffer); + shaderBuffer->Release(); } - else *blob = shaderBuffer; - - // cleanup - if (errorBuffer) errorBuffer->Release(); return SUCCEEDED(hr); } ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len) { - ID3D10Blob* blob = NULL; + D3DBlob* blob = NULL; if (CompileVertexShader(code, len, &blob)) { ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob); @@ -126,7 +130,7 @@ ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len) { - ID3D10Blob* blob = NULL; + D3DBlob* blob = NULL; CompilePixelShader(code, len, &blob); if (blob) { diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h index 1c3e014da5..737a10dff7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.h @@ -25,15 +25,15 @@ namespace D3D ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len); // The returned bytecode buffers should be Release()d. - bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob); - bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob); + bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob); + bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob); // Utility functions ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len); ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len); - inline ID3D11VertexShader* CreateVertexShaderFromByteCode(ID3D10Blob* bytecode) { return CreateVertexShaderFromByteCode(bytecode->GetBufferPointer(), bytecode->GetBufferSize()); } - inline ID3D11PixelShader* CreatePixelShaderFromByteCode(ID3D10Blob* bytecode) { return CreatePixelShaderFromByteCode(bytecode->GetBufferPointer(), bytecode->GetBufferSize()); } - inline ID3D11VertexShader* CompileAndCreateVertexShader(ID3D10Blob* code) { return CompileAndCreateVertexShader((const char*)code->GetBufferPointer(), code->GetBufferSize()); } - inline ID3D11PixelShader* CompileAndCreatePixelShader(ID3D10Blob* code) { return CompileAndCreatePixelShader((const char*)code->GetBufferPointer(), code->GetBufferSize()); } + inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode) { return CreateVertexShaderFromByteCode(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 ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code) { return CompileAndCreatePixelShader((const char*)code->Data(), code->Size()); } } \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp index ba2a87d582..7dd8f754cc 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp @@ -206,7 +206,7 @@ int CD3DFont::Init() m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader, sizeof(fontpixshader)); if (m_pshader == NULL) PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__); - ID3D10Blob* vsbytecode; + 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); @@ -218,7 +218,7 @@ 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 }, }; - hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode->GetBufferPointer(), vsbytecode->GetBufferSize(), &m_InputLayout); + 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__); vsbytecode->Release(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 60d1813105..265dc76a7a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -237,7 +237,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha) // need to compile a new shader const char* code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), dstAlpha, API_D3D11); - ID3D10Blob* pbytecode; + D3DBlob* pbytecode; if (!D3D::CompilePixelShader(code, strlen(code), &pbytecode)) { PanicAlert("Failed to compile Pixel Shader:\n\n%s", code); @@ -245,10 +245,10 @@ bool PixelShaderCache::SetShader(bool dstAlpha) } // insert the bytecode into the caches - g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->GetBufferPointer(), pbytecode->GetBufferSize()); + g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size()); g_ps_disk_cache.Sync(); - bool result = InsertByteCode(uid, pbytecode->GetBufferPointer(), pbytecode->GetBufferSize()); + bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size()); D3D::gfxstate->SetPShader(last_entry->shader); pbytecode->Release(); return result; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index db9ed0e82d..bb19b3bb58 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -93,9 +93,7 @@ public: } memcpy(&uid, key, key_size); - ID3D10Blob* blob; - D3D10CreateBlob(value_size, &blob); - memcpy(blob->GetBufferPointer(), value, value_size); + D3DBlob* blob = new D3DBlob(value_size, value); VertexShaderCache::InsertByteCode(uid, blob); blob->Release(); } @@ -144,15 +142,15 @@ void VertexShaderCache::Init() { "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - ID3D10Blob* blob; + D3DBlob* blob; D3D::CompileVertexShader(simple_shader_code, strlen(simple_shader_code), &blob); - D3D::device->CreateInputLayout(simpleelems, 2, blob->GetBufferPointer(), blob->GetBufferSize(), &SimpleLayout); + D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout); SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); D3D::CompileVertexShader(clear_shader_code, (int)strlen(clear_shader_code), &blob); - D3D::device->CreateInputLayout(clearelems, 2, blob->GetBufferPointer(), blob->GetBufferSize(), &ClearLayout); + D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout); ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); @@ -226,7 +224,7 @@ bool VertexShaderCache::SetShader(u32 components) const char* code = GenerateVertexShaderCode(components, API_D3D11); - ID3D10Blob* pbytecode = NULL; + D3DBlob* pbytecode = NULL; D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode); if (pbytecode == NULL) @@ -234,7 +232,7 @@ bool VertexShaderCache::SetShader(u32 components) PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code); return false; } - g_vs_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->GetBufferPointer(), pbytecode->GetBufferSize()); + g_vs_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size()); g_vs_disk_cache.Sync(); bool result = InsertByteCode(uid, pbytecode); @@ -243,12 +241,12 @@ bool VertexShaderCache::SetShader(u32 components) return result; } -bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, ID3D10Blob* bcodeblob) +bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob) { 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; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h index 7005f822cd..9c3a0e914f 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h @@ -41,17 +41,17 @@ public: static ID3D11InputLayout* GetSimpleInputLayout(); static ID3D11InputLayout* GetClearInputLayout(); - static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, ID3D10Blob* bcodeblob); + static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob); private: struct VSCacheEntry { ID3D11VertexShader* shader; - ID3D10Blob* bytecode; // needed to initialize the input layout + D3DBlob* bytecode; // needed to initialize the input layout int frameCount; VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {} - void SetByteCode(ID3D10Blob* blob) + void SetByteCode(D3DBlob* blob) { if (bytecode) bytecode->Release(); bytecode = blob;