From 5632330bee4ad7125676425cc530195af784f342 Mon Sep 17 00:00:00 2001 From: chambriat Date: Thu, 17 Mar 2016 15:18:07 +0100 Subject: [PATCH] Improve interface and handle filtering & wrapping --- src/SubPic/ISubPic.h | 4 +- src/SubPic/SubPicAllocatorPresenterImpl.h | 4 +- .../VideoRenderers/DX9AllocatorPresenter.cpp | 8 +- .../VideoRenderers/DX9AllocatorPresenter.h | 5 +- .../VideoRenderers/DX9RenderingEngine.cpp | 87 ++++++++++--------- .../VideoRenderers/DX9RenderingEngine.h | 12 ++- src/mpc-hc/MainFrm.cpp | 17 ++-- src/mpc-hc/Shaders.cpp | 74 ++++++++++------ src/mpc-hc/Shaders.h | 20 +++-- 9 files changed, 128 insertions(+), 103 deletions(-) diff --git a/src/SubPic/ISubPic.h b/src/SubPic/ISubPic.h index 6b377a8781b..298972d043e 100644 --- a/src/SubPic/ISubPic.h +++ b/src/SubPic/ISubPic.h @@ -234,6 +234,6 @@ public IPersist { interface __declspec(uuid("212C1425-F407-4FF6-B0A0-8335FA46ABA8")) ISubPicShaderPresenter : public IUnknown { - STDMETHOD(SetShaderTexture)(int registerId, const CString& path, bool bScreenSpace) PURE; - STDMETHOD(SetShaderFloat4)(int registerId, const float values[4], bool bScreenSpace) PURE; + STDMETHOD(SetPixelShaderTexture)(int registerId, const CString& path, int filter, int wrap) PURE; + STDMETHOD(SetPixelShaderParameter)(int registerId, const float values[4]) PURE; }; diff --git a/src/SubPic/SubPicAllocatorPresenterImpl.h b/src/SubPic/SubPicAllocatorPresenterImpl.h index e14deed0512..1c2f6e3c09a 100644 --- a/src/SubPic/SubPicAllocatorPresenterImpl.h +++ b/src/SubPic/SubPicAllocatorPresenterImpl.h @@ -157,11 +157,11 @@ class CSubPicAllocatorPresenterImpl // ISubPicShaderPresenter - STDMETHODIMP SetShaderTexture(int registerId, const CString& path, bool bScreenSpace) { + STDMETHODIMP SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap) { return E_NOTIMPL; } - STDMETHODIMP SetShaderFloat4(int registerId, const float values[4], bool bScreenSpace) { + STDMETHODIMP SetPixelShaderParameter(int registerId, const float values[4]) { return E_NOTIMPL; } }; diff --git a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp index 377ec4938a1..e061a86eb29 100644 --- a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp +++ b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp @@ -2288,16 +2288,16 @@ STDMETHODIMP CDX9AllocatorPresenter::GetD3DFullscreen(bool* pfEnabled) return S_OK; } -STDMETHODIMP CDX9AllocatorPresenter::SetShaderTexture(int registerId, const CString& path, bool bScreenSpace) +STDMETHODIMP CDX9AllocatorPresenter::SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap) { CAutoLock cRenderLock(&m_RenderLock); - return SetCustomShaderTexture(registerId, path, bScreenSpace); + return SetCustomPixelShaderTexture(registerId, path, filter, wrap); } -STDMETHODIMP CDX9AllocatorPresenter::SetShaderFloat4(int registerId, const float values[4], bool bScreenSpace) +STDMETHODIMP CDX9AllocatorPresenter::SetPixelShaderParameter(int registerId, const float values[4]) { CAutoLock cRenderLock(&m_RenderLock); - return SetCustomShaderParameter(registerId, values, bScreenSpace); + return SetCustomPixelShaderParameter(registerId, values); } diff --git a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.h b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.h index 1eb2e19ac08..c4a896a2261 100644 --- a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.h +++ b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.h @@ -310,8 +310,7 @@ namespace DSObjects STDMETHODIMP GetD3DFullscreen(bool* pfEnabled); // ISubPicShaderPresenter - - STDMETHODIMP SetShaderTexture(int registerId, const CString& path, bool bScreenSpace); - STDMETHODIMP SetShaderFloat4(int registerId, const float values[4], bool bScreenSpace); + STDMETHODIMP SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap); + STDMETHODIMP SetPixelShaderParameter(int registerId, const float values[4]); }; } diff --git a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp index d74359acb30..019167710ff 100644 --- a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp +++ b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp @@ -1720,64 +1720,45 @@ HRESULT CDX9RenderingEngine::SetCustomPixelShader(LPCSTR pSrcData, LPCSTR pTarge return E_INVALIDARG; } - CAutoPtr pShader; - pShader.Attach(DEBUG_NEW CExternalPixelShader()); - pShader->m_SourceData = pSrcData; - pShader->m_SourceTarget = pTarget; + CAutoPtr shader; + shader.Attach(DEBUG_NEW CExternalPixelShader()); + shader->m_SourceData = pSrcData; + shader->m_SourceTarget = pTarget; - HRESULT hr = pShader->Compile(m_pPSC); + HRESULT hr = shader->Compile(m_pPSC); if (FAILED(hr)) { return hr; } - pPixelShaders->AddTail(pShader); + m_LatestCustomPixelShader = shader; + pPixelShaders->AddTail(shader); Paint(false); return S_OK; } -HRESULT CDX9RenderingEngine::SetCustomShaderTexture(int registerId, const CString& path, bool bScreenSpace) +HRESULT CDX9RenderingEngine::SetCustomPixelShaderTexture(int registerId, const CString& path, int filter, int wrap) { - CAutoPtrList* pPixelShaders; - if (bScreenSpace) { - pPixelShaders = &m_pCustomScreenSpacePixelShaders; - } else { - pPixelShaders = &m_pCustomPixelShaders; - } - - if (!pPixelShaders->IsEmpty()) { - CExternalPixelShader& shader = *pPixelShaders->GetTail(); - PixelShaderTexture texture; - texture.texture = LoadExternalTexture(path); - if (texture.texture == NULL) { - return E_FAIL; - } - texture.registerId = registerId; - shader.m_Textures.AddTail(texture); - return S_OK; + PixelShaderTexture texture; + texture.texture = LoadExternalTexture(path); + if (texture.texture == NULL) { + return E_FAIL; } - return E_FAIL; + texture.registerId = registerId; + texture.filter = filter; + texture.wrap = wrap; + m_LatestCustomPixelShader->m_Textures.AddTail(texture); + return S_OK; } -HRESULT CDX9RenderingEngine::SetCustomShaderParameter(int registerId, const float values[4], bool bScreenSpace) +HRESULT CDX9RenderingEngine::SetCustomPixelShaderParameter(int registerId, const float values[4]) { - CAutoPtrList* pPixelShaders; - if (bScreenSpace) { - pPixelShaders = &m_pCustomScreenSpacePixelShaders; - } else { - pPixelShaders = &m_pCustomPixelShaders; - } - - if (!pPixelShaders->IsEmpty()) { - CExternalPixelShader& shader = *pPixelShaders->GetTail(); - PixelShaderParameter parameter; - memcpy(parameter.values, values, sizeof(float) * 4); - parameter.registerId = registerId; - shader.m_Parameters.AddTail(parameter); - return S_OK; - } - return E_FAIL; + PixelShaderParameter parameter; + memcpy(parameter.values, values, sizeof(float) * 4); + parameter.registerId = registerId; + m_LatestCustomPixelShader->m_Parameters.AddTail(parameter); + return S_OK; } CDX9RenderingEngine::ExternalTexture* CDX9RenderingEngine::LoadExternalTexture(CString filePath) @@ -1863,6 +1844,28 @@ HRESULT CDX9RenderingEngine::CExternalPixelShader::Apply(IDirect3DDevice9* pD3DD if (res != S_OK) { return res; } + + if (texture.wrap == 1) { + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); + } else { + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + } + + if (texture.filter == 2) { + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + } else if (texture.filter == 3) { + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + } else { + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MINFILTER, D3DTEXF_POINT); + pD3DDev->SetSamplerState(texture.registerId, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + } } // Apply parameters diff --git a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.h b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.h index 400795967fe..a88e2f3c4c3 100644 --- a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.h +++ b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.h @@ -83,10 +83,11 @@ namespace DSObjects HRESULT AlphaBlt(const RECT* pSrc, const RECT* pDst, IDirect3DTexture9* pTexture); HRESULT SetCustomPixelShader(LPCSTR pSrcData, LPCSTR pTarget, bool bScreenSpace); - HRESULT SetCustomShaderTexture(int registerId, const CString& path, bool bScreenSpace); - HRESULT SetCustomShaderParameter(int registerId, const float values[4], bool bScreenSpace); + HRESULT SetCustomPixelShaderTexture(int registerId, const CString& path, int filter, int wrap); + HRESULT SetCustomPixelShaderParameter(int registerId, const float values[4]); private: + struct ExternalTexture { CComPtr pTexture; CTime timeStamp; @@ -100,13 +101,15 @@ namespace DSObjects void UpdateExternalTextures(); struct PixelShaderTexture { - ExternalTexture* texture; int registerId; + ExternalTexture* texture; + int filter; + int wrap; }; struct PixelShaderParameter { - float values[4]; int registerId; + float values[4]; }; class CExternalPixelShader @@ -128,6 +131,7 @@ namespace DSObjects CONST float* pIn, UINT n); + CExternalPixelShader* m_LatestCustomPixelShader; CAutoPtr m_pPSC; diff --git a/src/mpc-hc/MainFrm.cpp b/src/mpc-hc/MainFrm.cpp index 2767644c052..13b73c72e7e 100644 --- a/src/mpc-hc/MainFrm.cpp +++ b/src/mpc-hc/MainFrm.cpp @@ -10175,21 +10175,18 @@ bool CMainFrame::SetShaderListP2(const ShaderList& shaderList, bool bScreenSpace ISubPicShaderPresenter* pShaderPresenter = nullptr; m_pCAP2.QueryInterface(&pShaderPresenter); - m_pCAP2->SetPixelShader2(nullptr, nullptr, false); - for (const auto& shader : s.m_Shaders.GetCurrentPreset().GetPreResize()) { + m_pCAP2->SetPixelShader2(nullptr, nullptr, bScreenSpace); + for (const auto& shader : shaderList) { if (FAILED(m_pCAP2->SetPixelShader2(shader.GetCode(), nullptr, bScreenSpace))) { result = false; m_pCAP2->SetPixelShader2(nullptr, nullptr, bScreenSpace); break; } else if ((pShaderPresenter != nullptr)) { + for (const ShaderTexture& texture : shader.GetTextures()) { + pShaderPresenter->SetPixelShaderTexture(texture.id, texture.path, texture.filter, texture.wrap); + } for (const ShaderParameter& param : shader.GetParameters()) { - switch (param.type) { - case ShaderParameter::TYPE_TEXTURE: - pShaderPresenter->SetShaderTexture(param.id, param.path, bScreenSpace); - break; - case ShaderParameter::TYPE_FLOAT4: - pShaderPresenter->SetShaderFloat4(param.id, param.values, bScreenSpace); - } + pShaderPresenter->SetPixelShaderParameter(param.id, param.values); } } } @@ -10216,7 +10213,7 @@ void CMainFrame::SetShaders(bool bSetPreResize/* = true*/, bool bSetPostResize/* preFailed = !SetShaderListP2(s.m_Shaders.GetCurrentPreset().GetPreResize(), false); } if (bSetPostResize) { - postFailed = !SetShaderListP2(s.m_Shaders.GetCurrentPreset().GetPostResize(), false); + postFailed = !SetShaderListP2(s.m_Shaders.GetCurrentPreset().GetPostResize(), true); } } else if (m_pCAP) { // shouldn't happen, all knows renderers that support ISubPicAllocatorPresenter interface diff --git a/src/mpc-hc/Shaders.cpp b/src/mpc-hc/Shaders.cpp index cdbbf6774c6..5ff311d185b 100644 --- a/src/mpc-hc/Shaders.cpp +++ b/src/mpc-hc/Shaders.cpp @@ -74,6 +74,11 @@ const std::vector& Shader::GetPathes() const return m_Pathes; } +const std::vector& Shader::GetTextures() const +{ + return m_Textures; +} + const std::vector& Shader::GetParameters() const { return m_Parameters; @@ -83,6 +88,7 @@ void Shader::Reload() { m_Code.clear(); m_Pathes.clear(); + m_Textures.clear(); m_Parameters.clear(); Load(m_FilePath); @@ -147,71 +153,85 @@ bool Shader::Load(const CString& path) } m_Code += '\n'; } - return LoadParameters(path); + return LoadConfig(path); } -bool Shader::LoadParameters(const CString& path) +bool Shader::LoadConfig(const CString& path) { CString folder = PathUtils::DirName(path); - CString paramsPath = PathUtils::CombinePaths(folder, PathUtils::FileName(path) + SHADERS_CFG); - if (!PathUtils::IsFile(paramsPath)) { + CString configPath = PathUtils::CombinePaths(folder, PathUtils::FileName(path) + SHADERS_CFG); + if (!PathUtils::IsFile(configPath)) { return true; } - const std::string filePath = CT2CA(paramsPath); + const std::string filePath = CT2CA(configPath); - m_Pathes.push_back(paramsPath); + m_Pathes.push_back(configPath); CFile file; - if (!file.Open(paramsPath, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary) || file.GetLength() > SHADER_MAX_FILE_SIZE) { + if (!file.Open(configPath, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary) || file.GetLength() > SHADER_MAX_FILE_SIZE) { Log("failed to access : " + filePath); return false; } - CArray content; - content.SetSize(file.GetLength() + 1); - content.GetAt(file.GetLength()) = 0; - - if (file.Read(content.GetData(), file.GetLength()) != file.GetLength()) { + std::string content; + content.resize(file.GetLength()); + if (file.Read(&content[0], file.GetLength()) != file.GetLength()) { Log("failed to read : " + filePath); return false; } + if (!StripComments(content)) { + Log("invalid comments : " + filePath); + return false; + } + rapidjson::Document document; - if (document.Parse(content.GetData()).HasParseError()) { + if (document.Parse(content.c_str()).HasParseError()) { Log(filePath + " : " + rapidjson::GetParseError_En(document.GetParseError())); return false; } for (rapidjson::Value::ConstMemberIterator member = document.MemberBegin(); member != document.MemberEnd(); ++member) { if (member->name == "texture") { - rapidjson::Value::ConstMemberIterator path = member->value.FindMember("path"); rapidjson::Value::ConstMemberIterator id = member->value.FindMember("id"); + rapidjson::Value::ConstMemberIterator path = member->value.FindMember("path"); if (path != member->value.MemberEnd() && id != member->value.MemberEnd()) { - ShaderParameter param; - param.type = ShaderParameter::TYPE_TEXTURE; - param.id = id->value.GetInt(); - param.path = path->value.GetString(); - param.path.Replace(_T("/"), _T("\\")); + ShaderTexture texture; + texture.id = id->value.GetInt(); + texture.path = path->value.GetString(); + texture.path.Replace(_T("/"), _T("\\")); - if (PathUtils::IsFile(param.path)) { - m_Pathes.push_back(param.path); + if (PathUtils::IsFile(texture.path)) { + m_Pathes.push_back(texture.path); } else { - CString texturePath = PathUtils::CombinePaths(folder, param.path); + CString texturePath = PathUtils::CombinePaths(folder, texture.path); if (PathUtils::IsFile(CString(texturePath))) { - param.path = texturePath; - m_Pathes.push_back(param.path); + texture.path = texturePath; + m_Pathes.push_back(texture.path); } else { - Log(std::string(CT2CA(param.path)) + " not found"); + Log(std::string(CT2CA(texture.path)) + " not found"); } } - m_Parameters.push_back(param); + texture.filter = 3; + texture.wrap = 0; + + rapidjson::Value::ConstMemberIterator filter = member->value.FindMember("filter"); + if (filter != member->value.MemberEnd()) { + texture.filter = filter->value.GetInt(); + } + + rapidjson::Value::ConstMemberIterator wrap = member->value.FindMember("wrap"); + if (wrap != member->value.MemberEnd()) { + texture.wrap = filter->value.GetInt(); + } + + m_Textures.push_back(texture); } } else if (member->name == "float4") { rapidjson::Value::ConstMemberIterator values = member->value.FindMember("values"); rapidjson::Value::ConstMemberIterator id = member->value.FindMember("id"); if (values != member->value.MemberEnd() && values->value.IsArray() && values->value.Size() == 4 && id != member->value.MemberEnd()) { ShaderParameter param; - param.type = ShaderParameter::TYPE_FLOAT4; param.id = id->value.GetInt(); memset(param.values, 0, sizeof(float) * 4); diff --git a/src/mpc-hc/Shaders.h b/src/mpc-hc/Shaders.h index 12670c7ac09..be279579f02 100644 --- a/src/mpc-hc/Shaders.h +++ b/src/mpc-hc/Shaders.h @@ -29,16 +29,16 @@ #include "EventDispatcher.h" -struct ShaderParameter { - enum TYPE { - TYPE_TEXTURE, - TYPE_FLOAT4 - }; - - TYPE type; +struct ShaderTexture { + int id; CString path; - float values[4]; + int filter; + int wrap; +}; + +struct ShaderParameter { int id; + float values[4]; }; class Shader @@ -53,6 +53,7 @@ class Shader const CString& GetFilePath() const; const CStringA GetCode() const; const std::vector& GetPathes() const; + const std::vector& GetTextures() const; const std::vector& GetParameters() const; void Reload(); @@ -60,7 +61,7 @@ class Shader private: bool Load(const CString& path); - bool LoadParameters(const CString& path); + bool LoadConfig(const CString& path); bool StripComments(std::string& code) const; void Log(std::string message); @@ -68,6 +69,7 @@ class Shader CString m_FilePath; std::string m_Code; std::vector m_Pathes; + std::vector m_Textures; std::vector m_Parameters; };