diff --git a/Externals/Cg/cgD3D10.h b/Externals/Cg/cgD3D10.h new file mode 100644 index 0000000000..3abf196cc0 --- /dev/null +++ b/Externals/Cg/cgD3D10.h @@ -0,0 +1,238 @@ +/* + * + * Copyright (c) 2008-2009, NVIDIA Corporation. + * + * + * + * NVIDIA Corporation("NVIDIA") supplies this software to you in consideration + * of your agreement to the following terms, and your use, installation, + * modification or redistribution of this NVIDIA software constitutes + * acceptance of these terms. If you do not agree with these terms, please do + * not use, install, modify or redistribute this NVIDIA software. + * + * + * + * In consideration of your agreement to abide by the following terms, and + * subject to these terms, NVIDIA grants you a personal, non-exclusive license, + * under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA + * Software"), to use, reproduce, modify and redistribute the NVIDIA + * Software, with or without modifications, in source and/or binary forms; + * provided that if you redistribute the NVIDIA Software, you must retain the + * copyright notice of NVIDIA, this notice and the following text and + * disclaimers in all such redistributions of the NVIDIA Software. Neither the + * name, trademarks, service marks nor logos of NVIDIA Corporation may be used + * to endorse or promote products derived from the NVIDIA Software without + * specific prior written permission from NVIDIA. Except as expressly stated + * in this notice, no other rights or licenses express or implied, are granted + * by NVIDIA herein, including but not limited to any patent rights that may be + * infringed by your derivative works or by other works in which the NVIDIA + * Software may be incorporated. No hardware is licensed hereunder. + * + * + * + * THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION + * EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS. + * + * + * + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST + * PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE, + * REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE, + * HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING + * NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __CGD3D10_H__ +#define __CGD3D10_H__ + +#ifdef _WIN32 + +#pragma once + +#include +#include + +#include "Cg/cg.h" + + + +// Set up for either Win32 import/export/lib. +#ifdef CGD3D10DLL_EXPORTS +#define CGD3D10DLL_API __declspec(dllexport) +#elif defined (CG_LIB) +#define CGD3D10DLL_API +#else +#define CGD3D10DLL_API __declspec(dllimport) +#endif + +#ifndef CGD3D10ENTRY +# ifdef _WIN32 +# define CGD3D10ENTRY __cdecl +# else +# define CGD3D10ENTRY +# endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef CGD3D10_EXPLICIT + +/* ----- D3D Device Control ----- */ + +CGD3D10DLL_API ID3D10Device * CGD3D10ENTRY +cgD3D10GetDevice( + CGcontext Context +); + +CGD3D10DLL_API HRESULT CGD3D10ENTRY +cgD3D10SetDevice( + CGcontext Context, + ID3D10Device * pDevice +); + +/* ----- Texture Functions ----- */ + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10SetTextureParameter( + CGparameter Parameter, + ID3D10Resource * pTexture +); + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10SetSamplerStateParameter( + CGparameter Parameter, + ID3D10SamplerState * pSamplerState +); + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10SetTextureSamplerStateParameter( + CGparameter Parameter, + ID3D10Resource * pTexture, + ID3D10SamplerState * pSamplerState +); + +/* ----- Shader Management ----- */ + +CGD3D10DLL_API HRESULT CGD3D10ENTRY +cgD3D10LoadProgram( + CGprogram Program, + UINT Flags +); + +CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY +cgD3D10GetCompiledProgram( + CGprogram Program +); + +CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY +cgD3D10GetProgramErrors( + CGprogram Program +); + +CGD3D10DLL_API CGbool CGD3D10ENTRY +cgD3D10IsProgramLoaded( + CGprogram Program +); + +CGD3D10DLL_API HRESULT CGD3D10ENTRY +cgD3D10BindProgram( + CGprogram Program +); + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10UnloadProgram( + CGprogram Program +); + +/* ----- Buffer Management ----- */ + +CGD3D10DLL_API ID3D10Buffer * CGD3D10ENTRY +cgD3D10GetBufferByIndex( + CGprogram Program, + UINT Index +); + +/* ----- CgFX ----- */ + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10RegisterStates( + CGcontext Context +); + +CGD3D10DLL_API void CGD3D10ENTRY +cgD3D10SetManageTextureParameters( + CGcontext Context, + CGbool Flag +); + +CGD3D10DLL_API CGbool CGD3D10ENTRY +cgD3D10GetManageTextureParameters( + CGcontext Context +); + +CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY +cgD3D10GetIASignatureByPass( + CGpass Pass +); + +/* ----- Profile Options ----- */ + +CGD3D10DLL_API CGprofile CGD3D10ENTRY +cgD3D10GetLatestVertexProfile(); + +CGD3D10DLL_API CGprofile CGD3D10ENTRY +cgD3D10GetLatestGeometryProfile(); + +CGD3D10DLL_API CGprofile CGD3D10ENTRY +cgD3D10GetLatestPixelProfile(); + +CGD3D10DLL_API CGbool CGD3D10ENTRY +cgD3D10IsProfileSupported( + CGprofile Profile +); + +/* ----- Utility Functions ----- */ + +CGD3D10DLL_API DWORD CGD3D10ENTRY +cgD3D10TypeToSize( + CGtype Type +); + +CGD3D10DLL_API HRESULT CGD3D10ENTRY +cgD3D10GetLastError(); + +CGD3D10DLL_API const char ** CGD3D10ENTRY +cgD3D10GetOptimalOptions( + CGprofile Profile +); + +CGD3D10DLL_API const char * CGD3D10ENTRY +cgD3D10TranslateCGerror( + CGerror Error +); + +CGD3D10DLL_API const char * CGD3D10ENTRY +cgD3D10TranslateHRESULT( + HRESULT hr +); + +#endif // #ifndef CGD3D10_EXPLICIT + +#ifdef __cplusplus +}; // extern "C" +#endif + +#endif // #ifdef _WIN32 + +#endif // #ifndef __CGD3D10_H__ diff --git a/Externals/Cg/cgD3D9.dll b/Externals/Cg/cgD3D9.dll new file mode 100644 index 0000000000..f1b043b275 Binary files /dev/null and b/Externals/Cg/cgD3D9.dll differ diff --git a/Externals/Cg/cgD3D9.h b/Externals/Cg/cgD3D9.h new file mode 100644 index 0000000000..71618debc4 --- /dev/null +++ b/Externals/Cg/cgD3D9.h @@ -0,0 +1,317 @@ +/* + * + * Copyright (c) 2002-2009, NVIDIA Corporation. + * + * + * + * NVIDIA Corporation("NVIDIA") supplies this software to you in consideration + * of your agreement to the following terms, and your use, installation, + * modification or redistribution of this NVIDIA software constitutes + * acceptance of these terms. If you do not agree with these terms, please do + * not use, install, modify or redistribute this NVIDIA software. + * + * + * + * In consideration of your agreement to abide by the following terms, and + * subject to these terms, NVIDIA grants you a personal, non-exclusive license, + * under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA + * Software"), to use, reproduce, modify and redistribute the NVIDIA + * Software, with or without modifications, in source and/or binary forms; + * provided that if you redistribute the NVIDIA Software, you must retain the + * copyright notice of NVIDIA, this notice and the following text and + * disclaimers in all such redistributions of the NVIDIA Software. Neither the + * name, trademarks, service marks nor logos of NVIDIA Corporation may be used + * to endorse or promote products derived from the NVIDIA Software without + * specific prior written permission from NVIDIA. Except as expressly stated + * in this notice, no other rights or licenses express or implied, are granted + * by NVIDIA herein, including but not limited to any patent rights that may be + * infringed by your derivative works or by other works in which the NVIDIA + * Software may be incorporated. No hardware is licensed hereunder. + * + * + * + * THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION + * EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS. + * + * + * + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST + * PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE, + * REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE, + * HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING + * NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef CGD3D9_INCLUDED +#define CGD3D9_INCLUDED + +#ifdef _WIN32 + +#pragma once + +#include "cg.h" +#include +#include + +// Set up for either Win32 import/export/lib. +#include +#ifdef CGD3D9DLL_EXPORTS +#define CGD3D9DLL_API __declspec(dllexport) +#elif defined (CG_LIB) +#define CGD3D9DLL_API +#else +#define CGD3D9DLL_API __declspec(dllimport) +#endif + +#ifndef CGD3D9ENTRY +# ifdef _WIN32 +# define CGD3D9ENTRY __cdecl +# else +# define CGD3D9ENTRY +# endif +#endif + +/*--------------------------------------------------------------------------- +// CGerrors that will be fed to cgSetError +// Use cgD3D9TranslateCGerror() to translate these errors into strings. +---------------------------------------------------------------------------*/ +enum cgD3D9Errors +{ + cgD3D9Failed = 1000, + cgD3D9DebugTrace = 1001, +}; + +/*--------------------------------------------------------------------------- +// HRESULTs specific to cgD3D9. When the CGerror is set to cgD3D9Failed +// cgD3D9GetLastError will return an HRESULT that could be one these. +// Use cgD3D9TranslateHRESULT() to translate these errors into strings. +---------------------------------------------------------------------------*/ +static const HRESULT CGD3D9ERR_NOTLOADED = MAKE_HRESULT(1, 0x877, 1); +static const HRESULT CGD3D9ERR_NODEVICE = MAKE_HRESULT(1, 0x877, 2); +static const HRESULT CGD3D9ERR_NOTSAMPLER = MAKE_HRESULT(1, 0x877, 3); +static const HRESULT CGD3D9ERR_INVALIDPROFILE = MAKE_HRESULT(1, 0x877, 4); +static const HRESULT CGD3D9ERR_NULLVALUE = MAKE_HRESULT(1, 0x877, 5); +static const HRESULT CGD3D9ERR_OUTOFRANGE = MAKE_HRESULT(1, 0x877, 6); +static const HRESULT CGD3D9ERR_NOTUNIFORM = MAKE_HRESULT(1, 0x877, 7); +static const HRESULT CGD3D9ERR_NOTMATRIX = MAKE_HRESULT(1, 0x877, 8); +static const HRESULT CGD3D9ERR_INVALIDPARAM = MAKE_HRESULT(1, 0x877, 9); + +/*--------------------------------------------------------------------------- +// Other error return values +---------------------------------------------------------------------------*/ +static const DWORD CGD3D9_INVALID_USAGE = 0xFF; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef CGD3D9_EXPLICIT + +/*--------------------------------------------------------------------------- +// Minimal Interface +---------------------------------------------------------------------------*/ + +CGD3D9DLL_API DWORD CGD3D9ENTRY +cgD3D9TypeToSize( + CGtype type +); + +CGD3D9DLL_API BYTE CGD3D9ENTRY +cgD3D9ResourceToDeclUsage( + CGresource resource +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9GetVertexDeclaration( + CGprogram prog, + D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH] +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9ValidateVertexDeclaration( + CGprogram prog, + const D3DVERTEXELEMENT9* decl +); + +/*--------------------------------------------------------------------------- +// Expanded Interface +---------------------------------------------------------------------------*/ + +/* ----- D3D Device Control ----------- */ +CGD3D9DLL_API IDirect3DDevice9 * CGD3D9ENTRY +cgD3D9GetDevice(); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetDevice( + IDirect3DDevice9* pDevice +); + +/* ----- Shader Management ----------- */ + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9LoadProgram( + CGprogram prog, + CGbool paramShadowing, + DWORD assemFlags +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9UnloadProgram( + CGprogram prog +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9IsProgramLoaded( + CGprogram prog +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9BindProgram( + CGprogram prog +); + +/* ----- Parameter Management ----------- */ +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetUniform( + CGparameter param, + const void* floats +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetUniformArray( + CGparameter param, + DWORD offset, + DWORD numItems, + const void* values +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetUniformMatrix( + CGparameter param, + const D3DMATRIX* matrix +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetUniformMatrixArray( + CGparameter param, + DWORD offset, + DWORD numItems, + const D3DMATRIX* matrices +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetTexture( + CGparameter param, + IDirect3DBaseTexture9* tex +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetSamplerState( + CGparameter param, + D3DSAMPLERSTATETYPE type, + DWORD value +); + +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9SetTextureWrapMode( + CGparameter param, + DWORD value +); + +/* ----- Parameter Management (Shadowing) ----------- */ +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9EnableParameterShadowing( + CGprogram prog, + CGbool enable +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9IsParameterShadowingEnabled( + CGprogram prog +); + +/* --------- Profile Options ----------------- */ +CGD3D9DLL_API CGprofile CGD3D9ENTRY +cgD3D9GetLatestVertexProfile(); + +CGD3D9DLL_API CGprofile CGD3D9ENTRY +cgD3D9GetLatestPixelProfile(); + +CGD3D9DLL_API const char * * CGD3D9ENTRY +cgD3D9GetOptimalOptions( + CGprofile profile +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9IsProfileSupported( + CGprofile profile +); + +/* --------- Error reporting ----------------- */ +CGD3D9DLL_API HRESULT CGD3D9ENTRY +cgD3D9GetLastError(); + +CGD3D9DLL_API const char * CGD3D9ENTRY +cgD3D9TranslateCGerror( + CGerror error +); + +CGD3D9DLL_API const char * CGD3D9ENTRY +cgD3D9TranslateHRESULT( + HRESULT hr +); + +CGD3D9DLL_API void CGD3D9ENTRY +cgD3D9EnableDebugTracing( + CGbool enable +); + +/* --------- CgFX support -------------------- */ + +CGD3D9DLL_API void CGD3D9ENTRY +cgD3D9RegisterStates( + CGcontext ctx +); + +CGD3D9DLL_API void CGD3D9ENTRY +cgD3D9SetManageTextureParameters( + CGcontext ctx, + CGbool flag +); + +CGD3D9DLL_API CGbool CGD3D9ENTRY +cgD3D9GetManageTextureParameters( + CGcontext ctx +); + +CGD3D9DLL_API IDirect3DBaseTexture9 * CGD3D9ENTRY +cgD3D9GetTextureParameter( + CGparameter param +); + +CGD3D9DLL_API void CGD3D9ENTRY +cgD3D9SetTextureParameter( + CGparameter param, + IDirect3DBaseTexture9 *tex +); + +CGD3D9DLL_API void CGD3D9ENTRY +cgD3D9UnloadAllPrograms( void ); + + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif // _WIN32 + +#endif diff --git a/Externals/Cg/cgD3D9.lib b/Externals/Cg/cgD3D9.lib new file mode 100644 index 0000000000..4ae64fe9b6 Binary files /dev/null and b/Externals/Cg/cgD3D9.lib differ diff --git a/Externals/Cg64/cgD3D9.dll b/Externals/Cg64/cgD3D9.dll new file mode 100644 index 0000000000..17882b2426 Binary files /dev/null and b/Externals/Cg64/cgD3D9.dll differ diff --git a/Externals/Cg64/cgD3D9.lib b/Externals/Cg64/cgD3D9.lib new file mode 100644 index 0000000000..bad3dde626 Binary files /dev/null and b/Externals/Cg64/cgD3D9.lib differ diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj index f67309d777..36fe224999 100644 --- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj +++ b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj @@ -93,10 +93,11 @@ +#include + PixelShaderCache::PSCache PixelShaderCache::PixelShaders; void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4) @@ -58,7 +61,8 @@ void PixelShaderCache::SetShader() if (D3D::GetShaderVersion() < 2) return; // we are screwed - static LPDIRECT3DPIXELSHADER9 lastShader = 0; + //static LPDIRECT3DPIXELSHADER9 lastShader = 0; + static CGprogram lastShader = NULL; DVSTARTPROFILE(); PIXELSHADERUID uid; @@ -73,14 +77,17 @@ void PixelShaderCache::SetShader() PSCacheEntry &entry = iter->second; if (!lastShader || entry.shader != lastShader) { - D3D::dev->SetPixelShader(entry.shader); + //D3D::dev->SetPixelShader(entry.shader); + cgD3D9LoadProgram(entry.shader, false, 0); + cgD3D9BindProgram(entry.shader); lastShader = entry.shader; } return; } const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), false, false); - LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)(strlen(code))); + //LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)(strlen(code))); + CGprogram shader = CompileCgShader(code); if (shader) { //Make an entry in the table @@ -89,13 +96,48 @@ void PixelShaderCache::SetShader() newentry.frameCount = frameCount; PixelShaders[uid] = newentry; + // There seems to be an unknown Cg error here for some reason + ///PanicAlert("Load pShader"); + cgD3D9LoadProgram(shader, false, 0); + cgD3D9BindProgram(shader); + ///PanicAlert("Loaded pShader"); + INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size()); + } else + PanicAlert("Failed to compile Pixel Shader:\n\n%s", code); + + //D3D::dev->SetPixelShader(shader); +} + +CGprogram PixelShaderCache::CompileCgShader(const char *pstrprogram) +{ + char stropt[64]; + //sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); + //const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + + const char **opts = cgD3D9GetOptimalOptions(g_cgvProf); + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); + if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { + ERROR_LOG(VIDEO, "Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); + ERROR_LOG(VIDEO, pstrprogram); + return false; } - D3D::dev->SetPixelShader(shader); + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char *plocal = strstr(pcompiledprog, "program.local"); + while (plocal != NULL) { + const char *penv = " program.env"; + memcpy(plocal, penv, 13); + plocal = strstr(plocal+13, "program.local"); + } + + return tempprog; } + void PixelShaderCache::Cleanup() { PSCache::iterator iter; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index ee9ff3e587..e69df35643 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -25,6 +25,9 @@ #include "PixelShaderGen.h" #include "VertexShaderGen.h" +#include +#include + typedef u32 tevhash; tevhash GetCurrentTEV(); @@ -33,7 +36,8 @@ class PixelShaderCache { struct PSCacheEntry { - LPDIRECT3DPIXELSHADER9 shader; + //LPDIRECT3DPIXELSHADER9 shader; + CGprogram shader; int frameCount; PSCacheEntry() @@ -43,8 +47,12 @@ class PixelShaderCache } void Destroy() { - if (shader) - shader->Release(); + if (shader) { + cgD3D9UnloadProgram(shader); + cgDestroyProgram(shader); + // shader->Release(); + } + } }; @@ -57,6 +65,7 @@ public: static void Cleanup(); static void Shutdown(); static void SetShader(); + static CGprogram CompileCgShader(const char *pstrprogram); }; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 5ed556f907..5bab126790 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -38,6 +38,13 @@ #include "Utils.h" #include "EmuWindow.h" +#include +#include + +CGcontext g_cgcontext; +CGprofile g_cgvProf; +CGprofile g_cgfProf; + float Renderer::m_x; float Renderer::m_y; float Renderer::m_width; @@ -64,6 +71,15 @@ struct Message static std::list s_listMsgs; +void HandleCgError(CGcontext ctx, CGerror err, void* appdata) +{ + PanicAlert("Cg error: %s\n", cgGetErrorString(err)); + const char* listing = cgGetLastListing(g_cgcontext); + if (listing != NULL) { + PanicAlert("last listing: %s\n", listing); + } +} + void Renderer::Init(SVideoInitialize &_VideoInitialize) { EmuWindow::SetSize(g_Res[g_Config.iWindowedRes][0], g_Res[g_Config.iWindowedRes][1]); @@ -73,6 +89,15 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize) D3DVIEWPORT9 vp; D3D::dev->GetViewport(&vp); + g_cgcontext = cgCreateContext(); + + cgGetError(); + cgSetErrorHandler(HandleCgError, NULL); + + cgD3D9SetDevice(D3D::dev); + g_cgvProf = cgD3D9GetLatestVertexProfile(); + g_cgfProf = cgD3D9GetLatestPixelProfile(); + m_x = 0; m_y = 0; m_width = (float)vp.Width; @@ -104,6 +129,10 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize) void Renderer::Shutdown() { + cgD3D9SetDevice(NULL); + cgDestroyContext(g_cgcontext); + g_cgcontext = NULL; + D3D::font.Shutdown(); D3D::EndFrame(); D3D::Close(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h index 887418f5b0..e46ab5702f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h @@ -24,6 +24,11 @@ #include "pluginspecs_video.h" #include "D3DBase.h" +#include + +extern CGcontext g_cgcontext; +extern CGprofile g_cgvProf, g_cgfProf; + class Renderer { // screen offset diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 449c9eb7d2..5b46cc0b76 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -27,6 +27,9 @@ #include "BPMemory.h" #include "XFMemory.h" +#include +#include + VertexShaderCache::VSCache VertexShaderCache::vshaders; void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4) @@ -58,11 +61,11 @@ void VertexShaderCache::Shutdown() void VertexShaderCache::SetShader(u32 components) { - static LPDIRECT3DVERTEXSHADER9 shader = NULL; + static CGprogram shader = NULL; if (D3D::GetShaderVersion() < 2) return; // we are screwed - static LPDIRECT3DVERTEXSHADER9 lastShader = 0; + static CGprogram lastShader = NULL; DVSTARTPROFILE(); VERTEXSHADERUID uid; @@ -77,14 +80,17 @@ void VertexShaderCache::SetShader(u32 components) VSCacheEntry &entry = iter->second; if (!lastShader || entry.shader != lastShader) { - D3D::dev->SetVertexShader(entry.shader); + //D3D::dev->SetVertexShader(entry.shader); + cgD3D9LoadProgram(entry.shader, false, 0); + cgD3D9BindProgram(entry.shader); lastShader = entry.shader; } return; } const char *code = GenerateVertexShader(components, false); - shader = D3D::CompileVertexShader(code, (int)strlen(code)); + //shader = D3D::CompileVertexShader(code, (int)strlen(code)); + shader = CompileCgShader(code); if (shader) { //Make an entry in the table @@ -92,12 +98,45 @@ void VertexShaderCache::SetShader(u32 components) entry.shader = shader; entry.frameCount = frameCount; vshaders[uid] = entry; + + // There seems to be an unknown Cg error here for some reason + ///PanicAlert("Load vShader"); + cgD3D9LoadProgram(shader, false, 0); + cgD3D9BindProgram(shader); + ///PanicAlert("Loaded vShader"); + + INCSTAT(stats.numVertexShadersCreated); + SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); + } else + PanicAlert("Failed to compile Vertex Shader:\n\n%s", code); + + //D3D::dev->SetVertexShader(shader); +} + +CGprogram VertexShaderCache::CompileCgShader(const char *pstrprogram) +{ + char stropt[64]; + //sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); + //const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + const char **opts = cgD3D9GetOptimalOptions(g_cgvProf); + CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); + if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { + ERROR_LOG(VIDEO, "Failed to load vs %s:\n", cgGetLastListing(g_cgcontext)); + ERROR_LOG(VIDEO, pstrprogram); + return NULL; } - D3D::dev->SetVertexShader(shader); + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char *plocal = strstr(pcompiledprog, "program.local"); + while (plocal != NULL) { + const char* penv = " program.env"; + memcpy(plocal, penv, 13); + plocal = strstr(plocal + 13, "program.local"); + } - INCSTAT(stats.numVertexShadersCreated); - SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); + return tempprog; } void VertexShaderCache::Cleanup() diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h index 56798372ab..b34d123d0e 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h @@ -25,11 +25,15 @@ #include "D3DBase.h" #include "VertexShaderGen.h" +#include +#include + class VertexShaderCache { struct VSCacheEntry { - LPDIRECT3DVERTEXSHADER9 shader; + //LPDIRECT3DVERTEXSHADER9 shader; + CGprogram shader; int frameCount; VSCacheEntry() { @@ -38,8 +42,11 @@ class VertexShaderCache } void Destroy() { - if (shader) - shader->Release(); + if (shader) { + cgD3D9UnloadProgram(shader); + cgDestroyProgram(shader); + // shader->Release(); + } } }; @@ -52,6 +59,7 @@ public: static void Cleanup(); static void Shutdown(); static void SetShader(u32 components); + static CGprogram CompileCgShader(const char *pstrprogram); }; #endif // _VERTEXSHADERCACHE_H