mirror of https://github.com/PCSX2/pcsx2.git
zzogl: Try to use opengl3/4 feature for GLSL api. The API is easier and I had a better experience with GSdx-ogl
* Clean the zzsetparameter API to always use the program for uniform that depends on the program. Future goal is to use a nice OO interface * Use uniform buffer. Would allow future optimization and remove most initialization stuff. Don't support yet the 2 zzogl contexts. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5201 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
75484d3059
commit
a8209d610b
|
@ -20,7 +20,6 @@ set(CommonFlags
|
||||||
-fno-strict-aliasing
|
-fno-strict-aliasing
|
||||||
-Wstrict-aliasing # Allow to track strict aliasing issue.
|
-Wstrict-aliasing # Allow to track strict aliasing issue.
|
||||||
-Wunused-variable
|
-Wunused-variable
|
||||||
#-DOGL4_LOG # Easier for development
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(OptimizationFlags
|
set(OptimizationFlags
|
||||||
|
@ -31,7 +30,7 @@ set(OptimizationFlags
|
||||||
# Debug - Build
|
# Debug - Build
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
# add defines
|
# add defines
|
||||||
add_definitions(${CommonFlags} -g -Wall -D_DEBUG)
|
add_definitions(${CommonFlags} -g -Wall -D_DEBUG)
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
|
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
|
|
||||||
# Devel - Build
|
# Devel - Build
|
||||||
|
@ -48,7 +47,8 @@ endif(CMAKE_BUILD_TYPE STREQUAL Release)
|
||||||
|
|
||||||
# Select the shader API
|
# Select the shader API
|
||||||
if(GLSL_API)
|
if(GLSL_API)
|
||||||
add_definitions(-DGLSL_API)
|
add_definitions(-DGLSL_API -DGLSL4_API -DOGL4_LOG)
|
||||||
|
#add_definitions(-DGLSL_API)
|
||||||
else(GLSL_API)
|
else(GLSL_API)
|
||||||
add_definitions(-DNVIDIA_CG_API)
|
add_definitions(-DNVIDIA_CG_API)
|
||||||
endif(GLSL_API)
|
endif(GLSL_API)
|
||||||
|
@ -87,6 +87,7 @@ set(zzoglSources
|
||||||
ZZoglSave.cpp
|
ZZoglSave.cpp
|
||||||
ZZoglShaders.cpp
|
ZZoglShaders.cpp
|
||||||
ZZoglShadersGLSL.cpp
|
ZZoglShadersGLSL.cpp
|
||||||
|
ZZoglShadersGLSL4.cpp
|
||||||
ZZoglShoots.cpp
|
ZZoglShoots.cpp
|
||||||
ZZoglVB.cpp
|
ZZoglVB.cpp
|
||||||
)
|
)
|
||||||
|
@ -190,7 +191,8 @@ endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
||||||
if(PACKAGE_MODE)
|
if(PACKAGE_MODE)
|
||||||
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
|
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
|
||||||
if(GLSL_API)
|
if(GLSL_API)
|
||||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.glsl DESTINATION ${PLUGIN_DIR})
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.glsl DESTINATION ${GLSL_SHADER_DIR})
|
||||||
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl DESTINATION ${GLSL_SHADER_DIR})
|
||||||
else(GLSL_API)
|
else(GLSL_API)
|
||||||
if(NOT REBUILD_SHADER)
|
if(NOT REBUILD_SHADER)
|
||||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${PLUGIN_DIR})
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${PLUGIN_DIR})
|
||||||
|
@ -200,6 +202,7 @@ else(PACKAGE_MODE)
|
||||||
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||||
if(GLSL_API)
|
if(GLSL_API)
|
||||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||||
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||||
else(GLSL_API)
|
else(GLSL_API)
|
||||||
if(NOT REBUILD_SHADER)
|
if(NOT REBUILD_SHADER)
|
||||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
install(FILES ${PROJECT_SOURCE_DIR}/plugins/zzogl-pg/opengl/ps2hw.dat DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||||
|
|
|
@ -228,9 +228,9 @@ bool GLWindow::CreateContextGL(int major, int minor)
|
||||||
|
|
||||||
void GLWindow::CreateContextGL()
|
void GLWindow::CreateContextGL()
|
||||||
{
|
{
|
||||||
#ifdef OGL4_LOG
|
#if defined(OGL4_LOG) || defined(GLSL4_API)
|
||||||
// We need to define a debug context. So we need at a 3.0 context (if not 3.2)
|
// We need to define a debug context. So we need at a 3.0 context (if not 3.2 actually)
|
||||||
CreateContextGL(4, 1);
|
CreateContextGL(4, 2);
|
||||||
#else
|
#else
|
||||||
// FIXME there was some issue with previous context creation on Geforce7. Code was rewritten
|
// FIXME there was some issue with previous context creation on Geforce7. Code was rewritten
|
||||||
// for GSdx unfortunately it was not tested on Geforce7 so keep the 2.0 context for now.
|
// for GSdx unfortunately it was not tested on Geforce7 so keep the 2.0 context for now.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "GifTransfer.h"
|
#include "GifTransfer.h"
|
||||||
#include "HostMemory.h"
|
#include "HostMemory.h"
|
||||||
|
#include "ZZoglShoots.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -422,7 +423,7 @@ union tex_0_info
|
||||||
#define TEX_HIGHLIGHT 2
|
#define TEX_HIGHLIGHT 2
|
||||||
#define TEX_HIGHLIGHT2 3
|
#define TEX_HIGHLIGHT2 3
|
||||||
|
|
||||||
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
|
//bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height, int ext_format = 0);
|
||||||
extern void SaveTex(tex0Info* ptex, int usevid);
|
extern void SaveTex(tex0Info* ptex, int usevid);
|
||||||
extern char* NamedSaveTex(tex0Info* ptex, int usevid);
|
extern char* NamedSaveTex(tex0Info* ptex, int usevid);
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,11 @@ void CDepthTarget::Update(int context, CRenderTarget* prndr)
|
||||||
|
|
||||||
// write color and zero out stencil buf, always 0 context!
|
// write color and zero out stencil buf, always 0 context!
|
||||||
SetTexVariablesInt(0, 0, texframe, false, &ppsBitBltDepth, 1);
|
SetTexVariablesInt(0, 0, texframe, false, &ppsBitBltDepth, 1);
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
ZZshGLSetTextureParameter(ppsBitBltDepth.prog, ppsBitBltDepth.sMemory[context], vb[0].pmemtarg->ptex->tex, "BitBltDepth");
|
||||||
|
#else
|
||||||
ZZshGLSetTextureParameter(ppsBitBltDepth.prog, ppsBitBltDepth.sMemory, vb[0].pmemtarg->ptex->tex, "BitBltDepth");
|
ZZshGLSetTextureParameter(ppsBitBltDepth.prog, ppsBitBltDepth.sMemory, vb[0].pmemtarg->ptex->tex, "BitBltDepth");
|
||||||
|
#endif
|
||||||
|
|
||||||
float4 v = DefaultBitBltPos();
|
float4 v = DefaultBitBltPos();
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,11 @@ void CRenderTarget::Update(int context, CRenderTarget* pdepth)
|
||||||
// Fix in r133 -- FFX movies and Gust backgrounds!
|
// Fix in r133 -- FFX movies and Gust backgrounds!
|
||||||
//SetTexVariablesInt(0, 0*(AA.x || AA.y) ? 2 : 0, texframe, false, &ppsBitBlt[!!s_AAx], 1);
|
//SetTexVariablesInt(0, 0*(AA.x || AA.y) ? 2 : 0, texframe, false, &ppsBitBlt[!!s_AAx], 1);
|
||||||
SetTexVariablesInt(0, 0, texframe, false, &ppsBitBlt[bit_idx], 1);
|
SetTexVariablesInt(0, 0, texframe, false, &ppsBitBlt[bit_idx], 1);
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
ZZshGLSetTextureParameter(ppsBitBlt[bit_idx].prog, ppsBitBlt[bit_idx].sMemory[context], vb[0].pmemtarg->ptex->tex, "BitBlt.memory");
|
||||||
|
#else
|
||||||
ZZshGLSetTextureParameter(ppsBitBlt[bit_idx].prog, ppsBitBlt[bit_idx].sMemory, vb[0].pmemtarg->ptex->tex, "BitBlt.memory");
|
ZZshGLSetTextureParameter(ppsBitBlt[bit_idx].prog, ppsBitBlt[bit_idx].sMemory, vb[0].pmemtarg->ptex->tex, "BitBlt.memory");
|
||||||
|
#endif
|
||||||
|
|
||||||
v = float4(1, 1, 0.0f, 0.0f);
|
v = float4(1, 1, 0.0f, 0.0f);
|
||||||
ZZshSetParameter4fv(pvsBitBlt.prog, pvsBitBlt.sBitBltTex, v, "g_fBitBltTex");
|
ZZshSetParameter4fv(pvsBitBlt.prog, pvsBitBlt.sBitBltTex, v, "g_fBitBltTex");
|
||||||
|
|
|
@ -656,7 +656,13 @@ inline void RenderCheckForMemory(tex0Info& texframe, list<CRenderTarget*>& listT
|
||||||
v = RenderSetTargetInvTex(texframe.tw, texframe.th, CRTC_RENDER);
|
v = RenderSetTargetInvTex(texframe.tw, texframe.th, CRTC_RENDER);
|
||||||
float4 valpha = RenderGetForClip(texframe.psm, CRTC_RENDER);
|
float4 valpha = RenderGetForClip(texframe.psm, CRTC_RENDER);
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
// FIXME context
|
||||||
|
int context = 0;
|
||||||
|
ZZshGLSetTextureParameter(curr_ppsCRTC()->prog, curr_ppsCRTC()->sMemory[context], vb[0].pmemtarg->ptex->tex, "CRTC memory");
|
||||||
|
#else
|
||||||
ZZshGLSetTextureParameter(curr_ppsCRTC()->prog, curr_ppsCRTC()->sMemory, vb[0].pmemtarg->ptex->tex, "CRTC memory");
|
ZZshGLSetTextureParameter(curr_ppsCRTC()->prog, curr_ppsCRTC()->sMemory, vb[0].pmemtarg->ptex->tex, "CRTC memory");
|
||||||
|
#endif
|
||||||
RenderCreateInterlaceTex(texframe.th, CRTC_RENDER_TARG);
|
RenderCreateInterlaceTex(texframe.th, CRTC_RENDER_TARG);
|
||||||
ZZshSetPixelShader(curr_ppsCRTC()->prog);
|
ZZshSetPixelShader(curr_ppsCRTC()->prog);
|
||||||
|
|
||||||
|
|
|
@ -688,7 +688,7 @@ inline float4 FlushSetPageOffset(FRAGMENTSHADER* pfragment, int shadertype, CRen
|
||||||
// zoe2
|
// zoe2
|
||||||
if (PSMT_ISZTEX(ptextarg->psm)) vpageoffset.w = -1.0f;
|
if (PSMT_ISZTEX(ptextarg->psm)) vpageoffset.w = -1.0f;
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->fPageOffset, vpageoffset, "g_fPageOffset");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fPageOffset, vpageoffset, "g_fPageOffset");
|
||||||
|
|
||||||
return vpageoffset;
|
return vpageoffset;
|
||||||
}
|
}
|
||||||
|
@ -706,7 +706,7 @@ inline float4 FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& c
|
||||||
v.y = 16.0f / (float)curvb.tex0.th;
|
v.y = 16.0f / (float)curvb.tex0.th;
|
||||||
v.z = 0.5f * v.x;
|
v.z = 0.5f * v.x;
|
||||||
v.w = 0.5f * v.y;
|
v.w = 0.5f * v.y;
|
||||||
ZZshSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexOffset, v, "g_fTexOffset");
|
||||||
}
|
}
|
||||||
else if (shadertype == 4)
|
else if (shadertype == 4)
|
||||||
{
|
{
|
||||||
|
@ -715,7 +715,7 @@ inline float4 FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& c
|
||||||
v.y = 16.0f / (float)ptextarg->fbh;
|
v.y = 16.0f / (float)ptextarg->fbh;
|
||||||
v.z = -1;
|
v.z = -1;
|
||||||
v.w = 8.0f / (float)ptextarg->fbh;
|
v.w = 8.0f / (float)ptextarg->fbh;
|
||||||
ZZshSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexOffset, v, "g_fTexOffset");
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -749,7 +749,7 @@ inline float4 FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& cu
|
||||||
if (shadertype == 4)
|
if (shadertype == 4)
|
||||||
vTexDims.z += 8.0f;
|
vTexDims.z += 8.0f;
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexDims, vTexDims, "g_fTexDims");
|
||||||
|
|
||||||
return vTexDims;
|
return vTexDims;
|
||||||
}
|
}
|
||||||
|
@ -799,7 +799,7 @@ inline FRAGMENTSHADER* FlushUseExistRenderTarget(VB& curvb, CRenderTarget* ptext
|
||||||
float4 vTexDims = FlushTextureDims(pfragment, shadertype, curvb, ptextarg);
|
float4 vTexDims = FlushTextureDims(pfragment, shadertype, curvb, ptextarg);
|
||||||
|
|
||||||
if (pfragment->sCLUT != NULL && ptexclut != 0)
|
if (pfragment->sCLUT != NULL && ptexclut != 0)
|
||||||
ZZshGLSetTextureParameter(pfragment->sCLUT, ptexclut, "CLUT");
|
ZZshGLSetTextureParameter(pfragment->prog, pfragment->sCLUT, ptexclut, "CLUT");
|
||||||
|
|
||||||
FlushApplyResizeFilter(curvb, dwFilterOpts, ptextarg, context);
|
FlushApplyResizeFilter(curvb, dwFilterOpts, ptextarg, context);
|
||||||
|
|
||||||
|
@ -846,13 +846,17 @@ inline void FlushSetTexture(VB& curvb, FRAGMENTSHADER* pfragment, CRenderTarget*
|
||||||
|
|
||||||
// have to enable the texture parameters(curtest.atst)
|
// have to enable the texture parameters(curtest.atst)
|
||||||
if( curvb.ptexClamp[0] != 0 )
|
if( curvb.ptexClamp[0] != 0 )
|
||||||
ZZshGLSetTextureParameter(pfragment->sBitwiseANDX, curvb.ptexClamp[0], "Clamp 0");
|
ZZshGLSetTextureParameter(pfragment->prog, pfragment->sBitwiseANDX, curvb.ptexClamp[0], "Clamp 0");
|
||||||
|
|
||||||
if( curvb.ptexClamp[1] != 0 )
|
if( curvb.ptexClamp[1] != 0 )
|
||||||
ZZshGLSetTextureParameter(pfragment->sBitwiseANDY, curvb.ptexClamp[1], "Clamp 1");
|
ZZshGLSetTextureParameter(pfragment->prog, pfragment->sBitwiseANDY, curvb.ptexClamp[1], "Clamp 1");
|
||||||
|
|
||||||
if( pfragment->sMemory != NULL && s_ptexCurSet[context] != 0)
|
if( pfragment->sMemory != NULL && s_ptexCurSet[context] != 0)
|
||||||
ZZshGLSetTextureParameter(pfragment->sMemory, s_ptexCurSet[context], "Clamp memory");
|
#ifdef GLSL4_API
|
||||||
|
ZZshGLSetTextureParameter(pfragment->prog, pfragment->sMemory[context], s_ptexCurSet[context], "Clamp memory");
|
||||||
|
#else
|
||||||
|
ZZshGLSetTextureParameter(pfragment->prog, pfragment->sMemory, s_ptexCurSet[context], "Clamp memory");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset program and texture variables;
|
// Reset program and texture variables;
|
||||||
|
@ -975,7 +979,7 @@ inline void AlphaRenderFBA(VB& curvb, FRAGMENTSHADER* pfragment)
|
||||||
// needs to be before RenderAlphaTest
|
// needs to be before RenderAlphaTest
|
||||||
if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil))
|
if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil))
|
||||||
{
|
{
|
||||||
RenderFBA(curvb, pfragment->sOneColor);
|
RenderFBA(curvb, pfragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -990,7 +994,7 @@ inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pf
|
||||||
if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > ATST_ALWAYS) && (curtest.aref > 0x80))))
|
if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > ATST_ALWAYS) && (curtest.aref > 0x80))))
|
||||||
{
|
{
|
||||||
// need special stencil processing for the alpha
|
// need special stencil processing for the alpha
|
||||||
RenderAlphaTest(curvb, pfragment->sOneColor);
|
RenderAlphaTest(curvb, pfragment);
|
||||||
dwUsingSpecialTesting = 1;
|
dwUsingSpecialTesting = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,13 +1007,13 @@ inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pf
|
||||||
v.w *= 255;
|
v.w *= 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// not using blending so set to defaults
|
// not using blending so set to defaults
|
||||||
float4 v = exactcolor ? float4(1, 510 * 255.0f / 256.0f, 0, 0) : float4(1, 2 * 255.0f / 256.0f, 0, 0);
|
float4 v = exactcolor ? float4(1, 510 * 255.0f / 256.0f, 0, 0) : float4(1, 2 * 255.0f / 256.0f, 0, 0);
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1104,7 @@ inline void AlphaPabe(VB& curvb, FRAGMENTSHADER* pfragment, int exactcolor)
|
||||||
|
|
||||||
if (exactcolor) v.y *= 255;
|
if (exactcolor) v.y *= 255;
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
Draw(curvb);
|
Draw(curvb);
|
||||||
|
|
||||||
|
@ -1169,7 +1173,7 @@ inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest, FRAGMENTSHADE
|
||||||
|
|
||||||
if (exactcolor) { v.y *= 255; v.w *= 255; }
|
if (exactcolor) { v.y *= 255; v.w *= 255; }
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);
|
GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);
|
||||||
|
@ -1193,7 +1197,7 @@ inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest, FRAGMENTSHADE
|
||||||
|
|
||||||
if (exactcolor) v.y *= 255;
|
if (exactcolor) v.y *= 255;
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
Draw(curvb);
|
Draw(curvb);
|
||||||
|
|
||||||
|
@ -1245,7 +1249,7 @@ inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsin
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
|
||||||
float4 v = float4(0, exactcolor ? 510.0f : 2.0f, 0, 0);
|
float4 v = float4(0, exactcolor ? 510.0f : 2.0f, 0, 0);
|
||||||
ZZshSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
Draw(curvb);
|
Draw(curvb);
|
||||||
|
|
||||||
// don't need to restore
|
// don't need to restore
|
||||||
|
@ -1260,7 +1264,7 @@ inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment)
|
||||||
{
|
{
|
||||||
if (curvb.fba.fba)
|
if (curvb.fba.fba)
|
||||||
{
|
{
|
||||||
ProcessFBA(curvb, pfragment->sOneColor);
|
ProcessFBA(curvb, pfragment);
|
||||||
}
|
}
|
||||||
else if (s_bDestAlphaTest && bCanRenderStencil)
|
else if (s_bDestAlphaTest && bCanRenderStencil)
|
||||||
{
|
{
|
||||||
|
@ -1383,7 +1387,7 @@ void FlushIfNecesary(void* ptr)
|
||||||
if (vb[1].prndr == ptr || vb[1].pdepth == ptr) Flush(1);
|
if (vb[1].prndr == ptr || vb[1].pdepth == ptr) Flush(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderFBA(const VB& curvb, ZZshParameter sOneColor)
|
inline void RenderFBA(const VB& curvb, FRAGMENTSHADER* pfragment)
|
||||||
{
|
{
|
||||||
// add fba to all pixels
|
// add fba to all pixels
|
||||||
GL_STENCILFUNC(GL_ALWAYS, STENCIL_FBA, 0xff);
|
GL_STENCILFUNC(GL_ALWAYS, STENCIL_FBA, 0xff);
|
||||||
|
@ -1404,7 +1408,7 @@ inline void RenderFBA(const VB& curvb, ZZshParameter sOneColor)
|
||||||
|
|
||||||
float4 v(1,2,0,0);
|
float4 v(1,2,0,0);
|
||||||
|
|
||||||
ZZshSetParameter4fv(sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
Draw(curvb);
|
Draw(curvb);
|
||||||
|
|
||||||
|
@ -1427,7 +1431,7 @@ inline void RenderFBA(const VB& curvb, ZZshParameter sOneColor)
|
||||||
GL_ZTEST(curvb.test.zte);
|
GL_ZTEST(curvb.test.zte);
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline void RenderAlphaTest(const VB& curvb, ZZshParameter sOneColor)
|
__forceinline void RenderAlphaTest(const VB& curvb, FRAGMENTSHADER* pfragment )
|
||||||
{
|
{
|
||||||
if (!g_bUpdateStencil) return;
|
if (!g_bUpdateStencil) return;
|
||||||
|
|
||||||
|
@ -1443,7 +1447,7 @@ __forceinline void RenderAlphaTest(const VB& curvb, ZZshParameter sOneColor)
|
||||||
|
|
||||||
float4 v(1,2,0,0);
|
float4 v(1,2,0,0);
|
||||||
|
|
||||||
ZZshSetParameter4fv(sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
// or a 1 to the stencil buffer wherever alpha passes
|
// or a 1 to the stencil buffer wherever alpha passes
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
@ -1467,7 +1471,7 @@ __forceinline void RenderAlphaTest(const VB& curvb, ZZshParameter sOneColor)
|
||||||
if (curvb.test.ate && curvb.test.atst > ATST_ALWAYS && curvb.test.aref > 0x80)
|
if (curvb.test.ate && curvb.test.atst > ATST_ALWAYS && curvb.test.aref > 0x80)
|
||||||
{
|
{
|
||||||
v = float4(1,1,0,0);
|
v = float4(1,1,0,0);
|
||||||
ZZshSetParameter4fv(sOneColor, v, "g_fOneColor");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));
|
glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1565,7 +1569,7 @@ inline void ProcessStencil(const VB& curvb)
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline void ProcessFBA(const VB& curvb, ZZshParameter sOneColor)
|
__forceinline void ProcessFBA(const VB& curvb, FRAGMENTSHADER* pfragment )
|
||||||
{
|
{
|
||||||
if ((curvb.frame.fbm&0x80000000)) return;
|
if ((curvb.frame.fbm&0x80000000)) return;
|
||||||
|
|
||||||
|
@ -1590,8 +1594,12 @@ __forceinline void ProcessFBA(const VB& curvb, ZZshParameter sOneColor)
|
||||||
GL_BLEND_ALPHA(GL_ONE, GL_ONE);
|
GL_BLEND_ALPHA(GL_ONE, GL_ONE);
|
||||||
GL_BLENDEQ_ALPHA(GL_FUNC_ADD);
|
GL_BLENDEQ_ALPHA(GL_FUNC_ADD);
|
||||||
|
|
||||||
float f = 1;
|
// FIXME: Seem dangerous
|
||||||
ZZshSetParameter4fv(sOneColor, &f, "g_fOneColor");
|
// float f = 1;
|
||||||
|
// ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, &f, "g_fOneColor");
|
||||||
|
float4 v = float4(1,1,0,0);
|
||||||
|
ZZshSetParameter4fv(pfragment->prog, pfragment->sOneColor, v, "g_fOneColor");
|
||||||
|
|
||||||
ZZshSetPixelShader(ppsOne.prog);
|
ZZshSetPixelShader(ppsOne.prog);
|
||||||
Draw(curvb);
|
Draw(curvb);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
@ -1840,11 +1848,10 @@ void SetTexClamping(int context, FRAGMENTSHADER* pfragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfragment->fTexWrapMode != 0)
|
if (pfragment->fTexWrapMode != 0)
|
||||||
ZZshSetParameter4fv(pfragment->fTexWrapMode, v, "g_fTexWrapMode");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexWrapMode, v, "g_fTexWrapMode");
|
||||||
|
|
||||||
if (pfragment->fClampExts != 0)
|
if (pfragment->fClampExts != 0)
|
||||||
ZZshSetParameter4fv(pfragment->fClampExts, v2, "g_fClampExts");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fClampExts, v2, "g_fClampExts");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1917,15 +1924,15 @@ void SetTexVariables(int context, FRAGMENTSHADER* pfragment)
|
||||||
valpha.z = (tex0.tfx == TFX_HIGHLIGHT2);
|
valpha.z = (tex0.tfx == TFX_HIGHLIGHT2);
|
||||||
valpha.w = (tex0.tcc == 0) || (tex0.tcc == 1 && tex0.tfx == TFX_HIGHLIGHT);
|
valpha.w = (tex0.tcc == 0) || (tex0.tcc == 1 && tex0.tfx == TFX_HIGHLIGHT);
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->fTexAlpha, valpha, "g_fTexAlpha");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexAlpha, valpha, "g_fTexAlpha");
|
||||||
ZZshSetParameter4fv(pfragment->fTexAlpha2, valpha2, "g_fTexAlpha2");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexAlpha2, valpha2, "g_fTexAlpha2");
|
||||||
|
|
||||||
if (IsAlphaTestExpansion(tex0))
|
if (IsAlphaTestExpansion(tex0))
|
||||||
{
|
{
|
||||||
float4 vblack;
|
float4 vblack;
|
||||||
vblack.x = vblack.y = vblack.z = vblack.w = 10;
|
vblack.x = vblack.y = vblack.z = vblack.w = 10;
|
||||||
if (tex0.tcc && gs.texa.aem && psm == PSMCT24) vblack.w = 0;
|
if (tex0.tcc && gs.texa.aem && psm == PSMCT24) vblack.w = 0;
|
||||||
ZZshSetParameter4fv(pfragment->fTestBlack, vblack, "g_fTestBlack");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTestBlack, vblack, "g_fTestBlack");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTexClamping(context, pfragment);
|
SetTexClamping(context, pfragment);
|
||||||
|
@ -2025,11 +2032,11 @@ void SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, bool Ch
|
||||||
v.z *= b.bpp * (1 / 32.0f);
|
v.z *= b.bpp * (1 / 32.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexDims, vTexDims, "g_fTexDims");
|
||||||
|
|
||||||
// ZZshSetParameter4fv(pfragment->fTexBlock, b.vTexBlock, "g_fTexBlock"); // I change it, and it's working. Seems casting from float4 to float[4] is ok.
|
// ZZshSetParameter4fv(pfragment->fTexBlock, b.vTexBlock, "g_fTexBlock"); // I change it, and it's working. Seems casting from float4 to float[4] is ok.
|
||||||
ZZshSetParameter4fv(pfragment->fTexBlock, &b.vTexBlock.x, "g_fTexBlock");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexBlock, &b.vTexBlock.x, "g_fTexBlock");
|
||||||
ZZshSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fTexOffset, v, "g_fTexOffset");
|
||||||
|
|
||||||
// get hardware texture dims
|
// get hardware texture dims
|
||||||
//int texheight = pmemtarg->texH;
|
//int texheight = pmemtarg->texH;
|
||||||
|
@ -2049,7 +2056,7 @@ void SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, bool Ch
|
||||||
v.w = 0.5f;*/
|
v.w = 0.5f;*/
|
||||||
v.w = 0.5f;
|
v.w = 0.5f;
|
||||||
|
|
||||||
ZZshSetParameter4fv(pfragment->fPageOffset, v, "g_fPageOffset");
|
ZZshSetParameter4fv(pfragment->prog, pfragment->fPageOffset, v, "g_fPageOffset");
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
s_ptexCurSet[context] = pmemtarg->ptex->tex;
|
s_ptexCurSet[context] = pmemtarg->ptex->tex;
|
||||||
|
|
|
@ -108,11 +108,11 @@ void SetAlphaVariables(const alphaInfo& ainfo); // zzz
|
||||||
|
|
||||||
inline void SetAlphaTestInt(pixTest curtest);
|
inline void SetAlphaTestInt(pixTest curtest);
|
||||||
|
|
||||||
inline void RenderAlphaTest(const VB& curvb, ZZshParameter sOneColor);
|
inline void RenderAlphaTest(const VB& curvb, FRAGMENTSHADER* pfragment);
|
||||||
inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting);
|
inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting);
|
||||||
inline void ProcessStencil(const VB& curvb);
|
inline void ProcessStencil(const VB& curvb);
|
||||||
inline void RenderFBA(const VB& curvb, ZZshParameter sOneColor);
|
inline void RenderFBA(const VB& curvb, FRAGMENTSHADER* pfragment);
|
||||||
inline void ProcessFBA(const VB& curvb, ZZshParameter sOneColor); // zz
|
inline void ProcessFBA(const VB& curvb, FRAGMENTSHADER* pfragment); // zz
|
||||||
|
|
||||||
void SetContextTarget(int context);
|
void SetContextTarget(int context);
|
||||||
|
|
||||||
|
|
|
@ -276,13 +276,13 @@ void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name)
|
||||||
cgGLSetParameter4fv(param, v);
|
cgGLSetParameter4fv(param, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZZshSetParameter4fv(ZZshProgram prog, ZZshParameter param, const float* v, const char* name) {
|
void ZZshSetParameter4fv(ZZshProgram& prog, ZZshParameter param, const float* v, const char* name) {
|
||||||
ShaderHandleName = name;
|
ShaderHandleName = name;
|
||||||
cgGLSetParameter4fv(param, v);
|
cgGLSetParameter4fv(param, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same stuff, but also with retry of param, name should be USED name of param for prog.
|
// The same stuff, but also with retry of param, name should be USED name of param for prog.
|
||||||
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshProgram prog, const float* v, const char* name) {
|
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshProgram& prog, const float* v, const char* name) {
|
||||||
if (param != NULL)
|
if (param != NULL)
|
||||||
ZZshSetParameter4fv(prog, param[0], v, name);
|
ZZshSetParameter4fv(prog, param[0], v, name);
|
||||||
else
|
else
|
||||||
|
@ -303,7 +303,7 @@ void ZZshGLSetTextureParameter(ZZshProgram prog, ZZshParameter param, GLuint tex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used sometimes for color 1.
|
// Used sometimes for color 1.
|
||||||
void ZZshDefaultOneColor( FRAGMENTSHADER ptr ) {
|
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
|
||||||
ShaderHandleName = "Set Default One color";
|
ShaderHandleName = "Set Default One color";
|
||||||
float4 v = float4 ( 1, 1, 1, 1 );
|
float4 v = float4 ( 1, 1, 1, 1 );
|
||||||
ZZshSetParameter4fv( ptr.prog, ptr.sOneColor, v, "DefaultOne");
|
ZZshSetParameter4fv( ptr.prog, ptr.sOneColor, v, "DefaultOne");
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#define SHADER_REDUCED 1 // equivalent to ps2.0
|
#define SHADER_REDUCED 1 // equivalent to ps2.0
|
||||||
#define SHADER_ACCURATE 2 // for older cards with less accurate math (ps2.x+)
|
#define SHADER_ACCURATE 2 // for older cards with less accurate math (ps2.x+)
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include "ZZoglMath.h"
|
#include "ZZoglMath.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
|
|
||||||
|
@ -106,6 +107,159 @@ inline bool ZZshActiveParameter(ZZshParameter param) {return (param > -1); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern float4 g_vdepth;
|
||||||
|
extern float4 vlogz;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
enum {
|
||||||
|
ZZSH_CTX_0 = 0,
|
||||||
|
ZZSH_CTX_1 = 1,
|
||||||
|
ZZSH_CTX_ALL = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
class GSUniformBufferOGL {
|
||||||
|
GLuint buffer; // data object
|
||||||
|
GLuint index; // GLSL slot
|
||||||
|
uint size; // size of the data
|
||||||
|
const GLenum target;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GSUniformBufferOGL(GLuint index, uint size) : index(index)
|
||||||
|
, size(size)
|
||||||
|
,target(GL_UNIFORM_BUFFER)
|
||||||
|
{
|
||||||
|
glGenBuffers(1, &buffer);
|
||||||
|
bind();
|
||||||
|
allocate();
|
||||||
|
attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind()
|
||||||
|
{
|
||||||
|
glBindBuffer(target, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void allocate()
|
||||||
|
{
|
||||||
|
glBufferData(target, size, NULL, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach()
|
||||||
|
{
|
||||||
|
glBindBufferBase(target, index, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void upload(const void* src)
|
||||||
|
{
|
||||||
|
u32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||||
|
u8* dst = (u8*) glMapBufferRange(target, 0, size, flags);
|
||||||
|
memcpy(dst, src, size);
|
||||||
|
glUnmapBuffer(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
~GSUniformBufferOGL() {
|
||||||
|
glDeleteBuffers(1, &buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Note A nice template could be better
|
||||||
|
// Warning order is important for buffer (see GLSL)
|
||||||
|
// Note must be keep POD (so you can map it to GLSL)
|
||||||
|
struct GlobalUniform {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
// VS
|
||||||
|
float g_fPosXY[4]; // dual context
|
||||||
|
// PS
|
||||||
|
float g_fFogColor[4];
|
||||||
|
};
|
||||||
|
float linear[2*4];
|
||||||
|
};
|
||||||
|
void SettleFloat(int indice, const float* v) {
|
||||||
|
assert(indice >= 0);
|
||||||
|
assert(indice + 3 < sizeof(linear));
|
||||||
|
linear[indice+0] = v[0];
|
||||||
|
linear[indice+1] = v[1];
|
||||||
|
linear[indice+2] = v[2];
|
||||||
|
linear[indice+3] = v[3];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct ConstantUniform {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
// Both VS/PS
|
||||||
|
float g_fBilinear[4];
|
||||||
|
float g_fZbias[4];
|
||||||
|
float g_fc0[4];
|
||||||
|
float g_fMult[4];
|
||||||
|
// VS
|
||||||
|
float g_fZ[4];
|
||||||
|
float g_fZMin[4];
|
||||||
|
float g_fZNorm[4];
|
||||||
|
// PS
|
||||||
|
float g_fExactColor[4];
|
||||||
|
};
|
||||||
|
float linear[8*4];
|
||||||
|
};
|
||||||
|
void SettleFloat(int indice, const float* v) {
|
||||||
|
assert(indice >= 0);
|
||||||
|
assert(indice + 3 < sizeof(linear));
|
||||||
|
linear[indice+0] = v[0];
|
||||||
|
linear[indice+1] = v[1];
|
||||||
|
linear[indice+2] = v[2];
|
||||||
|
linear[indice+3] = v[3];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct FragmentUniform {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
float g_fTexAlpha2[4]; // dual context
|
||||||
|
float g_fTexOffset[4]; // dual context
|
||||||
|
float g_fTexDims[4]; // dual context
|
||||||
|
float g_fTexBlock[4]; // dual context
|
||||||
|
float g_fClampExts[4]; // dual context
|
||||||
|
float g_fTexWrapMode[4]; // dual context
|
||||||
|
float g_fRealTexDims[4]; // dual context
|
||||||
|
float g_fTestBlack[4]; // dual context
|
||||||
|
float g_fPageOffset[4]; // dual context
|
||||||
|
float g_fTexAlpha[4]; // dual context
|
||||||
|
float g_fInvTexDims[4];
|
||||||
|
float g_fBitBltZ[4];
|
||||||
|
float g_fOneColor[4];
|
||||||
|
};
|
||||||
|
float linear[13*4];
|
||||||
|
};
|
||||||
|
void SettleFloat(int indice, const float* v) {
|
||||||
|
assert(indice >= 0);
|
||||||
|
assert(indice + 3 < sizeof(linear));
|
||||||
|
linear[indice+0] = v[0];
|
||||||
|
linear[indice+1] = v[1];
|
||||||
|
linear[indice+2] = v[2];
|
||||||
|
linear[indice+3] = v[3];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct VertexUniform {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
float g_fBitBltPos[4];
|
||||||
|
float g_fBitBltTex[4];
|
||||||
|
float g_fBitBltTrans[4];
|
||||||
|
};
|
||||||
|
float linear[3*4];
|
||||||
|
};
|
||||||
|
void SettleFloat(int indice, const float* v) {
|
||||||
|
assert(indice >= 0);
|
||||||
|
assert(indice + 3 < sizeof(linear) / 4);
|
||||||
|
linear[indice+0] = v[0];
|
||||||
|
linear[indice+1] = v[1];
|
||||||
|
linear[indice+2] = v[2];
|
||||||
|
linear[indice+3] = v[3];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,6 +278,7 @@ extern ZZshParameter g_vparamPosXY[2], g_fparamFogColor;
|
||||||
#define MAX_ACTIVE_UNIFORMS 600
|
#define MAX_ACTIVE_UNIFORMS 600
|
||||||
#define MAX_ACTIVE_SHADERS 400
|
#define MAX_ACTIVE_SHADERS 400
|
||||||
|
|
||||||
|
#ifndef GLSL4_API
|
||||||
struct FRAGMENTSHADER
|
struct FRAGMENTSHADER
|
||||||
{
|
{
|
||||||
FRAGMENTSHADER() : prog(sZero), Shader(0), sMemory(pZero), sFinal(pZero), sBitwiseANDX(pZero), sBitwiseANDY(pZero), sInterlace(pZero), sCLUT(pZero), sOneColor(pZero), sBitBltZ(pZero),
|
FRAGMENTSHADER() : prog(sZero), Shader(0), sMemory(pZero), sFinal(pZero), sBitwiseANDX(pZero), sBitwiseANDY(pZero), sInterlace(pZero), sCLUT(pZero), sOneColor(pZero), sBitBltZ(pZero),
|
||||||
|
@ -217,7 +372,202 @@ struct FRAGMENTSHADER
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
const GLenum g_texture_target[10] = {GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D};
|
||||||
|
|
||||||
|
struct SamplerParam {
|
||||||
|
int unit;
|
||||||
|
GLuint texid;
|
||||||
|
GLenum target;
|
||||||
|
|
||||||
|
SamplerParam() : unit(-1), texid(0), target(0) {}
|
||||||
|
|
||||||
|
void set_unit(int new_unit = 0) {
|
||||||
|
assert(new_unit >= 0);
|
||||||
|
assert(new_unit < 10);
|
||||||
|
unit = new_unit;
|
||||||
|
target = g_texture_target[new_unit];
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_texture() {
|
||||||
|
assert(unit >= 0);
|
||||||
|
assert(unit < 10);
|
||||||
|
if (texid) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
|
glBindTexture(target, texid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_texture(GLuint texid) {
|
||||||
|
texid = texid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FRAGMENTSHADER
|
||||||
|
{
|
||||||
|
FRAGMENTSHADER() : prog(sZero) , Shader(0)
|
||||||
|
, sFinal(2)
|
||||||
|
, sBitwiseANDX(3)
|
||||||
|
, sBitwiseANDY(4)
|
||||||
|
, sInterlace(5)
|
||||||
|
, sCLUT(6)
|
||||||
|
{
|
||||||
|
// Uniform
|
||||||
|
sOneColor = (ZZshParameter)offsetof(struct FragmentUniform, g_fOneColor) /4;
|
||||||
|
sBitBltZ = (ZZshParameter)offsetof(struct FragmentUniform, g_fBitBltZ) /4;
|
||||||
|
sInvTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fInvTexDims) /4;
|
||||||
|
fTexAlpha = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexAlpha) /4;
|
||||||
|
fTexAlpha2 = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexAlpha2) /4;
|
||||||
|
fTexOffset = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexOffset) /4;
|
||||||
|
fTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexDims) /4;
|
||||||
|
fTexBlock = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexBlock) /4;
|
||||||
|
fClampExts = (ZZshParameter)offsetof(struct FragmentUniform, g_fClampExts) /4; // FIXME: There is a bug, that lead FFX-1 to incorrect CLAMP if this uniform have context.
|
||||||
|
fTexWrapMode = (ZZshParameter)offsetof(struct FragmentUniform, g_fTexWrapMode) /4;
|
||||||
|
fRealTexDims = (ZZshParameter)offsetof(struct FragmentUniform, g_fRealTexDims) /4;
|
||||||
|
fTestBlack = (ZZshParameter)offsetof(struct FragmentUniform, g_fTestBlack) /4;
|
||||||
|
fPageOffset = (ZZshParameter)offsetof(struct FragmentUniform, g_fPageOffset) /4;
|
||||||
|
|
||||||
|
sMemory[ZZSH_CTX_0] = 0;
|
||||||
|
sMemory[ZZSH_CTX_1] = 1;
|
||||||
|
//sFinal = 2;
|
||||||
|
//sBitwiseANDX = 3;
|
||||||
|
//sBitwiseANDY = 4;
|
||||||
|
//sInterlace = 5;
|
||||||
|
//sCLUT = 6;
|
||||||
|
samplers[sMemory[ZZSH_CTX_0]].set_unit(0);
|
||||||
|
samplers[sMemory[ZZSH_CTX_1]].set_unit(0); // Dual context. Use same unit
|
||||||
|
samplers[sFinal].set_unit(1);
|
||||||
|
samplers[sBitwiseANDX].set_unit(6);
|
||||||
|
samplers[sBitwiseANDY].set_unit(7);
|
||||||
|
samplers[sInterlace].set_unit(8);
|
||||||
|
samplers[sCLUT].set_unit(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZshShaderLink prog; // it link to FRAGMENTSHADER structure, for compability between GLSL and CG
|
||||||
|
ZZshShader Shader; // useless with separate build
|
||||||
|
ZZshShaderType ShaderType; // Not every PS and VS are used together, only compatible ones.
|
||||||
|
|
||||||
|
FragmentUniform uniform_buffer[ZZSH_CTX_ALL];
|
||||||
|
|
||||||
|
// sampler
|
||||||
|
ZZshParameter sMemory[ZZSH_CTX_ALL];
|
||||||
|
const ZZshParameter sFinal, sBitwiseANDX, sBitwiseANDY, sInterlace, sCLUT;
|
||||||
|
SamplerParam samplers[7];
|
||||||
|
|
||||||
|
// uniform
|
||||||
|
ZZshParameter sOneColor, sBitBltZ, sInvTexDims;
|
||||||
|
ZZshParameter fTexAlpha2, fTexOffset, fTexDims, fTexBlock, fClampExts, fTexWrapMode, fRealTexDims, fTestBlack, fPageOffset, fTexAlpha;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
string filename;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ZZshSetParameter4fv(ZZshParameter param, const float* v, int context = ZZSH_CTX_ALL) {
|
||||||
|
if (context < ZZSH_CTX_ALL)
|
||||||
|
uniform_buffer[context].SettleFloat((int) param, v);
|
||||||
|
else
|
||||||
|
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
|
||||||
|
uniform_buffer[i].SettleFloat((int) param, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_texture(int context) {
|
||||||
|
samplers[0+context].enable_texture();
|
||||||
|
for (int i = 2; i < 7; i++)
|
||||||
|
samplers[i].enable_texture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_texture(ZZshParameter param, GLuint texid) {
|
||||||
|
samplers[param].set_texture(texid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
struct COMMONSHADER
|
||||||
|
{
|
||||||
|
COMMONSHADER() : sBlocks(0)
|
||||||
|
, sBilinearBlocks(1)
|
||||||
|
, sConv16to32(2)
|
||||||
|
, sConv32to16(3)
|
||||||
|
{
|
||||||
|
// sBlocks = 0;
|
||||||
|
// sBilinearBlocks = 1;
|
||||||
|
// sConv16to32 = 2;
|
||||||
|
// sConv32to16 = 3;
|
||||||
|
samplers[sBlocks].set_unit(2);
|
||||||
|
samplers[sBilinearBlocks].set_unit(3);
|
||||||
|
samplers[sConv16to32].set_unit(4);
|
||||||
|
samplers[sConv32to16].set_unit(5);
|
||||||
|
|
||||||
|
|
||||||
|
g_fparamFogColor = (ZZshParameter)offsetof(struct GlobalUniform, g_fFogColor) /4;
|
||||||
|
g_vparamPosXY = (ZZshParameter)offsetof(struct GlobalUniform, g_fPosXY) /4;
|
||||||
|
|
||||||
|
g_fBilinear = (ZZshParameter)offsetof(struct ConstantUniform, g_fBilinear) /4;
|
||||||
|
g_fZBias = (ZZshParameter)offsetof(struct ConstantUniform, g_fZbias) /4;
|
||||||
|
g_fc0 = (ZZshParameter)offsetof(struct ConstantUniform, g_fc0) /4;
|
||||||
|
g_fMult = (ZZshParameter)offsetof(struct ConstantUniform, g_fMult) /4;
|
||||||
|
g_fZ = (ZZshParameter)offsetof(struct ConstantUniform, g_fZ) /4;
|
||||||
|
g_fZMin = (ZZshParameter)offsetof(struct ConstantUniform, g_fZMin) /4;
|
||||||
|
g_fZNorm = (ZZshParameter)offsetof(struct ConstantUniform, g_fZNorm) /4;
|
||||||
|
g_fExactColor = (ZZshParameter)offsetof(struct ConstantUniform, g_fExactColor) /4;
|
||||||
|
|
||||||
|
// Setup the constant buffer
|
||||||
|
|
||||||
|
// Set Z-test, log or no log;
|
||||||
|
if (conf.settings().no_logz) {
|
||||||
|
g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f));
|
||||||
|
vlogz = float4( 1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f);
|
||||||
|
vlogz = float4( 0.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fZ, g_vdepth );
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fZMin, vlogz );
|
||||||
|
|
||||||
|
const float g_filog32 = 0.999f / (32.0f * logf(2.0f));
|
||||||
|
float4 vnorm = float4(g_filog32, 0, 0,0);
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fZNorm, vnorm);
|
||||||
|
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fBilinear, float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ) );
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fZBias, float4(1.0f/256.0f, 1.0004f, 1, 0.5f) );
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fc0, float4(0,1, 0.001f, 0.5f) );
|
||||||
|
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fExactColor, float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f) );
|
||||||
|
uniform_buffer_constant.SettleFloat(g_fMult, float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZshParameter g_fparamFogColor, g_vparamPosXY;
|
||||||
|
ZZshParameter g_fBilinear, g_fZBias, g_fc0, g_fMult, g_fZ, g_fZMin, g_fZNorm, g_fExactColor;
|
||||||
|
|
||||||
|
GlobalUniform uniform_buffer[ZZSH_CTX_ALL];
|
||||||
|
ConstantUniform uniform_buffer_constant;
|
||||||
|
|
||||||
|
// Sampler
|
||||||
|
const ZZshParameter sBlocks, sBilinearBlocks, sConv16to32, sConv32to16;
|
||||||
|
SamplerParam samplers[4];
|
||||||
|
|
||||||
|
void ZZshSetParameter4fv(ZZshParameter param, const float* v, int context = ZZSH_CTX_ALL) {
|
||||||
|
if (context < ZZSH_CTX_ALL)
|
||||||
|
uniform_buffer[context].SettleFloat((int) param, v);
|
||||||
|
else
|
||||||
|
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
|
||||||
|
uniform_buffer[i].SettleFloat((int) param, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_texture(ZZshParameter param, GLuint texid) {
|
||||||
|
samplers[param].set_texture(texid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_texture() {
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
samplers[i].enable_texture();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GLSL4_API
|
||||||
struct VERTEXSHADER
|
struct VERTEXSHADER
|
||||||
{
|
{
|
||||||
VERTEXSHADER() : prog(sZero), Shader(0), sBitBltPos(pZero), sBitBltTex(pZero) {}
|
VERTEXSHADER() : prog(sZero), Shader(0), sBitBltPos(pZero), sBitBltTex(pZero) {}
|
||||||
|
@ -230,15 +580,50 @@ struct VERTEXSHADER
|
||||||
|
|
||||||
int ParametersStart, ParametersFinish;
|
int ParametersStart, ParametersFinish;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct VERTEXSHADER
|
||||||
|
{
|
||||||
|
|
||||||
|
VERTEXSHADER() : prog(sZero), Shader(0)
|
||||||
|
//: prog(sZero), Shader(0), sBitBltPos(pZero), sBitBltTex(pZero) {}
|
||||||
|
{
|
||||||
|
sBitBltPos = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltPos) /4;
|
||||||
|
sBitBltTex = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltTex) /4;
|
||||||
|
fBitBltTrans = (ZZshParameter)offsetof(struct VertexUniform, g_fBitBltTrans) /4;
|
||||||
|
|
||||||
|
// Default value not sure it is needed
|
||||||
|
uniform_buffer[0].SettleFloat(fBitBltTrans, float4(0.5f, -0.5f, 0.5, 0.5 + 0.4/416.0f ) );
|
||||||
|
uniform_buffer[1].SettleFloat(fBitBltTrans, float4(0.5f, -0.5f, 0.5, 0.5 + 0.4/416.0f ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexUniform uniform_buffer[ZZSH_CTX_ALL];
|
||||||
|
|
||||||
|
ZZshShaderLink prog;
|
||||||
|
ZZshShader Shader; // useless with separate build
|
||||||
|
ZZshShaderType ShaderType;
|
||||||
|
|
||||||
|
ZZshParameter sBitBltPos, sBitBltTex, fBitBltTrans; // vertex shader constants
|
||||||
|
|
||||||
|
void ZZshSetParameter4fv(ZZshParameter param, const float* v, int context = ZZSH_CTX_ALL) {
|
||||||
|
if (context < ZZSH_CTX_ALL)
|
||||||
|
uniform_buffer[context].SettleFloat((int) param, v);
|
||||||
|
else
|
||||||
|
for ( int i = 0; i < ZZSH_CTX_ALL ; i++)
|
||||||
|
uniform_buffer[i].SettleFloat((int) param, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
extern float4 g_vdepth;
|
|
||||||
extern float4 vlogz;
|
|
||||||
extern VERTEXSHADER pvsBitBlt;
|
extern VERTEXSHADER pvsBitBlt;
|
||||||
extern FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne; // ppsOne used to stop using shaders for draw
|
extern FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne; // ppsOne used to stop using shaders for draw
|
||||||
extern FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
|
extern FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
|
||||||
|
|
||||||
extern FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
|
extern FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
|
||||||
extern FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
|
extern FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
extern COMMONSHADER g_cs;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int interlace_mode;
|
extern int interlace_mode;
|
||||||
|
|
||||||
|
@ -318,16 +703,16 @@ extern void ZZshGLEnableProfile();
|
||||||
|
|
||||||
// Set the Uniform parameter in host (NOT GL)
|
// Set the Uniform parameter in host (NOT GL)
|
||||||
// Param seem to be an absolute index inside a table of uniform
|
// Param seem to be an absolute index inside a table of uniform
|
||||||
extern void ZZshSetParameter4fv(ZZshShaderLink prog, ZZshParameter param, const float* v, const char* name);
|
extern void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name);
|
||||||
extern void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name);
|
extern void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name);
|
||||||
extern void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink prog, const float* v, const char* name);
|
extern void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name);
|
||||||
|
|
||||||
// Set the Texture parameter in host (NOT GL)
|
// Set the Texture parameter in host (NOT GL)
|
||||||
extern void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name);
|
extern void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name);
|
||||||
extern void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name);
|
extern void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name);
|
||||||
|
|
||||||
// Set a default value for 1 uniform in host (NOT GL)
|
// Set a default value for 1 uniform in host (NOT GL)
|
||||||
extern void ZZshDefaultOneColor( FRAGMENTSHADER ptr );
|
extern void ZZshDefaultOneColor( FRAGMENTSHADER& ptr );
|
||||||
|
|
||||||
// Link then run with the new Vertex/Fragment Shader
|
// Link then run with the new Vertex/Fragment Shader
|
||||||
extern void ZZshSetVertexShader(ZZshShaderLink prog);
|
extern void ZZshSetVertexShader(ZZshShaderLink prog);
|
||||||
|
@ -350,5 +735,15 @@ extern u32 ptexConv16to32; // does not exists. This textures should be created o
|
||||||
extern u32 ptexBilinearBlocks;
|
extern u32 ptexBilinearBlocks;
|
||||||
extern u32 ptexConv32to16;
|
extern u32 ptexConv32to16;
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
extern GSUniformBufferOGL *constant_buffer;
|
||||||
|
extern GSUniformBufferOGL *common_buffer;
|
||||||
|
extern GSUniformBufferOGL *vertex_buffer;
|
||||||
|
extern GSUniformBufferOGL *fragment_buffer;
|
||||||
|
|
||||||
|
static void init_shader();
|
||||||
|
static void PutParametersInProgam(VERTEXSHADER* vs, FRAGMENTSHADER* ps, int context);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef GLSL_API // This code is only for GLSL API
|
#if defined(GLSL_API) && !defined(GLSL4_API) // This code is only for GLSL API
|
||||||
// ZZogl Shader manipulation functions.
|
// ZZogl Shader manipulation functions.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -237,10 +237,10 @@ bool ZZshCreateOpenShadersFile() {
|
||||||
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
||||||
// Each linux distributions have his rules for path so we give them the possibility to
|
// Each linux distributions have his rules for path so we give them the possibility to
|
||||||
// change it with compilation flags. -- Gregory
|
// change it with compilation flags. -- Gregory
|
||||||
#ifdef PLUGIN_DIR_COMPILATION
|
#ifdef GLSL_SHADER_DIR_COMPILATION
|
||||||
#define xPLUGIN_DIR_str(s) PLUGIN_DIR_str(s)
|
#define xGLSL_SHADER_DIR_str(s) GLSL_SHADER_DIR_str(s)
|
||||||
#define PLUGIN_DIR_str(s) #s
|
#define GLSL_SHADER_DIR_str(s) #s
|
||||||
ShaderFileName = string(xPLUGIN_DIR_str(PLUGIN_DIR_COMPILATION)) + "/ps2hw.glsl";
|
ShaderFileName = string(xGLSL_SHADER_DIR_str(GLSL_SHADER_DIR_COMPILATION)) + "/ps2hw.glsl";
|
||||||
ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
|
ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
|
||||||
#endif
|
#endif
|
||||||
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
||||||
|
@ -290,7 +290,7 @@ void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint
|
||||||
// This is helper of cgGLSetParameter4fv, made for debug purpose.
|
// This is helper of cgGLSetParameter4fv, made for debug purpose.
|
||||||
// Name could be any string. We must use it on compilation time, because erroneus handler does not
|
// Name could be any string. We must use it on compilation time, because erroneus handler does not
|
||||||
// return name
|
// return name
|
||||||
void ZZshSetParameter4fv(ZZshShaderLink prog, ZZshParameter param, const float* v, const char* name) {
|
void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name) {
|
||||||
if (param > -1) {
|
if (param > -1) {
|
||||||
// ZZLog::Error_Log("Set float parameter %s %f, %f, %f, %f... Ok", name, v[0], v[1], v[2], v[3]);
|
// ZZLog::Error_Log("Set float parameter %s %f, %f, %f, %f... Ok", name, v[0], v[1], v[2], v[3]);
|
||||||
SettleFloat(UniformsIndex[param].fvalue, v);
|
SettleFloat(UniformsIndex[param].fvalue, v);
|
||||||
|
@ -307,13 +307,13 @@ void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same stuff, but also with retry of param, name should be USED name of param for prog.
|
// The same stuff, but also with retry of param, name should be USED name of param for prog.
|
||||||
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink prog, const float* v, const char* name) {
|
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name) {
|
||||||
if (param != NULL)
|
if (param != NULL)
|
||||||
ZZshSetParameter4fv(prog, *param, v, name);
|
ZZshSetParameter4fv(prog, *param, v, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used sometimes for color 1.
|
// Used sometimes for color 1.
|
||||||
void ZZshDefaultOneColor( FRAGMENTSHADER ptr ) {
|
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
|
||||||
// return;
|
// return;
|
||||||
ShaderHandleName = "Set Default One colot";
|
ShaderHandleName = "Set Default One colot";
|
||||||
float4 v = float4 ( 1, 1, 1, 1 );
|
float4 v = float4 ( 1, 1, 1, 1 );
|
||||||
|
@ -426,7 +426,7 @@ inline bool GetLinkLog(ZZshProgram prog) {
|
||||||
|
|
||||||
if (LinkStatus == GL_TRUE && glIsProgram(prog)) return true;
|
if (LinkStatus == GL_TRUE && glIsProgram(prog)) return true;
|
||||||
|
|
||||||
#ifdef DEVBUILD
|
#if defined(DEVBUILD) || defined(_DEBUG)
|
||||||
int* lenght, infologlength;
|
int* lenght, infologlength;
|
||||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infologlength);
|
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
char* InfoLog = new char[infologlength];
|
char* InfoLog = new char[infologlength];
|
||||||
|
@ -474,6 +474,9 @@ static void PutParametersInProgam(int start, int finish) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// assert(param.texid != 0);
|
||||||
|
// ZZLog::Error_Log("Set texture (%s) : %d with sampler %d\n", param.ShName, param.texid, param.sampler);
|
||||||
|
// assert(param.sampler >= 0);
|
||||||
glActiveTexture(GL_TEXTURE0 + param.sampler);
|
glActiveTexture(GL_TEXTURE0 + param.sampler);
|
||||||
if (param.type == ZZ_TEXTURE_2D)
|
if (param.type == ZZ_TEXTURE_2D)
|
||||||
glBindTexture(GL_TEXTURE_2D, param.texid);
|
glBindTexture(GL_TEXTURE_2D, param.texid);
|
||||||
|
@ -974,4 +977,4 @@ FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testae
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLSL_API
|
#endif
|
||||||
|
|
|
@ -0,0 +1,843 @@
|
||||||
|
/* ZZ Open GL graphics plugin
|
||||||
|
* Copyright (c)2009 zeydlitz@gmail.com
|
||||||
|
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2006
|
||||||
|
*
|
||||||
|
* 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef GLSL4_API // This code is only for GLSL API
|
||||||
|
// ZZogl Shader manipulation functions.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* used cg calls:
|
||||||
|
* cgGLIsProfileSupported -- don't needed
|
||||||
|
* cgGetErrorString -- later
|
||||||
|
* cgGetLastListing -- later
|
||||||
|
* cgSetErrorHandler -- later
|
||||||
|
* cgCreateContext -- think that don't need
|
||||||
|
* cgGLEnableProfile -- don't need
|
||||||
|
* cgGLSetOptimalOptions -- don't need?
|
||||||
|
* cgGLSetManageTextureParameters -- what's this?
|
||||||
|
* cgCreateParameter -- don't need
|
||||||
|
* cgGLLoadProgram void LinkProgram(uint program)
|
||||||
|
* cgGetError -- later
|
||||||
|
* cgGLDisableProfile -- don't need
|
||||||
|
* cgGLSetParameter4fv
|
||||||
|
* cgGetNamedParameter
|
||||||
|
* cgGLEnableTextureParameter
|
||||||
|
* cgIsParameterUsed
|
||||||
|
* cgGLBindProgram void UseProgram(uint program)
|
||||||
|
* cgConnectParameter
|
||||||
|
* cgIsProgram bool IsProgram(uint program)
|
||||||
|
* cgCreateProgramFromFile
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------- Includes
|
||||||
|
#include "Util.h"
|
||||||
|
#include "ZZoglShaders.h"
|
||||||
|
#include "zpipe.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <map>
|
||||||
|
#include <fcntl.h> // this for open(). Maybe linux-specific
|
||||||
|
#include <sys/mman.h> // and this for mmap
|
||||||
|
|
||||||
|
// ----------------- Defines
|
||||||
|
|
||||||
|
#define TEXWRAP_REPEAT 0
|
||||||
|
#define TEXWRAP_CLAMP 1
|
||||||
|
#define TEXWRAP_REGION_REPEAT 2
|
||||||
|
#define TEXWRAP_REPEAT_CLAMP 3
|
||||||
|
|
||||||
|
#ifdef DEVBUILD
|
||||||
|
# define UNIFORM_ERROR_LOG ZZLog::Error_Log
|
||||||
|
#else
|
||||||
|
# define UNIFORM_ERROR_LOG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set it to 0 to diable context usage, 1 -- to enable. FFX-1 have a strange issue with ClampExt.
|
||||||
|
#define NOCONTEXT 0
|
||||||
|
#define NUMBER_OF_SAMPLERS 11
|
||||||
|
#define MAX_SHADER_NAME_SIZE 25
|
||||||
|
#define MAX_UNIFORM_NAME_SIZE 20
|
||||||
|
#define DEFINE_STRING_SIZE 256
|
||||||
|
//------------------ Constants
|
||||||
|
|
||||||
|
// Used in a logarithmic Z-test, as (1-o(1))/log(MAX_U32).
|
||||||
|
const float g_filog32 = 0.999f / (32.0f * logf(2.0f));
|
||||||
|
|
||||||
|
const static char* g_pTexTypes[] = { "32", "tex32", "clut32", "tex32to16", "tex16to8h" };
|
||||||
|
const static char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
|
||||||
|
|
||||||
|
// ----------------- Global Variables
|
||||||
|
|
||||||
|
ZZshContext g_cgcontext;
|
||||||
|
ZZshProfile cgvProf, cgfProf;
|
||||||
|
int g_nPixelShaderVer = 0; // default
|
||||||
|
u8* s_lpShaderResources = NULL;
|
||||||
|
ZZshShaderLink pvs[16] = {sZero}, g_vsprog = sZero, g_psprog = sZero; // 2 -- ZZ
|
||||||
|
ZZshParameter g_vparamPosXY[2] = {pZero}, g_fparamFogColor = pZero;
|
||||||
|
|
||||||
|
ZZshProgram ZZshMainProgram;
|
||||||
|
char* ZZshSource; // Shader's source data.
|
||||||
|
off_t ZZshSourceSize;
|
||||||
|
|
||||||
|
extern char* EFFECT_NAME; // All this variables used for testing and set manually
|
||||||
|
extern char* EFFECT_DIR;
|
||||||
|
|
||||||
|
bool g_bCRTCBilinear = true;
|
||||||
|
|
||||||
|
float4 g_vdepth, vlogz;
|
||||||
|
FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne;
|
||||||
|
FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
|
||||||
|
FRAGMENTSHADER ppsRegular[4], ppsTexture[NUM_SHADERS];
|
||||||
|
FRAGMENTSHADER ppsCRTC[2], /*ppsCRTC24[2],*/ ppsCRTCTarg[2];
|
||||||
|
VERTEXSHADER pvsStore[16];
|
||||||
|
VERTEXSHADER pvsBitBlt;
|
||||||
|
|
||||||
|
inline bool LoadEffects();
|
||||||
|
extern bool s_bWriteDepth;
|
||||||
|
|
||||||
|
struct SHADERHEADER
|
||||||
|
{
|
||||||
|
unsigned int index, offset, size; // if highest bit of index is set, pixel shader
|
||||||
|
};
|
||||||
|
map<int, SHADERHEADER*> mapShaderResources;
|
||||||
|
|
||||||
|
// Debug variable, store name of the function that call the shader.
|
||||||
|
const char* ShaderCallerName = "";
|
||||||
|
const char* ShaderHandleName = "";
|
||||||
|
|
||||||
|
int NumActiveUniforms, NumGlobalUniforms;
|
||||||
|
ZZshParamInfo UniformsIndex[MAX_ACTIVE_UNIFORMS] = {qZero};
|
||||||
|
const char* ShaderNames[MAX_ACTIVE_SHADERS] = {""};
|
||||||
|
ZZshShaderType ShaderTypes[MAX_ACTIVE_SHADERS] = {ZZ_SH_NONE};
|
||||||
|
|
||||||
|
ZZshProgram CompiledPrograms[MAX_ACTIVE_SHADERS][MAX_ACTIVE_SHADERS] = {{0}};
|
||||||
|
const char* TextureUnits[NUMBER_OF_SAMPLERS] =
|
||||||
|
{"g_sMemory[0]", "g_sMemory[1]", "g_sSrcFinal", "g_sBitwiseANDX", "g_sBitwiseANDY", "g_sInterlace", \
|
||||||
|
"g_sCLUT", "g_sBlocks", "g_sBilinearBlocks", "g_sConv16to32", "g_sConv32to16"};
|
||||||
|
ZZshPARAMTYPE TextureTypes[NUMBER_OF_SAMPLERS] =
|
||||||
|
{ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, ZZ_TEXTURE_RECT, \
|
||||||
|
ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_2D, ZZ_TEXTURE_3D} ;
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
GSUniformBufferOGL *constant_buffer;
|
||||||
|
GSUniformBufferOGL *common_buffer;
|
||||||
|
GSUniformBufferOGL *vertex_buffer;
|
||||||
|
GSUniformBufferOGL *fragment_buffer;
|
||||||
|
|
||||||
|
COMMONSHADER g_cs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------ Code
|
||||||
|
|
||||||
|
inline int GET_SHADER_INDEX(int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int context, int ps) {
|
||||||
|
return type + texfilter*NUM_TYPES + NUM_FILTERS*NUM_TYPES*texwrap + NUM_TEXWRAPS*NUM_FILTERS*NUM_TYPES*(fog+2*writedepth+4*testaem+8*exactcolor+16*context+32*ps) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing need to be done.
|
||||||
|
bool ZZshCheckProfilesSupport() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error handler. Setup in ZZogl_Create once.
|
||||||
|
void HandleCgError(ZZshContext ctx, ZZshError err, void* appdata)
|
||||||
|
{/*
|
||||||
|
ZZLog::Error_Log("%s->%s: %s", ShaderCallerName, ShaderHandleName, cgGetErrorString(err));
|
||||||
|
const char* listing = cgGetLastListing(g_cgcontext);
|
||||||
|
if (listing != NULL)
|
||||||
|
ZZLog::Debug_Log(" last listing: %s", listing);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
float ZeroFloat4[4] = {0};
|
||||||
|
|
||||||
|
inline void SettleFloat(float* f, const float* v) {
|
||||||
|
f[0] = v[0];
|
||||||
|
f[1] = v[1];
|
||||||
|
f[2] = v[2];
|
||||||
|
f[3] = v[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ZZshParamInfo ParamInfo(const char* ShName, ZZshPARAMTYPE type, const float fvalue[], GLuint sampler, GLint texid, bool Constant, bool Settled) {
|
||||||
|
ZZshParamInfo x;
|
||||||
|
x.ShName = new char[MAX_UNIFORM_NAME_SIZE];
|
||||||
|
x.ShName = ShName;
|
||||||
|
x.type = type;
|
||||||
|
SettleFloat(x.fvalue, fvalue);
|
||||||
|
x.sampler = sampler;
|
||||||
|
x.texid = texid;
|
||||||
|
x.Constant = Constant;
|
||||||
|
x.Settled = Settled;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZZshStartUsingShaders() {
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Creating effects.");
|
||||||
|
B_G(LoadEffects(), return false);
|
||||||
|
if (!glCreateShader)
|
||||||
|
{
|
||||||
|
ZZLog::Error_Log("GLSL shaders is not supported, stop.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_shader();
|
||||||
|
|
||||||
|
// create a sample shader
|
||||||
|
clampInfo temp;
|
||||||
|
memset(&temp, 0, sizeof(temp));
|
||||||
|
temp.wms = 3; temp.wmt = 3;
|
||||||
|
|
||||||
|
g_nPixelShaderVer = 0;//SHADER_ACCURATE;
|
||||||
|
// test
|
||||||
|
bool bFailed;
|
||||||
|
FRAGMENTSHADER* pfrag = ZZshLoadShadeEffect(0, 1, 1, 1, 1, temp, 0, &bFailed);
|
||||||
|
if( bFailed || pfrag == NULL ) {
|
||||||
|
g_nPixelShaderVer = SHADER_ACCURATE|SHADER_REDUCED;
|
||||||
|
|
||||||
|
pfrag = ZZshLoadShadeEffect(0, 0, 1, 1, 0, temp, 0, &bFailed);
|
||||||
|
if( pfrag != NULL )
|
||||||
|
glLinkProgram(pfrag->Shader);
|
||||||
|
if( bFailed || pfrag == NULL || glGetError() != GL_NO_ERROR) {
|
||||||
|
g_nPixelShaderVer = SHADER_REDUCED;
|
||||||
|
ZZLog::Error_Log("Basic shader test failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZZshMainProgram = glCreateProgram();
|
||||||
|
NumActiveUniforms = 0;
|
||||||
|
//SetGlobalUniform(&g_fparamFogColor, "g_fFogColor");
|
||||||
|
//SetGlobalUniform(&g_vparamPosXY[0], "g_fPosXY[0]");
|
||||||
|
//SetGlobalUniform(&g_vparamPosXY[1], NOCONTEXT?"g_fPosXY[1]":"g_fPosXY[0]");
|
||||||
|
//NumGlobalUniforms = NumActiveUniforms;
|
||||||
|
|
||||||
|
if (g_nPixelShaderVer & SHADER_REDUCED)
|
||||||
|
conf.bilinear = 0;
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Creating extra effects.");
|
||||||
|
B_G(ZZshLoadExtraEffects(), return false);
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Using %s shaders.", g_pShaders[g_nPixelShaderVer]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open shader file according to build target
|
||||||
|
bool ZZshCreateOpenShadersFile() {
|
||||||
|
std::string ShaderFileName("plugins/ps2hw_gl4.glsl");
|
||||||
|
int ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
|
||||||
|
struct stat sb;
|
||||||
|
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
||||||
|
// Each linux distributions have his rules for path so we give them the possibility to
|
||||||
|
// change it with compilation flags. -- Gregory
|
||||||
|
#ifdef GLSL_SHADER_DIR_COMPILATION
|
||||||
|
#define xGLSL_SHADER_DIR_str(s) GLSL_SHADER_DIR_str(s)
|
||||||
|
#define GLSL_SHADER_DIR_str(s) #s
|
||||||
|
ShaderFileName = string(xGLSL_SHADER_DIR_str(GLSL_SHADER_DIR_COMPILATION)) + "/ps2hw_gl4.glsl";
|
||||||
|
ShaderFD = open(ShaderFileName.c_str(), O_RDONLY);
|
||||||
|
#endif
|
||||||
|
if ((ShaderFD == -1) || (fstat(ShaderFD, &sb) == -1)) {
|
||||||
|
ZZLog::Error_Log("No source for %s: \n", ShaderFileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZshSourceSize = sb.st_size;
|
||||||
|
ZZshSource = (char*)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, ShaderFD, 0); // This function directly maped file into memory.
|
||||||
|
ZZshSource[ ZZshSourceSize - 1] = 0; // Made source null-terminated.
|
||||||
|
|
||||||
|
close(ShaderFD);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZZshExitCleaning() {
|
||||||
|
munmap(ZZshSource, ZZshSourceSize);
|
||||||
|
delete constant_buffer;
|
||||||
|
delete common_buffer;
|
||||||
|
delete vertex_buffer;
|
||||||
|
delete fragment_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable CG
|
||||||
|
void ZZshGLDisableProfile() { // This stop all other shader programs from running;
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
//Enable CG
|
||||||
|
void ZZshGLEnableProfile() {
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The same function for texture, also to cgGLEnable
|
||||||
|
void ZZshGLSetTextureParameter(ZZshParameter param, GLuint texobj, const char* name) {
|
||||||
|
g_cs.set_texture(param, texobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZZshGLSetTextureParameter(ZZshShaderLink prog, ZZshParameter param, GLuint texobj, const char* name) {
|
||||||
|
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link;
|
||||||
|
shader->set_texture(param, texobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is helper of cgGLSetParameter4fv, made for debug purpose.
|
||||||
|
// Name could be any string. We must use it on compilation time, because erroneus handler does not
|
||||||
|
// return name
|
||||||
|
void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* v, const char* name) {
|
||||||
|
if (prog.isFragment) {
|
||||||
|
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link;
|
||||||
|
shader->ZZshSetParameter4fv(param, v);
|
||||||
|
} else {
|
||||||
|
VERTEXSHADER* shader = (VERTEXSHADER*)prog.link;
|
||||||
|
shader->ZZshSetParameter4fv(param, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) {
|
||||||
|
g_cs.ZZshSetParameter4fv(param, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The same stuff, but also with retry of param, name should be USED name of param for prog.
|
||||||
|
void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name) {
|
||||||
|
if (prog.isFragment) {
|
||||||
|
FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link;
|
||||||
|
shader->ZZshSetParameter4fv(*param, v);
|
||||||
|
} else {
|
||||||
|
VERTEXSHADER* shader = (VERTEXSHADER*)prog.link;
|
||||||
|
shader->ZZshSetParameter4fv(*param, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used sometimes for color 1.
|
||||||
|
void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) {
|
||||||
|
// return;
|
||||||
|
ShaderHandleName = "Set Default One colot";
|
||||||
|
float4 v = float4 ( 1, 1, 1, 1 );
|
||||||
|
//ZZshSetParameter4fv(ptr.prog, ptr.sOneColor, v, "DegaultOne");
|
||||||
|
// FIXME context
|
||||||
|
ptr.ZZshSetParameter4fv(ptr.sOneColor, v);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const GLchar * EmptyVertex = "void main(void) {gl_Position = ftransform();}";
|
||||||
|
const GLchar * EmptyFragment = "void main(void) {gl_FragColor = gl_Color;}";
|
||||||
|
|
||||||
|
inline ZZshProgram UseEmptyProgram(const char* name, GLenum shaderType) {
|
||||||
|
GLuint shader = glCreateShader(shaderType);
|
||||||
|
if (shaderType == GL_VERTEX_SHADER)
|
||||||
|
glShaderSource(shader, 1, &EmptyVertex, NULL);
|
||||||
|
else
|
||||||
|
glShaderSource(shader, 1, &EmptyFragment, NULL);
|
||||||
|
|
||||||
|
glCompileShader(shader);
|
||||||
|
ZZshProgram prog = glCreateProgram();
|
||||||
|
glAttachShader(prog, shader);
|
||||||
|
glLinkProgram(prog);
|
||||||
|
if( !glIsProgram(prog) || glGetError() != GL_NO_ERROR ) {
|
||||||
|
ZZLog::Error_Log("Failed to load empty shader for %s:", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ZZLog::Error_Log("Used Empty program for %s... Ok.",name);
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZshShaderType ZZshGetShaderType(const char* name) {
|
||||||
|
if (strncmp(name, "TextureFog", 10) == 0) return ZZ_SH_TEXTURE_FOG;
|
||||||
|
if (strncmp(name, "Texture", 7) == 0) return ZZ_SH_TEXTURE;
|
||||||
|
if (strncmp(name, "RegularFog", 10) == 0) return ZZ_SH_REGULAR_FOG;
|
||||||
|
if (strncmp(name, "Regular", 7) == 0) return ZZ_SH_REGULAR;
|
||||||
|
if (strncmp(name, "Zero", 4) == 0) return ZZ_SH_ZERO;
|
||||||
|
return ZZ_SH_CRTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ZZshShader UseEmptyShader(const char* name, GLenum shaderType) {
|
||||||
|
GLuint shader = glCreateShader(shaderType);
|
||||||
|
if (shaderType == GL_VERTEX_SHADER)
|
||||||
|
glShaderSource(shader, 1, &EmptyVertex, NULL);
|
||||||
|
else
|
||||||
|
glShaderSource(shader, 1, &EmptyFragment, NULL);
|
||||||
|
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
ShaderNames[shader] = name;
|
||||||
|
ShaderTypes[shader] = ZZshGetShaderType(name);
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Used Empty shader for %s... Ok.",name);
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GetCompilationLog(GLuint shader) {
|
||||||
|
GLint CompileStatus;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &CompileStatus);
|
||||||
|
if (CompileStatus == GL_TRUE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int* lenght, infologlength;
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
|
char* InfoLog = new char[infologlength];
|
||||||
|
glGetShaderInfoLog(shader, infologlength, lenght, InfoLog);
|
||||||
|
ZZLog::Error_Log("Compiling... %d:\t %s", shader, InfoLog);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CompileShader(ZZshProgram& shader, const char* DefineString, const char* name, GLenum shaderType) {
|
||||||
|
const GLchar* ShaderSource[2];
|
||||||
|
ShaderSource[0] = (const GLchar*)DefineString;
|
||||||
|
ShaderSource[1] = (const GLchar*)ZZshSource;
|
||||||
|
|
||||||
|
shader = glCreateShader(shaderType);
|
||||||
|
glShaderSource(shader, 2, &ShaderSource[0], NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
ZZLog::Debug_Log("Creating shader %d for %s", shader, name);
|
||||||
|
|
||||||
|
if (!GetCompilationLog(shader)) {
|
||||||
|
ZZLog::Error_Log("Failed to compile shader for %s:", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderTypes[shader] = ZZshGetShaderType(name);
|
||||||
|
ShaderNames[shader] = name;
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool LoadShaderFromFile(ZZshShader& shader, const char* DefineString, const char* name, GLenum ShaderType) { // Linux specific, as I presume
|
||||||
|
if (!CompileShader(shader, DefineString, name, ShaderType)) {
|
||||||
|
ZZLog::Error_Log("Failed to compile shader for %s: ", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Used shader for %s... Ok",name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GetLinkLog(ZZshProgram prog) {
|
||||||
|
GLint LinkStatus;
|
||||||
|
glGetProgramiv(prog, GL_LINK_STATUS, &LinkStatus);
|
||||||
|
|
||||||
|
int unif, atrib;
|
||||||
|
glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &unif);
|
||||||
|
glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &atrib);
|
||||||
|
UNIFORM_ERROR_LOG("Uniforms %d, attributes %d", unif, atrib);
|
||||||
|
|
||||||
|
if (LinkStatus == GL_TRUE && glIsProgram(prog)) return true;
|
||||||
|
|
||||||
|
#if defined(DEVBUILD) || defined(_DEBUG)
|
||||||
|
int* lenght, infologlength;
|
||||||
|
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
|
char* InfoLog = new char[infologlength];
|
||||||
|
glGetProgramInfoLog(prog, infologlength, lenght, InfoLog);
|
||||||
|
if (!infologlength == 0)
|
||||||
|
ZZLog::Error_Log("Linking %d... %d:\t %s", prog, infologlength, InfoLog);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static bool ValidateProgram(ZZshProgram Prog) {
|
||||||
|
GLint isValid;
|
||||||
|
glGetProgramiv(Prog, GL_VALIDATE_STATUS, &isValid);
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
glValidateProgram(Prog);
|
||||||
|
int* lenght, infologlength;
|
||||||
|
glGetProgramiv(Prog, GL_INFO_LOG_LENGTH, &infologlength);
|
||||||
|
char* InfoLog = new char[infologlength];
|
||||||
|
glGetProgramInfoLog(Prog, infologlength, lenght, InfoLog);
|
||||||
|
ZZLog::Error_Log("Validation %d... %d:\t %s", Prog, infologlength, InfoLog);
|
||||||
|
}
|
||||||
|
return (isValid != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutParametersAndRun(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
|
||||||
|
UNIFORM_ERROR_LOG("Run program %s(%d) \t+\t%s(%d)", ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader);
|
||||||
|
|
||||||
|
glUseProgram(ZZshMainProgram);
|
||||||
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
ZZLog::Error_Log("Something weird happened on Linking stage.");
|
||||||
|
|
||||||
|
glUseProgram(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME context argument
|
||||||
|
int context = 0;
|
||||||
|
PutParametersInProgam(vs, ps, context);
|
||||||
|
|
||||||
|
ValidateProgram(ZZshMainProgram);
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateNewProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
|
||||||
|
ZZLog::Error_Log("\n---> New shader program %d, %s(%d) \t+\t%s(%d).", ZZshMainProgram, ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader);
|
||||||
|
|
||||||
|
if (vs->Shader != 0)
|
||||||
|
glAttachShader(ZZshMainProgram, vs->Shader);
|
||||||
|
if (ps->Shader != 0)
|
||||||
|
glAttachShader(ZZshMainProgram, ps->Shader);
|
||||||
|
|
||||||
|
glLinkProgram(ZZshMainProgram);
|
||||||
|
if (!GetLinkLog(ZZshMainProgram)) {
|
||||||
|
ZZLog::Error_Log("Main program linkage error, don't use any shader for this stage.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ZZshCheckShaderCompatibility(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
|
||||||
|
if (vs == NULL) return false;
|
||||||
|
if (vs->ShaderType == ZZ_SH_ZERO) return true; // ZeroPS is compatible with everything
|
||||||
|
if (ps == NULL) return false;
|
||||||
|
|
||||||
|
return (vs->ShaderType == ps->ShaderType);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZZshSetShader(VERTEXSHADER* vs, FRAGMENTSHADER* ps) {
|
||||||
|
if (!ZZshCheckShaderCompatibility(vs, ps)) // We don't need to link uncompatible shaders
|
||||||
|
return;
|
||||||
|
|
||||||
|
int vss = (vs!=NULL)?vs->Shader:0;
|
||||||
|
int pss = (ps!=NULL)?ps->Shader:0;
|
||||||
|
|
||||||
|
if (vss !=0 && pss != 0) {
|
||||||
|
if (CompiledPrograms[vss][pss] != 0 && glIsProgram(CompiledPrograms[vss][pss])) {
|
||||||
|
ZZshMainProgram = CompiledPrograms[vs->Shader][ps->Shader];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ZZshProgram NewProgram = glCreateProgram();
|
||||||
|
ZZshMainProgram = NewProgram;
|
||||||
|
CompiledPrograms[vss][pss] = NewProgram;
|
||||||
|
CreateNewProgram(vs, ps) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
PutParametersAndRun(vs, ps);
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZZshSetVertexShader(ZZshShaderLink prog) {
|
||||||
|
g_vsprog = prog;
|
||||||
|
ZZshSetShader((VERTEXSHADER*)(g_vsprog.link), (FRAGMENTSHADER*)(g_psprog.link)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZZshSetPixelShader(ZZshShaderLink prog) {
|
||||||
|
g_psprog = prog;
|
||||||
|
ZZshSetShader((VERTEXSHADER*)(g_vsprog.link), (FRAGMENTSHADER*)(g_psprog.link)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef GLSL4_API
|
||||||
|
static void init_shader() {
|
||||||
|
// Warning put same order than GLSL
|
||||||
|
constant_buffer = new GSUniformBufferOGL(0, sizeof(ConstantUniform));
|
||||||
|
common_buffer = new GSUniformBufferOGL(1, sizeof(GlobalUniform));
|
||||||
|
vertex_buffer = new GSUniformBufferOGL(2, sizeof(VertexUniform));
|
||||||
|
fragment_buffer = new GSUniformBufferOGL(3, sizeof(FragmentUniform));
|
||||||
|
|
||||||
|
constant_buffer->bind();
|
||||||
|
constant_buffer->upload((void*)&g_cs.uniform_buffer_constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutParametersInProgam(VERTEXSHADER* vs, FRAGMENTSHADER* ps, int context) {
|
||||||
|
|
||||||
|
common_buffer->bind();
|
||||||
|
common_buffer->upload((void*)&g_cs.uniform_buffer[context]);
|
||||||
|
|
||||||
|
vertex_buffer->bind();
|
||||||
|
vertex_buffer->upload((void*)&vs->uniform_buffer[context]);
|
||||||
|
|
||||||
|
fragment_buffer->bind();
|
||||||
|
fragment_buffer->upload((void*)&ps->uniform_buffer[context]);
|
||||||
|
|
||||||
|
// FIXME DEBUG
|
||||||
|
#ifdef _DEBUG
|
||||||
|
GLint cb_idx = glGetUniformBlockIndex(ZZshMainProgram, "constant_buffer");
|
||||||
|
GLint co_idx = glGetUniformBlockIndex(ZZshMainProgram, "common_buffer");
|
||||||
|
GLint fb_idx = glGetUniformBlockIndex(ZZshMainProgram, "fragment_buffer");
|
||||||
|
GLint vb_idx = glGetUniformBlockIndex(ZZshMainProgram, "vertex_buffer");
|
||||||
|
|
||||||
|
GLint debug;
|
||||||
|
|
||||||
|
ZZLog::Error_Log("NEW !!!");
|
||||||
|
if (cb_idx != GL_INVALID_INDEX) {
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, cb_idx, GL_UNIFORM_BLOCK_BINDING, &debug);
|
||||||
|
ZZLog::Error_Log("cb active : %d", debug);
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, cb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug);
|
||||||
|
ZZLog::Error_Log("size : %d", debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (co_idx != GL_INVALID_INDEX) {
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, co_idx, GL_UNIFORM_BLOCK_BINDING, &debug);
|
||||||
|
ZZLog::Error_Log("co active : %d", debug);
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, co_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug);
|
||||||
|
ZZLog::Error_Log("size : %d", debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vb_idx != GL_INVALID_INDEX) {
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, vb_idx, GL_UNIFORM_BLOCK_BINDING, &debug);
|
||||||
|
ZZLog::Error_Log("vb active : %d", debug);
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, vb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug);
|
||||||
|
ZZLog::Error_Log("size : %d", debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fb_idx != GL_INVALID_INDEX) {
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, fb_idx, GL_UNIFORM_BLOCK_BINDING, &debug);
|
||||||
|
ZZLog::Error_Log("fb active : %d", debug);
|
||||||
|
glGetActiveUniformBlockiv(ZZshMainProgram, fb_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &debug);
|
||||||
|
ZZLog::Error_Log("size : %d", debug);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_cs.enable_texture();
|
||||||
|
ps->enable_texture(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type)
|
||||||
|
{
|
||||||
|
// uniform parameters
|
||||||
|
GLint p;
|
||||||
|
pf->prog.link = (void*)pf; // Setting autolink
|
||||||
|
pf->prog.isFragment = true; // Setting autolink
|
||||||
|
pf->ShaderType = ShaderTypes[pf->Shader];
|
||||||
|
|
||||||
|
g_cs.set_texture(g_cs.sBlocks, ptexBlocks);
|
||||||
|
g_cs.set_texture(g_cs.sConv16to32, ptexConv16to32);
|
||||||
|
g_cs.set_texture(g_cs.sConv32to16, ptexConv32to16);
|
||||||
|
g_cs.set_texture(g_cs.sBilinearBlocks, ptexBilinearBlocks);
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupVertexProgramParameters(VERTEXSHADER* pf, int context)
|
||||||
|
{
|
||||||
|
GLint p;
|
||||||
|
pf->prog.link = (void*)pf; // Setting autolink
|
||||||
|
pf->prog.isFragment = false; // Setting autolink
|
||||||
|
pf->ShaderType = ShaderTypes[pf->Shader];
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
}
|
||||||
|
|
||||||
|
//const int GLSL_VERSION = 130; // Sampler2DRect appear in 1.3
|
||||||
|
const int GLSL_VERSION = 420;
|
||||||
|
|
||||||
|
// We use strictly compilation from source for GSLS
|
||||||
|
static __forceinline void GlslHeaderString(char* header_string, const char* name, const char* depth)
|
||||||
|
{
|
||||||
|
sprintf(header_string, "#version %d\n#define %s main\n%s\n", GLSL_VERSION, name, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __forceinline bool LOAD_VS(char* DefineString, const char* name, VERTEXSHADER& vertex, int shaderver, ZZshProfile context, const char* depth)
|
||||||
|
{
|
||||||
|
bool flag;
|
||||||
|
char temp[200];
|
||||||
|
GlslHeaderString(temp, name, depth);
|
||||||
|
sprintf(DefineString, "%s#define VERTEX_SHADER 1\n#define CTX %d\n", temp, context * NOCONTEXT);
|
||||||
|
//ZZLog::WriteLn("Define for VS == '%s'", DefineString);
|
||||||
|
flag = LoadShaderFromFile(vertex.Shader, DefineString, name, GL_VERTEX_SHADER);
|
||||||
|
SetupVertexProgramParameters(&vertex, context);
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __forceinline bool LOAD_PS(char* DefineString, const char* name, FRAGMENTSHADER& fragment, int shaderver, ZZshProfile context, const char* depth)
|
||||||
|
{
|
||||||
|
bool flag;
|
||||||
|
char temp[200];
|
||||||
|
GlslHeaderString(temp, name, depth);
|
||||||
|
sprintf(DefineString, "%s#define FRAGMENT_SHADER 1\n#define CTX %d\n", temp, context * NOCONTEXT);
|
||||||
|
//ZZLog::WriteLn("Define for PS == '%s'", DefineString);
|
||||||
|
|
||||||
|
flag = LoadShaderFromFile(fragment.Shader, DefineString, name, GL_FRAGMENT_SHADER);
|
||||||
|
SetupFragmentProgramParameters(&fragment, context, 0);
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool LoadEffects()
|
||||||
|
{
|
||||||
|
// clear the textures
|
||||||
|
for(u32 i = 0; i < ArraySize(ppsTexture); ++i) {
|
||||||
|
SAFE_RELEASE_PROG(ppsTexture[i].prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _DEBUG
|
||||||
|
memset(ppsTexture, 0, sizeof(ppsTexture));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZZshLoadExtraEffects() {
|
||||||
|
bool bLoadSuccess = true;
|
||||||
|
char DefineString[DEFINE_STRING_SIZE] = "";
|
||||||
|
const char* writedepth = "#define WRITE_DEPTH 1\n"; // should we write depth field
|
||||||
|
|
||||||
|
|
||||||
|
const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" };
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 * i], cgvProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 1 ], cgvProf, 1, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 8 ], cgvProf, 0, writedepth)) bLoadSuccess = false;
|
||||||
|
if (!LOAD_VS(DefineString, pvsshaders[i], pvsStore[2 *i + 8 + 1], cgvProf, 1, writedepth)) bLoadSuccess = false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
pvs[i] = pvsStore[i].prog;
|
||||||
|
|
||||||
|
if (!LOAD_VS(DefineString, "BitBltVS", pvsBitBlt, cgvProf, 0, "")) bLoadSuccess = false;
|
||||||
|
GLint p;
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "RegularFogPS", ppsRegular[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
|
||||||
|
if( conf.mrtdepth ) {
|
||||||
|
if (!LOAD_PS(DefineString, "RegularPS", ppsRegular[2], cgfProf, 0, writedepth)) bLoadSuccess = false;
|
||||||
|
if (!bLoadSuccess) conf.mrtdepth = 0;
|
||||||
|
|
||||||
|
if (!LOAD_PS(DefineString, "RegularFogPS", ppsRegular[3], cgfProf, 0, writedepth)) bLoadSuccess = false;
|
||||||
|
if (!bLoadSuccess) conf.mrtdepth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LOAD_PS(DefineString, "BitBltPS", ppsBitBlt[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "BitBltAAPS", ppsBitBlt[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!bLoadSuccess) {
|
||||||
|
ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS.");
|
||||||
|
if (!LOAD_PS(DefineString, "BitBltPS", ppsBitBlt[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LOAD_PS(DefineString, "BitBltDepthPS", ppsBitBltDepth, cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCTargPS", ppsCRTCTarg[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCTargInterPS", ppsCRTCTarg[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
|
||||||
|
g_bCRTCBilinear = true;
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCPS", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if( !bLoadSuccess ) {
|
||||||
|
// switch to simpler
|
||||||
|
g_bCRTCBilinear = false;
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCPS_Nearest", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCInterPS_Nearest", ppsCRTC[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!LOAD_PS(DefineString, "CRTCInterPS", ppsCRTC[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bLoadSuccess )
|
||||||
|
ZZLog::Error_Log("Failed to create CRTC shaders.");
|
||||||
|
|
||||||
|
// if (!LOAD_PS(DefineString, "CRTC24PS", ppsCRTC24[0], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
// if (!LOAD_PS(DefineString, "CRTC24InterPS", ppsCRTC24[1], cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "ZeroPS", ppsOne, cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "BaseTexturePS", ppsBaseTexture, cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "Convert16to32PS", ppsConvert16to32, cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
if (!LOAD_PS(DefineString, "Convert32to16PS", ppsConvert32to16, cgfProf, 0, "")) bLoadSuccess = false;
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const static char* g_pPsTexWrap[] = { "#define REPEAT 1\n", "#define CLAMP 1\n", "#define REGION_REPEAT 1\n", "" };
|
||||||
|
|
||||||
|
static ZZshShader LoadShaderFromType(const char* srcdir, const char* srcfile, int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context) {
|
||||||
|
|
||||||
|
assert( texwrap < NUM_TEXWRAPS);
|
||||||
|
assert( type < NUM_TYPES );
|
||||||
|
//ZZLog::Error_Log("\n");
|
||||||
|
|
||||||
|
ZZshProgram prog;
|
||||||
|
|
||||||
|
char* name = new char[MAX_SHADER_NAME_SIZE];
|
||||||
|
sprintf(name, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]);
|
||||||
|
|
||||||
|
ZZLog::Debug_Log("Starting shader for %s", name);
|
||||||
|
|
||||||
|
const char* AddWrap = g_pPsTexWrap[texwrap];
|
||||||
|
const char* AddDepth = writedepth?"#define WRITE_DEPTH 1\n":"";
|
||||||
|
const char* AddAEM = testaem?"#define TEST_AEM 1\n":"";
|
||||||
|
const char* AddExcolor = exactcolor?"#define EXACT_COLOR 1\n":"";
|
||||||
|
const char* AddAccurate = (ps & SHADER_ACCURATE)?"#define ACCURATE_DECOMPRESSION 1\n":"";
|
||||||
|
char DefineString[DEFINE_STRING_SIZE] = "";
|
||||||
|
char temp[200];
|
||||||
|
GlslHeaderString(temp, name, AddWrap);
|
||||||
|
sprintf(DefineString, "%s#define FRAGMENT_SHADER 1\n%s%s%s%s\n#define CTX %d\n", temp, AddDepth, AddAEM, AddExcolor, AddAccurate, context * NOCONTEXT);
|
||||||
|
|
||||||
|
ZZshShader shader;
|
||||||
|
if (!CompileShader(shader, DefineString, name, GL_FRAGMENT_SHADER))
|
||||||
|
return UseEmptyShader(name, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
ZZLog::Debug_Log("Used shader for type:%d filter:%d wrap:%d for:%d depth:%d aem:%d color:%d decompression:%d ctx:%d... Ok \n", type, texfilter, texwrap, fog, writedepth, testaem, exactcolor, ps, context);
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed)
|
||||||
|
{
|
||||||
|
int texwrap;
|
||||||
|
|
||||||
|
assert( texfilter < NUM_FILTERS );
|
||||||
|
//assert( g_nPixelShaderVer == SHADER_30 );
|
||||||
|
if( clamp.wms == clamp.wmt ) {
|
||||||
|
switch( clamp.wms ) {
|
||||||
|
case 0: texwrap = TEXWRAP_REPEAT; break;
|
||||||
|
case 1: texwrap = TEXWRAP_CLAMP; break;
|
||||||
|
case 2: texwrap = TEXWRAP_CLAMP; break;
|
||||||
|
default:
|
||||||
|
texwrap = TEXWRAP_REGION_REPEAT; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( clamp.wms==3||clamp.wmt==3)
|
||||||
|
texwrap = TEXWRAP_REGION_REPEAT;
|
||||||
|
else
|
||||||
|
texwrap = TEXWRAP_REPEAT_CLAMP;
|
||||||
|
|
||||||
|
int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);
|
||||||
|
|
||||||
|
if( pbFailed != NULL ) *pbFailed = false;
|
||||||
|
|
||||||
|
FRAGMENTSHADER* pf = ppsTexture+index;
|
||||||
|
|
||||||
|
if (ZZshExistProgram(pf))
|
||||||
|
{
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
pf->Shader = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context);
|
||||||
|
|
||||||
|
if (ZZshExistProgram(pf)) {
|
||||||
|
SetupFragmentProgramParameters(pf, context, type);
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
if( glGetError() != GL_NO_ERROR ) {
|
||||||
|
ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
|
||||||
|
if (pbFailed != NULL ) *pbFailed = true;
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt);
|
||||||
|
if( pbFailed != NULL ) *pbFailed = true;
|
||||||
|
|
||||||
|
GL_REPORT_ERRORD();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GLSL_API
|
|
@ -101,7 +101,7 @@ bool SaveRenderTarget(const char* filename, int width, int height, int jpeg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save selected texture as TGA
|
// Save selected texture as TGA
|
||||||
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height)
|
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height, int ext_format)
|
||||||
{
|
{
|
||||||
vector<u32> data(width*height);
|
vector<u32> data(width*height);
|
||||||
glBindTexture(textarget, tex);
|
glBindTexture(textarget, tex);
|
||||||
|
@ -109,7 +109,19 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR) return false;
|
if (glGetError() != GL_NO_ERROR) return false;
|
||||||
|
|
||||||
return SaveTGA(filename, width, height, &data[0]);
|
if (ext_format == EXT_BMP)
|
||||||
|
return SaveBMP(filename, width, height, &data[0]);
|
||||||
|
else if (ext_format == EXT_TGA)
|
||||||
|
return SaveTGA(filename, width, height, &data[0]);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save image as BMP
|
||||||
|
bool SaveBMP(const char* filename, int width, int height, void* pdata)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save image as JPEG
|
// save image as JPEG
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
|
|
||||||
void SaveSnapshot(const char* filename);
|
void SaveSnapshot(const char* filename);
|
||||||
bool SaveRenderTarget(const char* filename, int width, int height, int jpeg);
|
bool SaveRenderTarget(const char* filename, int width, int height, int jpeg);
|
||||||
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
|
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height, int ext_format = 0);
|
||||||
bool SaveJPEG(const char* filename, int width, int height, const void* pdata, int quality);
|
bool SaveJPEG(const char* filename, int width, int height, const void* pdata, int quality);
|
||||||
bool SaveTGA(const char* filename, int width, int height, void* pdata);
|
bool SaveTGA(const char* filename, int width, int height, void* pdata);
|
||||||
|
bool SaveBMP(const char* filename, int width, int height, void* pdata);
|
||||||
void Stop_Avi();
|
void Stop_Avi();
|
||||||
void Delete_Avi_Capture();
|
void Delete_Avi_Capture();
|
||||||
|
|
||||||
|
@ -32,4 +33,10 @@ void StartCapture();
|
||||||
void StopCapture();
|
void StopCapture();
|
||||||
void CaptureFrame();
|
void CaptureFrame();
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EXT_TGA = 0,
|
||||||
|
EXT_BMP = 1,
|
||||||
|
EXT_JPG = 2
|
||||||
|
};
|
||||||
|
|
||||||
#endif // ZZOGLSHOOTS_H_INCLUDED
|
#endif // ZZOGLSHOOTS_H_INCLUDED
|
||||||
|
|
|
@ -0,0 +1,839 @@
|
||||||
|
//#version 420 Keep it for text editor detection
|
||||||
|
// Cg Shaders for PS2 GS emulation
|
||||||
|
|
||||||
|
// divides by z for every pixel, instead of in vertex shader
|
||||||
|
// fixes kh textures
|
||||||
|
|
||||||
|
#extension ARB_texture_rectangle: require
|
||||||
|
#define GL_compatibility_profile 1
|
||||||
|
#define PERSPECTIVE_CORRECT_TEX
|
||||||
|
|
||||||
|
// When writting GLSL code we should change variables in code according to denominator
|
||||||
|
// Not than in and out variables are differ!
|
||||||
|
// in POSITION set by glVertexPointer goes to gl_Vertex;
|
||||||
|
// out POSITION goes to gl_position
|
||||||
|
// in COLOR0 gl_Color
|
||||||
|
// out COLOR0 gl_FrontColor
|
||||||
|
// in TEXCOORD0 gl_MultiTexCoord0
|
||||||
|
// out TEXCOORD0 gl_TexCoord[0]
|
||||||
|
|
||||||
|
//in Fragments:
|
||||||
|
// in TEXCOORD0 gl_TexCoord[0]
|
||||||
|
// out COLOR0 gl_FragData[0]
|
||||||
|
|
||||||
|
//#define TEST_AEM // tests AEM for black pixels
|
||||||
|
//#define REGION_REPEAT // set if texture wrapping mode is region repeat
|
||||||
|
//#define WRITE_DEPTH // set if depth is also written in a MRT
|
||||||
|
//#define ACCURATE_DECOMPRESSION // set for less capable hardware ATI Radeon 9000 series
|
||||||
|
//#define EXACT_COLOR // make sure the output color is clamped to 1/255 boundaries (for alpha testing)
|
||||||
|
|
||||||
|
#ifdef PERSPECTIVE_CORRECT_TEX
|
||||||
|
#define TEX_XY tex.xy/tex.z
|
||||||
|
#define TEX_DECL vec4
|
||||||
|
#else
|
||||||
|
#define TEX_XY tex.xy
|
||||||
|
#define TEX_DECL vec4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WRITE_DEPTH
|
||||||
|
#define DOZWRITE(x) x
|
||||||
|
#else
|
||||||
|
#define DOZWRITE(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NVidia CG-data types
|
||||||
|
#define half2 vec2
|
||||||
|
#define half3 vec3
|
||||||
|
#define half4 vec4
|
||||||
|
#define float2 vec2
|
||||||
|
#define float3 vec3
|
||||||
|
#define float4 vec4
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Texture SAMPLER
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// // main ps2 memory, each pixel is stored in 32bit color
|
||||||
|
// uniform sampler2DRect g_sMemory[2];
|
||||||
|
//
|
||||||
|
// // used to get the tiled offset into a page given the linear offset
|
||||||
|
// uniform sampler2DRect g_sSrcFinal;
|
||||||
|
// uniform sampler2D g_sBlocks;
|
||||||
|
// uniform sampler2D g_sBilinearBlocks;
|
||||||
|
// uniform sampler2D g_sConv16to32;
|
||||||
|
// uniform sampler3D g_sConv32to16;
|
||||||
|
// uniform sampler2DRect g_sBitwiseANDX;
|
||||||
|
// uniform sampler2DRect g_sBitwiseANDY;
|
||||||
|
// uniform sampler2DRect g_sInterlace;
|
||||||
|
//
|
||||||
|
// // used only on rare cases where the render target is PSMT8H
|
||||||
|
// uniform sampler2D g_sCLUT;
|
||||||
|
// main ps2 memory, each pixel is stored in 32bit color
|
||||||
|
layout(binding = 0) uniform sampler2DRect g_sMemory; // dual context
|
||||||
|
|
||||||
|
// used to get the tiled offset into a page given the linear offset
|
||||||
|
layout(binding = 1) uniform sampler2DRect g_sSrcFinal;
|
||||||
|
layout(binding = 2) uniform sampler2D g_sBlocks;
|
||||||
|
layout(binding = 3) uniform sampler2D g_sBilinearBlocks;
|
||||||
|
layout(binding = 4) uniform sampler2D g_sConv16to32;
|
||||||
|
layout(binding = 5) uniform sampler3D g_sConv32to16;
|
||||||
|
layout(binding = 6) uniform sampler2DRect g_sBitwiseANDX;
|
||||||
|
layout(binding = 7) uniform sampler2DRect g_sBitwiseANDY;
|
||||||
|
layout(binding = 8) uniform sampler2DRect g_sInterlace;
|
||||||
|
|
||||||
|
// used only on rare cases where the render target is PSMT8H
|
||||||
|
layout(binding = 9) uniform sampler2D g_sCLUT;
|
||||||
|
|
||||||
|
// Uniform buffer
|
||||||
|
layout(std140, binding = 0) uniform constant_buffer
|
||||||
|
{
|
||||||
|
// Both shader
|
||||||
|
// .z is used for the addressing fn
|
||||||
|
// FIXME: not same value between c and shader...
|
||||||
|
// float4 g_fBilinear = float4(-0.7f, -0.65f, 0.9,1/32767.0f);
|
||||||
|
float4 g_fBilinear;
|
||||||
|
float4 g_fZBias;
|
||||||
|
float4 g_fc0;
|
||||||
|
float4 g_fMult;
|
||||||
|
// Vertex
|
||||||
|
float4 g_fZ; // transforms d3dcolor z into float z
|
||||||
|
float4 g_fZMin;
|
||||||
|
float4 g_fZNorm;
|
||||||
|
// Pixel
|
||||||
|
half4 g_fExactColor;
|
||||||
|
};
|
||||||
|
layout(std140, binding = 1) uniform common_buffer
|
||||||
|
{
|
||||||
|
float4 g_fPosXY;
|
||||||
|
float4 g_fFogColor;
|
||||||
|
};
|
||||||
|
layout(std140, binding = 2) uniform vertex_buffer
|
||||||
|
{
|
||||||
|
float4 g_fBitBltPos;
|
||||||
|
float4 g_fBitBltTex;
|
||||||
|
float4 g_fBitBltTrans;
|
||||||
|
};
|
||||||
|
layout(std140, binding = 3) uniform fragment_buffer
|
||||||
|
{
|
||||||
|
half4 fTexAlpha2;
|
||||||
|
|
||||||
|
float4 g_fTexOffset; // converts the page and block offsets into the mem addr/1024
|
||||||
|
float4 g_fTexDims; // mult by tex dims when accessing the block texture
|
||||||
|
float4 g_fTexBlock;
|
||||||
|
|
||||||
|
float4 g_fClampExts; // if clamping the texture, use (minu, minv, maxu, maxv)
|
||||||
|
float4 TexWrapMode; // 0 - repeat/clamp, 1 - region rep (use fRegRepMask)
|
||||||
|
|
||||||
|
float4 g_fRealTexDims; // tex dims used for linear filtering (w,h,1/w,1/h)
|
||||||
|
|
||||||
|
// (alpha0, alpha1, 1 if highlight2 and tcc is rgba, 1-y)
|
||||||
|
half4 g_fTestBlack; // used for aem bit
|
||||||
|
|
||||||
|
float4 g_fPageOffset;
|
||||||
|
|
||||||
|
half4 fTexAlpha;
|
||||||
|
|
||||||
|
float4 g_fInvTexDims; // similar to g_fClutOff
|
||||||
|
|
||||||
|
// used for rectblitting
|
||||||
|
float4 g_fBitBltZ;
|
||||||
|
|
||||||
|
half4 g_fOneColor; // col*.xxxy+.zzzw
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// given a local tex coord, returns the coord in the memory
|
||||||
|
float2 ps2memcoord(float2 realtex)
|
||||||
|
{
|
||||||
|
float4 off;
|
||||||
|
|
||||||
|
// block off
|
||||||
|
realtex.xy = realtex.xy * g_fTexDims.xy + g_fTexDims.zw;
|
||||||
|
realtex.xy = (realtex.xy - fract(realtex.xy)) * g_fMult.zw;
|
||||||
|
float2 fblock = fract(realtex.xy);
|
||||||
|
off.xy = realtex.xy-fblock.xy;
|
||||||
|
|
||||||
|
#ifdef ACCURATE_DECOMPRESSION
|
||||||
|
off.zw = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).ar;
|
||||||
|
off.x = dot(off.xy, g_fTexOffset.xy);
|
||||||
|
float r = g_fTexOffset.w;
|
||||||
|
float f = fract(off.x);
|
||||||
|
float fadd = g_fTexOffset.z * off.z;
|
||||||
|
off.w = off.x + fadd + r;
|
||||||
|
off.x = fract(f + fadd + r);
|
||||||
|
off.w -= off.x ;
|
||||||
|
#else
|
||||||
|
off.z = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).a;
|
||||||
|
|
||||||
|
// combine the two
|
||||||
|
off.x = dot(off.xyz, g_fTexOffset.xyz)+g_fTexOffset.w;
|
||||||
|
off.x = modf(off.x, off.w);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
off.xy = off.xw * g_fPageOffset.zy + g_fPageOffset.wx;
|
||||||
|
//off.y = off.w * g_fPageOffset.y + g_fPageOffset.x;
|
||||||
|
return off.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all texcoords for bilinear filtering
|
||||||
|
// assume that orgtex are already on boundaries
|
||||||
|
void ps2memcoord4(float4 orgtex, out float4 off0, out float4 off1)
|
||||||
|
{
|
||||||
|
//float4 off0, off1, off2, off3;
|
||||||
|
float4 realtex;
|
||||||
|
|
||||||
|
// block off
|
||||||
|
realtex = (orgtex * g_fTexDims.xyxy + g_fTexDims.zwzw);// * g_fMult.zwzw;
|
||||||
|
float4 fblock = fract(realtex.xyzw);
|
||||||
|
float4 ftransblock = g_fTexBlock.xyxy*fblock + g_fTexBlock.zwzw;
|
||||||
|
realtex -= fblock;
|
||||||
|
|
||||||
|
float4 transvals = g_fTexOffset.x * realtex.xzxz + g_fTexOffset.y * realtex.yyww + g_fTexOffset.w;
|
||||||
|
|
||||||
|
float4 colors;// = texture(g_sBilinearBlocks, ftransblock.xy);
|
||||||
|
|
||||||
|
// this is faster on ffx ingame
|
||||||
|
colors.x = texture(g_sBlocks, ftransblock.xy).a;
|
||||||
|
colors.y = texture(g_sBlocks, ftransblock.zy).a;
|
||||||
|
colors.z = texture(g_sBlocks, ftransblock.xw).a;
|
||||||
|
colors.w = texture(g_sBlocks, ftransblock.zw).a;
|
||||||
|
|
||||||
|
float4 fr, rem;
|
||||||
|
|
||||||
|
#ifdef ACCURATE_DECOMPRESSION
|
||||||
|
fr = fract(transvals);
|
||||||
|
float4 fadd = colors * g_fTexOffset.z;
|
||||||
|
rem = transvals + fadd;
|
||||||
|
fr = fract(fr + fadd);
|
||||||
|
rem -= fr;
|
||||||
|
#else
|
||||||
|
transvals += colors * g_fTexOffset.z;
|
||||||
|
|
||||||
|
fr = modf(transvals, rem);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rem = rem * g_fPageOffset.y + g_fPageOffset.x;
|
||||||
|
fr = fr * g_fPageOffset.z + g_fPageOffset.w;
|
||||||
|
|
||||||
|
// combine
|
||||||
|
off0 = g_fc0.yxyx * fr.xxyy + g_fc0.xyxy * rem.xxyy;
|
||||||
|
off1 = g_fc0.yxyx * fr.zzww + g_fc0.xyxy * rem.zzww;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps2memcoord4_fast(float4 orgtex, out float4 off0, out float4 off1)
|
||||||
|
{
|
||||||
|
float4 realtex;
|
||||||
|
|
||||||
|
realtex = (orgtex * g_fTexDims.xyxy + g_fTexDims.zwzw);// * g_fMult.zwzw;
|
||||||
|
float4 fblock = fract(realtex.xyzw);
|
||||||
|
float2 ftransblock = g_fTexBlock.xy*fblock.xy + g_fTexBlock.zw;
|
||||||
|
realtex -= fblock;
|
||||||
|
|
||||||
|
float4 transvals = g_fTexOffset.x * realtex.xzxz + g_fTexOffset.y * realtex.yyww + g_fTexOffset.w;
|
||||||
|
|
||||||
|
float4 colors = texture(g_sBilinearBlocks, ftransblock.xy);
|
||||||
|
float4 fr, rem;
|
||||||
|
|
||||||
|
#ifdef ACCURATE_DECOMPRESSION
|
||||||
|
fr = fract(transvals);
|
||||||
|
float4 fadd = colors * g_fTexOffset.z;
|
||||||
|
rem = transvals + fadd;
|
||||||
|
fr = fract(fr + fadd);
|
||||||
|
rem -= fr;
|
||||||
|
#else
|
||||||
|
transvals += colors * g_fTexOffset.z;
|
||||||
|
|
||||||
|
fr = modf(transvals, rem);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rem = rem * g_fPageOffset.y + g_fPageOffset.x;
|
||||||
|
fr = fr * g_fPageOffset.z;
|
||||||
|
|
||||||
|
off0 = g_fc0.yxyx * fr.xxyy + g_fc0.xyxy * rem.xxyy;
|
||||||
|
off1 = g_fc0.yxyx * fr.zzww + g_fc0.xyxy * rem.zzww;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapping modes
|
||||||
|
#if defined(REPEAT)
|
||||||
|
|
||||||
|
float2 ps2addr(float2 coord)
|
||||||
|
{
|
||||||
|
return fract(coord.xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CLAMP)
|
||||||
|
|
||||||
|
float2 ps2addr(float2 coord)
|
||||||
|
{
|
||||||
|
return clamp(coord.xy, g_fClampExts.xy, g_fClampExts.zw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(REGION_REPEAT)
|
||||||
|
|
||||||
|
// computes the local tex coord along with addressing modes
|
||||||
|
float2 ps2addr(float2 coord)
|
||||||
|
{
|
||||||
|
float2 final = fract(clamp(coord.xy, g_fClampExts.xy, g_fClampExts.zw));
|
||||||
|
|
||||||
|
if( TexWrapMode.x > g_fBilinear.z ) // region repeat mode for x (umsk&x)|ufix
|
||||||
|
final.x = texture(g_sBitwiseANDX, abs(coord.x)*TexWrapMode.zx).x * g_fClampExts.x + g_fClampExts.z;
|
||||||
|
if( TexWrapMode.y > g_fBilinear.z ) // region repeat mode for x (vmsk&x)|vfix
|
||||||
|
final.y = texture(g_sBitwiseANDY, abs(coord.y)*TexWrapMode.wy).x * g_fClampExts.y + g_fClampExts.w;
|
||||||
|
|
||||||
|
return final;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
float2 ps2addr(float2 coord)
|
||||||
|
{
|
||||||
|
return fract(clamp(coord.xy, g_fClampExts.xy, g_fClampExts.zw));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
half4 tex2DPS_32(float2 tex0)
|
||||||
|
{
|
||||||
|
return texture(g_sMemory, ps2memcoord(tex0).xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// use when texture is not tiled -- shader 1
|
||||||
|
half4 tex2DPS_tex32(float2 tex0)
|
||||||
|
{
|
||||||
|
return texture(g_sMemory, g_fTexDims.xy*tex0+g_fTexDims.zw)*g_fZBias.zzzw+g_fPageOffset.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use when texture is not tiled -- shader 2
|
||||||
|
half4 tex2DPS_clut32(float2 tex0)
|
||||||
|
{
|
||||||
|
float index = texture(g_sMemory, g_fTexDims.xy*tex0+g_fTexDims.zw).a+g_fPageOffset.w;
|
||||||
|
return texture(g_sCLUT, index*g_fExactColor.xz+g_fExactColor.yz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader 3
|
||||||
|
// use when texture is not tiled and converting from 32bit to 16bit
|
||||||
|
// don't convert on the block level, only on the column level
|
||||||
|
// so every other 8 pixels, use the upper bits instead of lower
|
||||||
|
half4 tex2DPS_tex32to16(float2 tex0)
|
||||||
|
{
|
||||||
|
bool upper = false;
|
||||||
|
tex0.y += g_fPageOffset.z;
|
||||||
|
float2 ffrac = mod(tex0, g_fTexOffset.xy);
|
||||||
|
tex0.xy = g_fc0.ww * (tex0.xy + ffrac);
|
||||||
|
if( ffrac.x > g_fTexOffset.z ) {
|
||||||
|
tex0.x -= g_fTexOffset.z;
|
||||||
|
upper = true;
|
||||||
|
}
|
||||||
|
if( ffrac.y >= g_fTexOffset.w ) {
|
||||||
|
tex0.y -= g_fTexOffset.w;
|
||||||
|
tex0.x += g_fc0.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
half4 color = texture(g_sMemory, g_fTexDims.xy*tex0+g_fTexDims.zw)*g_fZBias.zzzw+g_fPageOffset.w;
|
||||||
|
float2 uv = upper ? color.xw : color.zy;
|
||||||
|
return texture(g_sConv16to32, uv+g_fPageOffset.xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader 4
|
||||||
|
// used when a 16 bit texture is used an 8h
|
||||||
|
half4 tex2DPS_tex16to8h(float2 tex0)
|
||||||
|
{
|
||||||
|
float4 final;
|
||||||
|
float2 ffrac = mod(tex0+g_fPageOffset.zw, g_fTexOffset.xy);
|
||||||
|
tex0.xy = g_fPageOffset.xy * tex0.xy - ffrac * g_fc0.yw;
|
||||||
|
|
||||||
|
if( ffrac.x > g_fTexOffset.x*g_fc0.w )
|
||||||
|
tex0.x += g_fTexOffset.x*g_fc0.w;
|
||||||
|
if( tex0.x >= g_fc0.y ) tex0 += g_fTexOffset.zw;
|
||||||
|
|
||||||
|
float4 upper = texture(g_sMemory, g_fTexDims.xy*tex0+g_fTexDims.zw);
|
||||||
|
|
||||||
|
// only need alpha
|
||||||
|
float index = texture(g_sConv32to16, upper.zyx-g_fc0.z).y + upper.w*g_fc0.w*g_fc0.w;
|
||||||
|
return texture(g_sCLUT, index+g_fExactColor.yz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader 5
|
||||||
|
// used when a 16 bit texture is used a 32bit one
|
||||||
|
half4 tex2DPS_tex16to32(float2 tex0)
|
||||||
|
{
|
||||||
|
float4 final;
|
||||||
|
float2 ffrac = mod(tex0+g_fPageOffset.zw, g_fTexOffset.xy);
|
||||||
|
//tex0.xy = g_fPageOffset.xy * tex0.xy - ffrac * g_fc0.yw;
|
||||||
|
tex0.y += g_fPageOffset.y * ffrac.y;
|
||||||
|
|
||||||
|
if( ffrac.x > g_fTexOffset.z ) {
|
||||||
|
tex0.x -= g_fTexOffset.z;
|
||||||
|
tex0.y += g_fTexOffset.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fconst = g_fc0.w*g_fc0.w;
|
||||||
|
float4 lower = texture(g_sSrcFinal, g_fTexDims.xy*tex0);
|
||||||
|
float4 upper = texture(g_sMemory, g_fTexDims.xy*tex0+g_fTexDims.zw);
|
||||||
|
|
||||||
|
final.zy = texture(g_sConv32to16, lower.zyx).xy + lower.ww*fconst;
|
||||||
|
final.xw = texture(g_sConv32to16, upper.zyx).xy + upper.ww*fconst;
|
||||||
|
return final;
|
||||||
|
}
|
||||||
|
|
||||||
|
half4 tex2DPS_tex16to32h(float2 tex0)
|
||||||
|
{
|
||||||
|
float4 final = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
return final;
|
||||||
|
}
|
||||||
|
|
||||||
|
//half4 f;
|
||||||
|
//f.w = old.y > (127.2f/255.0f) ? 1 : 0;
|
||||||
|
//old.y -= 0.5f * f.w;
|
||||||
|
//f.xyz = fract(old.yyx*half3(2.002*255.0f/256.0f, 64.025f*255.0f/256.0f, 8.002*255.0f/256.0f));
|
||||||
|
//f.y += old.x * (0.25f*255.0f/256.0f);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// calculates the texture color
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
#define decl_ps2shade(num) \
|
||||||
|
decl_ps2shade_##num(_32) \
|
||||||
|
decl_ps2shade_##num(_tex32) \
|
||||||
|
decl_ps2shade_##num(_clut32) \
|
||||||
|
decl_ps2shade_##num(_tex32to16) \
|
||||||
|
decl_ps2shade_##num(_tex16to8h) \
|
||||||
|
decl_ps2shade_##num(_tex16to32h)
|
||||||
|
|
||||||
|
// nearest
|
||||||
|
#define decl_ps2shade_0(bit) \
|
||||||
|
float4 ps2shade0##bit( TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return tex2DPS##bit( ps2addr(TEX_XY)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// do fast memcoord4 calcs when textures behave well
|
||||||
|
#ifdef REPEAT
|
||||||
|
#define PS2MEMCOORD4 ps2memcoord4
|
||||||
|
#else
|
||||||
|
#define PS2MEMCOORD4 ps2memcoord4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define decl_BilinearFilter(bit, addrfn) \
|
||||||
|
half4 BilinearFilter##bit(float2 tex0) \
|
||||||
|
{ \
|
||||||
|
float4 off0, off1; \
|
||||||
|
float4 ftex; \
|
||||||
|
float2 ffrac; \
|
||||||
|
ftex.xy = tex0 + g_fBilinear.xy * g_fRealTexDims.zw; \
|
||||||
|
ffrac = fract(ftex.xy*g_fRealTexDims.xy); \
|
||||||
|
ftex.xy -= ffrac.xy * g_fRealTexDims.zw; \
|
||||||
|
\
|
||||||
|
ftex.zw = ps2addr(ftex.xy + g_fRealTexDims.zw); \
|
||||||
|
ftex.xy = ps2addr(ftex.xy); \
|
||||||
|
\
|
||||||
|
PS2MEMCOORD4(ftex, off0, off1); \
|
||||||
|
half4 c0 = texture(g_sMemory, off0.xy); \
|
||||||
|
half4 c1 = texture(g_sMemory, off0.zw); \
|
||||||
|
half4 c2 = texture(g_sMemory, off1.xy); \
|
||||||
|
half4 c3 = texture(g_sMemory, off1.zw); \
|
||||||
|
return mix( mix(c0, c1, vec4(ffrac.x)), mix(c2, c3, ffrac.x), vec4(ffrac.y) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
decl_BilinearFilter(_32, ps2addr)
|
||||||
|
decl_BilinearFilter(_tex32, ps2addr)
|
||||||
|
decl_BilinearFilter(_clut32, ps2addr)
|
||||||
|
decl_BilinearFilter(_tex32to16, ps2addr)
|
||||||
|
decl_BilinearFilter(_tex16to8h, ps2addr)
|
||||||
|
decl_BilinearFilter(_tex16to32h, ps2addr)
|
||||||
|
|
||||||
|
//TODO! For mip maps, only apply when LOD >= 0
|
||||||
|
// lcm == 0, LOD = log(1/Q)*L + K, lcm == 1, LOD = K
|
||||||
|
|
||||||
|
// bilinear
|
||||||
|
#define decl_ps2shade_1(bit) \
|
||||||
|
half4 ps2shade1##bit(TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return BilinearFilter##bit(TEX_XY); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// nearest, mip nearest
|
||||||
|
#define decl_ps2shade_2(bit) \
|
||||||
|
half4 ps2shade2##bit(TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return tex2DPS##bit( ps2addr(TEX_XY)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// nearest, mip linear
|
||||||
|
#define decl_ps2shade_3(bit) \
|
||||||
|
half4 ps2shade3##bit(TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return tex2DPS##bit(ps2addr(TEX_XY)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// linear, mip nearest
|
||||||
|
#define decl_ps2shade_4(bit) \
|
||||||
|
half4 ps2shade4##bit(TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return BilinearFilter##bit(TEX_XY); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// linear, mip linear
|
||||||
|
#define decl_ps2shade_5(bit) \
|
||||||
|
half4 ps2shade5##bit(TEX_DECL tex) \
|
||||||
|
{ \
|
||||||
|
return BilinearFilter##bit(TEX_XY); \
|
||||||
|
}
|
||||||
|
|
||||||
|
decl_ps2shade(0)
|
||||||
|
decl_ps2shade(1)
|
||||||
|
decl_ps2shade(2)
|
||||||
|
decl_ps2shade(3)
|
||||||
|
decl_ps2shade(4)
|
||||||
|
decl_ps2shade(5)
|
||||||
|
|
||||||
|
|
||||||
|
half4 ps2CalcShade(half4 texcol, half4 color)
|
||||||
|
{
|
||||||
|
#ifdef TEST_AEM
|
||||||
|
if( dot(texcol.xyzw, g_fTestBlack.xyzw) <= g_fc0.z )
|
||||||
|
texcol.w = g_fc0.x;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
texcol.w = texcol.w * fTexAlpha.y + fTexAlpha.x;
|
||||||
|
|
||||||
|
texcol = texcol * (fTexAlpha2.zzzw * color + fTexAlpha2.xxxy) + fTexAlpha.zzzw * color.wwww;
|
||||||
|
|
||||||
|
return texcol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// final ops on the color
|
||||||
|
#ifdef EXACT_COLOR
|
||||||
|
|
||||||
|
half4 ps2FinalColor(half4 col)
|
||||||
|
{
|
||||||
|
// g_fOneColor has to scale by 255
|
||||||
|
half4 temp = col * g_fOneColor.xxxy + g_fOneColor.zzzw;
|
||||||
|
temp.w = floor(temp.w)*g_fExactColor.w;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
half4 ps2FinalColor(half4 col)
|
||||||
|
{
|
||||||
|
return col * g_fOneColor.xxxy + g_fOneColor.zzzw;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FRAGMENT_SHADER // This is code only for FRAGMENTS (pixel shader)
|
||||||
|
|
||||||
|
void RegularPS() {
|
||||||
|
// whenever outputting depth, make sure to mult by 255/256 and 1
|
||||||
|
gl_FragData[0] = ps2FinalColor(gl_Color);
|
||||||
|
DOZWRITE(gl_FragData[1] = gl_TexCoord[0];)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WRITE_DEPTH
|
||||||
|
|
||||||
|
#define DECL_TEXPS(num, bit) \
|
||||||
|
void Texture##num##bit##PS() \
|
||||||
|
{ \
|
||||||
|
gl_FragData[0] = ps2FinalColor(ps2CalcShade(ps2shade##num##bit(gl_TexCoord[0]), gl_Color)); \
|
||||||
|
gl_FragData[1] = gl_TexCoord[1]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DECL_TEXPS(num, bit) \
|
||||||
|
void Texture##num##bit##PS() \
|
||||||
|
{ \
|
||||||
|
gl_FragData[0] = ps2FinalColor(ps2CalcShade(ps2shade##num##bit(gl_TexCoord[0]), gl_Color)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define DECL_TEXPS_(num) \
|
||||||
|
DECL_TEXPS(num, _32) \
|
||||||
|
DECL_TEXPS(num, _tex32) \
|
||||||
|
DECL_TEXPS(num, _clut32) \
|
||||||
|
DECL_TEXPS(num, _tex32to16) \
|
||||||
|
DECL_TEXPS(num, _tex16to8h)
|
||||||
|
|
||||||
|
DECL_TEXPS_(0)
|
||||||
|
DECL_TEXPS_(1)
|
||||||
|
DECL_TEXPS_(2)
|
||||||
|
DECL_TEXPS_(3)
|
||||||
|
DECL_TEXPS_(4)
|
||||||
|
DECL_TEXPS_(5)
|
||||||
|
|
||||||
|
void RegularFogPS() {
|
||||||
|
half4 c;
|
||||||
|
c.xyz = mix(g_fFogColor.xyz, gl_Color.xyz, vec3(gl_TexCoord[0].x));
|
||||||
|
c.w = gl_Color.w;
|
||||||
|
gl_FragData[0] = ps2FinalColor(c);
|
||||||
|
DOZWRITE(gl_FragData[1] = gl_TexCoord[1];)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WRITE_DEPTH
|
||||||
|
|
||||||
|
#define DECL_TEXFOGPS(num, bit) \
|
||||||
|
void TextureFog##num##bit##PS() \
|
||||||
|
{ \
|
||||||
|
half4 c = ps2CalcShade(ps2shade##num##bit(gl_TexCoord[0]), gl_Color); \
|
||||||
|
c.xyz = mix(g_fFogColor.xyz, c.xyz, vec3(gl_TexCoord[1].x)); \
|
||||||
|
gl_FragData[0] = ps2FinalColor(c); \
|
||||||
|
gl_FragData[1] = gl_TexCoord[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DECL_TEXFOGPS(num, bit) \
|
||||||
|
void TextureFog##num##bit##PS() \
|
||||||
|
{ \
|
||||||
|
half4 c = ps2CalcShade(ps2shade##num##bit(gl_TexCoord[0]), gl_Color); \
|
||||||
|
c.xyz = mix(g_fFogColor.xyz, c.xyz, vec3(gl_TexCoord[1].x)); \
|
||||||
|
gl_FragData[0] = ps2FinalColor(c); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DECL_TEXFOGPS_(num) \
|
||||||
|
DECL_TEXFOGPS(num, _32) \
|
||||||
|
DECL_TEXFOGPS(num, _tex32) \
|
||||||
|
DECL_TEXFOGPS(num, _clut32) \
|
||||||
|
DECL_TEXFOGPS(num, _tex32to16) \
|
||||||
|
DECL_TEXFOGPS(num, _tex16to8h)
|
||||||
|
|
||||||
|
DECL_TEXFOGPS_(0)
|
||||||
|
DECL_TEXFOGPS_(1)
|
||||||
|
DECL_TEXFOGPS_(2)
|
||||||
|
DECL_TEXFOGPS_(3)
|
||||||
|
DECL_TEXFOGPS_(4)
|
||||||
|
DECL_TEXFOGPS_(5)
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Techniques not related to the main primitive commands
|
||||||
|
half4 BilinearBitBlt(float2 tex0)
|
||||||
|
{
|
||||||
|
float4 ftex;
|
||||||
|
float2 ffrac;
|
||||||
|
|
||||||
|
ffrac.xy = fract(tex0*g_fRealTexDims.xy);
|
||||||
|
ftex.xy = tex0 - ffrac.xy * g_fRealTexDims.zw;
|
||||||
|
ftex.zw = ftex.xy + g_fRealTexDims.zw;
|
||||||
|
|
||||||
|
float4 off0, off1;
|
||||||
|
ps2memcoord4_fast(ftex, off0, off1);
|
||||||
|
half4 c0 = texture(g_sMemory, off0.xy);
|
||||||
|
half4 c1 = texture(g_sMemory, off0.zw);
|
||||||
|
half4 c2 = texture(g_sMemory, off1.xy);
|
||||||
|
half4 c3 = texture(g_sMemory, off1.zw);
|
||||||
|
|
||||||
|
return mix( mix(c0, c1, vec4(ffrac.x)), mix(c2, c3, vec4(ffrac.x)), vec4(ffrac.y) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBltPS() {
|
||||||
|
gl_FragData[0] = texture(g_sMemory, ps2memcoord(gl_TexCoord[0].xy).xy)*g_fOneColor.xxxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// used when AA
|
||||||
|
void BitBltAAPS() {
|
||||||
|
gl_FragData[0] = BilinearBitBlt(gl_TexCoord[0].xy) * g_fOneColor.xxxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBltDepthPS() {
|
||||||
|
vec4 data;
|
||||||
|
data = texture(g_sMemory, ps2memcoord(gl_TexCoord[0].xy));
|
||||||
|
gl_FragData[0] = data + g_fZBias.y;
|
||||||
|
gl_FragDepth = (log(g_fc0.y + dot(data, g_fBitBltZ)) * g_fOneColor.w) * g_fZMin.y + dot(data, g_fBitBltZ) * g_fZMin.x ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBltDepthMRTPS() {
|
||||||
|
vec4 data;
|
||||||
|
data = texture(g_sMemory, ps2memcoord(gl_TexCoord[0].xy));
|
||||||
|
gl_FragData[0] = data + g_fZBias.y;
|
||||||
|
gl_FragData[1].x = g_fc0.x;
|
||||||
|
gl_FragDepth = (log(g_fc0.y + dot(data, g_fBitBltZ)) * g_fOneColor.w) * g_fZMin.y + dot(data, g_fBitBltZ) * g_fZMin.x ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static const float BlurKernel[9] = {
|
||||||
|
// 0.027601,
|
||||||
|
// 0.066213,
|
||||||
|
// 0.123701,
|
||||||
|
// 0.179952,
|
||||||
|
// 0.205065,
|
||||||
|
// 0.179952,
|
||||||
|
// 0.123701,
|
||||||
|
// 0.066213,
|
||||||
|
// 0.027601
|
||||||
|
// };
|
||||||
|
|
||||||
|
half4 BilinearFloat16(float2 tex0)
|
||||||
|
{
|
||||||
|
return texture(g_sSrcFinal, tex0.xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTCTargInterPS() {
|
||||||
|
float finter = texture(g_sInterlace, gl_TexCoord[1].yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w;
|
||||||
|
float4 c = BilinearFloat16(gl_TexCoord[0].xy);
|
||||||
|
c.w = ( g_fc0.w*c.w * g_fOneColor.x + g_fOneColor.y ) * finter;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTCTargPS() {
|
||||||
|
float4 c = BilinearFloat16(gl_TexCoord[0].xy);
|
||||||
|
c.w = g_fc0.w * c.w * g_fOneColor.x + g_fOneColor.y;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTCInterPS() {
|
||||||
|
float finter = texture(g_sInterlace, gl_TexCoord[1].yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w;
|
||||||
|
float2 filtcoord = trunc(gl_TexCoord[0].xy) * g_fInvTexDims.xy + g_fInvTexDims.zw;
|
||||||
|
half4 c = BilinearBitBlt(filtcoord);
|
||||||
|
c.w = (c.w * g_fOneColor.x + g_fOneColor.y)*finter;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpler
|
||||||
|
void CRTCInterPS_Nearest() {
|
||||||
|
float finter = texture(g_sInterlace, gl_TexCoord[1].yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w;
|
||||||
|
half4 c = texture(g_sMemory, ps2memcoord(gl_TexCoord[0].xy).xy);
|
||||||
|
c.w = (c.w * g_fOneColor.x + g_fOneColor.y)*finter;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTCPS() {
|
||||||
|
float2 filtcoord = gl_TexCoord[0].xy * g_fInvTexDims.xy+g_fInvTexDims.zw;
|
||||||
|
half4 c = BilinearBitBlt(filtcoord);
|
||||||
|
c.w = c.w * g_fOneColor.x + g_fOneColor.y;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpler
|
||||||
|
void CRTCPS_Nearest() {
|
||||||
|
half4 c = texture(g_sMemory, ps2memcoord(gl_TexCoord[0].xy).xy);
|
||||||
|
c.w = c.w * g_fOneColor.x + g_fOneColor.y;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTC24InterPS() {
|
||||||
|
float finter = texture(g_sInterlace, gl_TexCoord[1].yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w;
|
||||||
|
float2 filtcoord = trunc(gl_TexCoord[0].xy) * g_fInvTexDims.xy + g_fInvTexDims.zw;
|
||||||
|
|
||||||
|
half4 c = texture(g_sMemory, ps2memcoord(filtcoord).xy);
|
||||||
|
c.w = (c.w * g_fOneColor.x + g_fOneColor.y)*finter;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRTC24PS() {
|
||||||
|
float2 filtcoord = trunc(gl_TexCoord[0].xy) * g_fInvTexDims.xy + g_fInvTexDims.zw;
|
||||||
|
half4 c = texture(g_sMemory, ps2memcoord(filtcoord).xy);
|
||||||
|
c.w = c.w * g_fOneColor.x + g_fOneColor.y;
|
||||||
|
gl_FragData[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZeroPS() {
|
||||||
|
gl_FragData[0] = g_fOneColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseTexturePS() {
|
||||||
|
gl_FragData[0] = texture(g_sSrcFinal, gl_TexCoord[0].xy) * g_fOneColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Convert16to32PS() {
|
||||||
|
float4 final;
|
||||||
|
float2 ffrac = mod ( gl_TexCoord[0].xy + g_fTexDims.zw, g_fTexOffset.xy);
|
||||||
|
float2 tex0 = g_fTexDims.xy * gl_TexCoord[0].xy - ffrac * g_fc0.yw;
|
||||||
|
|
||||||
|
if (ffrac.x > g_fTexOffset.x*g_fc0.w)
|
||||||
|
tex0.x += g_fTexOffset.x*g_fc0.w;
|
||||||
|
if (tex0.x >= g_fc0.y)
|
||||||
|
tex0 += g_fTexOffset.zw;
|
||||||
|
|
||||||
|
float4 lower = texture(g_sSrcFinal, tex0);
|
||||||
|
float4 upper = texture(g_sSrcFinal, tex0 + g_fPageOffset.xy);
|
||||||
|
|
||||||
|
final.zy = texture(g_sConv32to16, lower.zyx).xy + lower.ww*g_fPageOffset.zw;
|
||||||
|
final.xw = texture(g_sConv32to16, upper.zyx).xy + upper.ww*g_fPageOffset.zw;
|
||||||
|
|
||||||
|
gl_FragData[0]= final;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use when texture is not tiled and converting from 32bit to 16bit
|
||||||
|
// don't convert on the block level, only on the column level
|
||||||
|
// so every other 8 pixels, use the upper bits instead of lower
|
||||||
|
void Convert32to16PS() {
|
||||||
|
bool upper = false;
|
||||||
|
float2 ffrac = mod(gl_TexCoord[0].xy + g_fTexDims.zw, g_fTexOffset.xy);
|
||||||
|
float2 tex0 = g_fc0.ww * (gl_TexCoord[0].xy + ffrac);
|
||||||
|
if( ffrac.x > g_fTexOffset.z ) {
|
||||||
|
tex0.x -= g_fTexOffset.z;
|
||||||
|
upper = true;
|
||||||
|
}
|
||||||
|
if( ffrac.y >= g_fTexOffset.w ) {
|
||||||
|
tex0.y -= g_fTexOffset.w;
|
||||||
|
tex0.x += g_fc0.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
half4 color = texture(g_sSrcFinal, tex0*g_fTexDims.xy)*g_fc0.yyyw;
|
||||||
|
float2 uv = upper ? color.xw : color.zy;
|
||||||
|
gl_FragData[0] = texture(g_sConv16to32, uv*g_fPageOffset.xy+g_fPageOffset.zw)*g_fTexDims.xxxy;
|
||||||
|
}
|
||||||
|
#endif //FRAGMENT_SHADER
|
||||||
|
|
||||||
|
#ifdef VERTEX_SHADER
|
||||||
|
|
||||||
|
float4 OutPosition(float4 vertex) {
|
||||||
|
float4 Position;
|
||||||
|
Position.xy = gl_Vertex.xy * g_fPosXY.xy + g_fPosXY.zw;
|
||||||
|
Position.z = (log(g_fc0.y + dot(g_fZ, gl_SecondaryColor.zyxw)) * g_fZNorm.x + g_fZNorm.y) * g_fZMin.y + dot(g_fZ, gl_SecondaryColor.zyxw) * g_fZMin.x ;
|
||||||
|
Position.w = g_fc0.y;
|
||||||
|
return Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just smooth shadering
|
||||||
|
void RegularVS() {
|
||||||
|
gl_Position = OutPosition(gl_Vertex);
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
DOZWRITE(gl_TexCoord[0] = gl_SecondaryColor * g_fZBias.x + g_fZBias.y; gl_TexCoord[0].w = g_fc0.y;)
|
||||||
|
}
|
||||||
|
|
||||||
|
// diffuse texture mapping
|
||||||
|
void TextureVS() {
|
||||||
|
gl_Position = OutPosition(gl_Vertex);
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
#ifdef PERSPECTIVE_CORRECT_TEX
|
||||||
|
gl_TexCoord[0].xyz = gl_MultiTexCoord0.xyz;
|
||||||
|
#else
|
||||||
|
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/gl_MultiTexCoord0.z;
|
||||||
|
#endif
|
||||||
|
DOZWRITE(gl_TexCoord[1] = gl_SecondaryColor * g_fZBias.x + g_fZBias.y; gl_TexCoord[1].w = g_fc0.y;)
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegularFogVS() {
|
||||||
|
float4 position = OutPosition(gl_Vertex);
|
||||||
|
gl_Position = position;
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
gl_TexCoord[0].x = position.z * g_fBilinear.w;
|
||||||
|
DOZWRITE(gl_TexCoord[1] = gl_SecondaryColor * g_fZBias.x + g_fZBias.y; gl_TexCoord[1].w = g_fc0.y;)
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureFogVS() {
|
||||||
|
gl_Position = OutPosition(gl_Vertex);
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
#ifdef PERSPECTIVE_CORRECT_TEX
|
||||||
|
gl_TexCoord[0].xyz = gl_MultiTexCoord0.xyz;
|
||||||
|
#else
|
||||||
|
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy / gl_MultiTexCoord0.z;
|
||||||
|
#endif
|
||||||
|
gl_TexCoord[1].x = gl_Vertex.z * g_fBilinear.w;
|
||||||
|
DOZWRITE(gl_TexCoord[2] = gl_SecondaryColor * g_fZBias.x + g_fZBias.y; gl_TexCoord[2].w = g_fc0.y;)
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBltVS() {
|
||||||
|
vec4 position;
|
||||||
|
position.xy = gl_Vertex.xy * g_fBitBltPos.xy + g_fBitBltPos.zw;
|
||||||
|
position.zw = g_fc0.xy;
|
||||||
|
gl_Position = position;
|
||||||
|
|
||||||
|
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy * g_fBitBltTex.xy + g_fBitBltTex.zw;
|
||||||
|
gl_TexCoord[1].xy = position.xy * g_fBitBltTrans.xy + g_fBitBltTrans.zw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue