Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Add shader settings support in external .json #163

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/mpc-hc_config.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef ISPP_INVOKED
/*
* (C) 2013-2015 see Authors.txt
* (C) 2013-2016 see Authors.txt
*
* This file is part of MPC-HC.
*
Expand Down Expand Up @@ -46,6 +46,7 @@

#define SHADERS_DIR _T("Shaders")
#define SHADERS_EXT _T(".hlsl")
#define SHADERS_CFG _T(".json")

// If this is enabled, the registered LAV Filters can be loaded as internal filters
#define ENABLE_LOAD_EXTERNAL_LAVF_AS_INTERNAL 0
Expand Down
10 changes: 10 additions & 0 deletions src/SubPic/ISubPic.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,13 @@ public IPersist {
// TODO: get rid of IPersist to identify type and use only
// interface functions to modify the settings of the substream
};

//
// ISubPicShaderPresenter
//
interface __declspec(uuid("212C1425-F407-4FF6-B0A0-8335FA46ABA8"))
ISubPicShaderPresenter :
public IUnknown {
STDMETHOD(SetPixelShaderTexture)(int registerId, const CString& path, int filter, int wrap) PURE;
STDMETHOD(SetPixelShaderParameter)(int registerId, const float values[4]) PURE;
};
1 change: 1 addition & 0 deletions src/SubPic/SubPicAllocatorPresenterImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ STDMETHODIMP CSubPicAllocatorPresenterImpl::NonDelegatingQueryInterface(REFIID r
QI(ISubRenderOptions)
QI(ISubRenderConsumer)
QI(ISubRenderConsumer2)
QI(ISubPicShaderPresenter)
__super::NonDelegatingQueryInterface(riid, ppv);
}

Expand Down
11 changes: 11 additions & 0 deletions src/SubPic/SubPicAllocatorPresenterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class CSubPicAllocatorPresenterImpl
, public CCritSec
, public ISubPicAllocatorPresenter2
, public ISubRenderConsumer2
, public ISubPicShaderPresenter
{
private:
CCritSec m_csSubPicProvider;
Expand Down Expand Up @@ -153,4 +154,14 @@ class CSubPicAllocatorPresenterImpl
// ISubRenderConsumer2

STDMETHODIMP Clear(REFERENCE_TIME clearNewerThan = 0);

// ISubPicShaderPresenter

STDMETHODIMP SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap) {
return E_NOTIMPL;
}

STDMETHODIMP SetPixelShaderParameter(int registerId, const float values[4]) {
return E_NOTIMPL;
}
};
14 changes: 14 additions & 0 deletions src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2287,3 +2287,17 @@ STDMETHODIMP CDX9AllocatorPresenter::GetD3DFullscreen(bool* pfEnabled)
*pfEnabled = m_bIsFullscreen;
return S_OK;
}

STDMETHODIMP CDX9AllocatorPresenter::SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap)
{
CAutoLock cRenderLock(&m_RenderLock);

return SetCustomPixelShaderTexture(registerId, path, filter, wrap);
}

STDMETHODIMP CDX9AllocatorPresenter::SetPixelShaderParameter(int registerId, const float values[4])
{
CAutoLock cRenderLock(&m_RenderLock);

return SetCustomPixelShaderParameter(registerId, values);
}
6 changes: 5 additions & 1 deletion src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
* (C) 2006-2015 see Authors.txt
* (C) 2006-2016 see Authors.txt
*
* This file is part of MPC-HC.
*
Expand Down Expand Up @@ -308,5 +308,9 @@ namespace DSObjects
// ID3DFullscreenControl
STDMETHODIMP SetD3DFullscreen(bool fEnabled);
STDMETHODIMP GetD3DFullscreen(bool* pfEnabled);

// ISubPicShaderPresenter
STDMETHODIMP SetPixelShaderTexture(int registerId, const CString& path, int filter, int wrap);
STDMETHODIMP SetPixelShaderParameter(int registerId, const float values[4]);
};
}
176 changes: 161 additions & 15 deletions src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) 2006-2015 see Authors.txt
* (C) 2006-2016 see Authors.txt
*
* This file is part of MPC-HC.
*
Expand Down Expand Up @@ -192,6 +192,8 @@ void CDX9RenderingEngine::InitRenderingEngine()

void CDX9RenderingEngine::CleanupRenderingEngine()
{
DestroyExternalTextures();

m_pPSC.Free();

for (int i = 0; i < 4; i++) {
Expand All @@ -202,12 +204,12 @@ void CDX9RenderingEngine::CleanupRenderingEngine()

POSITION pos = m_pCustomScreenSpacePixelShaders.GetHeadPosition();
while (pos) {
CExternalPixelShader& Shader = m_pCustomScreenSpacePixelShaders.GetNext(pos);
CExternalPixelShader& Shader = *m_pCustomScreenSpacePixelShaders.GetNext(pos);
Shader.m_pPixelShader = nullptr;
}
pos = m_pCustomPixelShaders.GetHeadPosition();
while (pos) {
CExternalPixelShader& Shader = m_pCustomPixelShaders.GetNext(pos);
CExternalPixelShader& Shader = *m_pCustomPixelShaders.GetNext(pos);
Shader.m_pPixelShader = nullptr;
}

Expand Down Expand Up @@ -419,11 +421,11 @@ HRESULT CDX9RenderingEngine::RenderVideoDrawPath(IDirect3DSurface9* pRenderTarge
hr = m_pTemporaryVideoTextures[dest]->GetSurfaceLevel(0, &pTemporarySurface);
hr = m_pD3DDev->SetRenderTarget(0, pTemporarySurface);

CExternalPixelShader& Shader = m_pCustomPixelShaders.GetNext(pos);
CExternalPixelShader& Shader = *m_pCustomPixelShaders.GetNext(pos);
if (!Shader.m_pPixelShader) {
Shader.Compile(m_pPSC);
}
hr = m_pD3DDev->SetPixelShader(Shader.m_pPixelShader);
hr = Shader.Apply(m_pD3DDev);

if (first) {
TextureCopy(m_pVideoTexture[m_nCurSurface]);
Expand Down Expand Up @@ -488,11 +490,11 @@ HRESULT CDX9RenderingEngine::RenderVideoDrawPath(IDirect3DSurface9* pRenderTarge
while (pos) {
BeginScreenSpacePass();

CExternalPixelShader& Shader = m_pCustomScreenSpacePixelShaders.GetNext(pos);
CExternalPixelShader& Shader = *m_pCustomScreenSpacePixelShaders.GetNext(pos);
if (!Shader.m_pPixelShader) {
Shader.Compile(m_pPSC);
}
hr = m_pD3DDev->SetPixelShader(Shader.m_pPixelShader);
hr = Shader.Apply(m_pD3DDev);
TextureCopy(m_pTemporaryScreenSpaceTextures[m_ScreenSpacePassSrc]);
}
}
Expand Down Expand Up @@ -1700,7 +1702,7 @@ HRESULT CDX9RenderingEngine::AlphaBlt(const RECT* pSrc, const RECT* pDst, IDirec

HRESULT CDX9RenderingEngine::SetCustomPixelShader(LPCSTR pSrcData, LPCSTR pTarget, bool bScreenSpace)
{
CAtlList<CExternalPixelShader>* pPixelShaders;
CAutoPtrList<CExternalPixelShader>* pPixelShaders;
if (bScreenSpace) {
pPixelShaders = &m_pCustomScreenSpacePixelShaders;
} else {
Expand All @@ -1710,27 +1712,171 @@ HRESULT CDX9RenderingEngine::SetCustomPixelShader(LPCSTR pSrcData, LPCSTR pTarge
if (!pSrcData && !pTarget) {
pPixelShaders->RemoveAll();
m_pD3DDev->SetPixelShader(nullptr);
UpdateExternalTextures();
return S_OK;
}

if (!pSrcData) {
return E_INVALIDARG;
}

CExternalPixelShader Shader;
Shader.m_SourceData = pSrcData;
Shader.m_SourceTarget = pTarget;

CComPtr<IDirect3DPixelShader9> pPixelShader;
CAutoPtr<CExternalPixelShader> shader;
shader.Attach(DEBUG_NEW CExternalPixelShader());
shader->m_SourceData = pSrcData;
shader->m_SourceTarget = pTarget;

HRESULT hr = Shader.Compile(m_pPSC);
HRESULT hr = shader->Compile(m_pPSC);
if (FAILED(hr)) {
return hr;
}

pPixelShaders->AddTail(Shader);
m_LatestCustomPixelShader = shader;
pPixelShaders->AddTail(shader);

Paint(false);

return S_OK;
}

HRESULT CDX9RenderingEngine::SetCustomPixelShaderTexture(int registerId, const CString& path, int filter, int wrap)
{
PixelShaderTexture texture;
texture.texture = LoadExternalTexture(path);
if (texture.texture == NULL) {
return E_FAIL;
}
texture.registerId = registerId;
texture.filter = filter;
texture.wrap = wrap;
m_LatestCustomPixelShader->m_Textures.AddTail(texture);
return S_OK;
}

HRESULT CDX9RenderingEngine::SetCustomPixelShaderParameter(int registerId, const float values[4])
{
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)
{
ExternalTexture* pTexture;
if (m_ExternalTextures.Lookup(filePath, pTexture) != 0) {
CFileStatus status;
if (!CFile::GetStatus(filePath, status) || status.m_mtime != pTexture->timeStamp) {
delete pTexture;
m_ExternalTextures.RemoveKey(filePath);
} else {
pTexture->bUsed = true;
return pTexture;
}
}

pTexture = DEBUG_NEW ExternalTexture();
if (FAILED(D3DXCreateTextureFromFile(m_pD3DDev, filePath, &pTexture->pTexture))) {
return NULL;
}

CFileStatus status;
if (CFile::GetStatus(filePath, status)) {
pTexture->timeStamp = status.m_mtime;
}

pTexture->bUsed = true;
m_ExternalTextures[filePath] = pTexture;
return pTexture;
}

void CDX9RenderingEngine::DestroyExternalTextures()
{
POSITION pos = m_ExternalTextures.GetStartPosition();
while (pos != NULL) {
CString filePath;
ExternalTexture* texture;
m_ExternalTextures.GetNextAssoc(pos, filePath, texture);
delete texture;
}
m_ExternalTextures.RemoveAll();
}

void CDX9RenderingEngine::UpdateExternalTextures()
{
POSITION pos = m_ExternalTextures.GetStartPosition();
while (pos) {
CString filePath;
ExternalTexture* texture;
m_ExternalTextures.GetNextAssoc(pos, filePath, texture);

if (texture->bUsed) {
texture->bUsed = false;
} else {
delete texture;
m_ExternalTextures.RemoveKey(filePath);
}
}
}

HRESULT CDX9RenderingEngine::CExternalPixelShader::Compile(CPixelShaderCompiler* pCompiler)
{
HRESULT hr = pCompiler->CompileShader(m_SourceData, "main", m_SourceTarget, 0, &m_pPixelShader);
if (FAILED(hr)) {
return hr;
}

return S_OK;
}

HRESULT CDX9RenderingEngine::CExternalPixelShader::Apply(IDirect3DDevice9* pD3DDev)
{
HRESULT res = pD3DDev->SetPixelShader(m_pPixelShader);
if (res != S_OK) {
return res;
}

// Apply textures
POSITION pos = m_Textures.GetHeadPosition();
while (pos) {
PixelShaderTexture& texture = m_Textures.GetNext(pos);
res = pD3DDev->SetTexture(texture.registerId, texture.texture->pTexture);
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
pos = m_Parameters.GetHeadPosition();
while (pos) {
PixelShaderParameter& parameter = m_Parameters.GetNext(pos);
res = pD3DDev->SetPixelShaderConstantF(parameter.registerId, parameter.values, 4);
if (res != S_OK) {
return res;
}
}

return res;
}