diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Utils.h b/Source/Plugins/Plugin_VideoDX9/Src/Utils.h
index ae5c242734..87159c3b38 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Utils.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Utils.h
@@ -1,7 +1,6 @@
#ifndef _UTILS_H
#define _UTILS_H
-
#include "Common.h"
#include "main.h"
@@ -17,7 +16,6 @@ extern float luts8tosfloat[256];
LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void InitLUTs();
-
//#define RAM_MASK 0x1FFFFFF
inline u8 *Memory_GetPtr(u32 _uAddress)
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp
index a3f9415c42..8faef5e046 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexLoader.cpp
@@ -35,7 +35,7 @@ int ComputeVertexSize(u32 comp)
size += 4;
if (comp & VB_HAS_NRM0)
size += 4;
- if (comp & (VB_HAS_NRM1|VB_HAS_NRM2)) //combine into single check for speed
+ if (comp & (VB_HAS_NRM1 | VB_HAS_NRM2)) //combine into single check for speed
size += 8;
if (comp & VB_HAS_COL0)
size += 4;
diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj
index 6b864f1861..2b1bf09687 100644
--- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj
+++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj
@@ -1301,6 +1301,14 @@
RelativePath=".\Src\PixelShader.h"
>
+
+
+
+
@@ -1349,6 +1357,14 @@
RelativePath=".\Src\VertexShader.h"
>
+
+
+
+
+#include
#include
-#include "VertexShader.h"
#include "PixelShader.h"
-
-#define I_COLORS "color"
-#define I_KCOLORS "k"
-#define I_ALPHA "alphaRef"
-#define I_TEXDIMS "texdim"
-#define I_ZBIAS "czbias"
-#define I_INDTEXSCALE "cindscale"
-#define I_INDTEXMTX "cindmtx"
-
-#define C_COLORS 0
-#define C_KCOLORS (C_COLORS+4)
-#define C_ALPHA (C_KCOLORS+4)
-#define C_TEXDIMS (C_ALPHA+1)
-#define C_ZBIAS (C_TEXDIMS+8)
-#define C_INDTEXSCALE (C_ZBIAS+2)
-#define C_INDTEXMTX (C_INDTEXSCALE+2)
-#define C_ENVCONST_END (C_INDTEXMTX+6)
-
-#define C_COLORMATRIX (C_INDTEXMTX+6)
-
-
-void WriteStage(char *&p, int n);
-void WrapNonPow2Tex(char* &p, const char* var, int texmap);
-void WriteAlphaCompare(char *&p, int num, int comp);
-bool WriteAlphaTest(char *&p);
-
-PixelShaderMngr::PSCache PixelShaderMngr::pshaders;
-FRAGMENTSHADER* PixelShaderMngr::pShaderLast = NULL;
-PixelShaderMngr::PIXELSHADERUID PixelShaderMngr::s_curuid;
-
-static int s_nMaxPixelInstructions;
-static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
-static int s_nTexDimsChanged[2], s_nIndTexMtxChanged = 0; //min, max
-static bool s_bAlphaChanged, s_bZBiasChanged, s_bIndTexScaleChanged;
-static float lastRGBAfull[2][4][4] = {0};
-static u32 lastAlpha = 0;
-static u32 lastTexDims[8]={0};
-static u32 lastZBias = 0;
-
-// lower byte describes if a texture is nonpow2 or pow2
-// next byte describes whether the repeat wrap mode is enabled for the s channel
-// next byte is for t channel
-static u32 s_texturemask = 0;
-
-static int maptocoord[8]; // indexed by texture map, holds the texcoord associated with the map
-static u32 maptocoord_mask=0;
-
-static GLuint s_ColorMatrixProgram=0;
-
-void PixelShaderMngr::Init()
-{
- s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
- s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = -1;
- s_nIndTexMtxChanged = 15;
- s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = true;
- GL_REPORT_ERRORD();
- for(int i = 0; i < 8; ++i) maptocoord[i] = -1;
- maptocoord_mask = 0;
- memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
-
- glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, &s_nMaxPixelInstructions);
-
- int maxinst, maxattribs;
- glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &maxinst);
- glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, &maxattribs);
- ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs);
-
- char pmatrixprog[1024];
- sprintf(pmatrixprog, "!!ARBfp1.0"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEX R0, fragment.texcoord[0], texture[0], RECT;\n"
- "DP4 R1.w, R0, program.env[%d];\n"
- "DP4 R1.z, R0, program.env[%d];\n"
- "DP4 R1.x, R0, program.env[%d];\n"
- "DP4 R1.y, R0, program.env[%d];\n"
- "ADD result.color, R1, program.env[%d];\n"
- "END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4);
- glGenProgramsARB( 1, &s_ColorMatrixProgram );
- glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram );
-
- glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
-
- GLenum err=GL_NO_ERROR;
- GL_REPORT_ERROR();
- if( err != GL_NO_ERROR ) {
- ERROR_LOG("Failed to create color matrix fragment program\n");
-
- SAFE_RELEASE_PROG(s_ColorMatrixProgram);
- }
-}
-
-void PixelShaderMngr::Shutdown()
-{
- SAFE_RELEASE_PROG(s_ColorMatrixProgram);
- PSCache::iterator iter = pshaders.begin();
- for (;iter!=pshaders.end();iter++)
- iter->second.Destroy();
- pshaders.clear();
-}
-
-FRAGMENTSHADER* PixelShaderMngr::GetShader()
-{
- DVSTARTPROFILE();
- PIXELSHADERUID uid;
- GetPixelShaderId(uid);
-
- PSCache::iterator iter = pshaders.find(uid);
-
- if (iter != pshaders.end()) {
- iter->second.frameCount=frameCount;
- PSCacheEntry &entry = iter->second;
- if (&entry.shader != pShaderLast)
- {
- pShaderLast = &entry.shader;
- }
- return pShaderLast;
- }
-
- PSCacheEntry& newentry = pshaders[uid];
-
- if (!GeneratePixelShader(newentry.shader)) {
- ERROR_LOG("failed to create pixel shader\n");
- return NULL;
- }
-
- //Make an entry in the table
- newentry.frameCount=frameCount;
-
- pShaderLast = &newentry.shader;
- INCSTAT(stats.numPixelShadersCreated);
- SETSTAT(stats.numPixelShadersAlive, pshaders.size());
- return pShaderLast;
-}
-
-void PixelShaderMngr::Cleanup()
-{
- PSCache::iterator iter = pshaders.begin();
- while(iter != pshaders.end()) {
- PSCacheEntry &entry = iter->second;
- if (entry.frameCount= 0 ) {
- float fdims[4];
- for(int i = s_nTexDimsChanged[0]; i <= s_nTexDimsChanged[1]; ++i) {
- if( s_texturemask & (1<= 0 ) {
- TCoordInfo& tc = bpmem.texcoords[maptocoord[i]];
- fdims[0] = (float)(lastTexDims[i]&0xffff);
- fdims[1] = (float)((lastTexDims[i]>>16)&0xfff);
- fdims[2] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[i]&0xffff);
- fdims[3] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[i]>>16)&0xfff);
- }
- else {
- fdims[0] = (float)(lastTexDims[i]&0xffff);
- fdims[1] = (float)((lastTexDims[i]>>16)&0xfff);
- fdims[2] = 1.0f;
- fdims[3] = 1.0f;
- }
- }
- else {
- if( maptocoord[i] >= 0 ) {
- TCoordInfo& tc = bpmem.texcoords[maptocoord[i]];
- fdims[0] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[i]&0xffff);
- fdims[1] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[i]>>16)&0xfff);
- fdims[2] = 1.0f/(float)(tc.s.scale_minus_1+1);
- fdims[3] = 1.0f/(float)(tc.t.scale_minus_1+1);
- }
- else {
- fdims[0] = 1.0f;
- fdims[1] = 1.0f;
- fdims[2] = 1.0f/(float)(lastTexDims[i]&0xffff);
- fdims[3] = 1.0f/(float)((lastTexDims[i]>>16)&0xfff);
- }
- }
-
- PRIM_LOG("texdims%d: %f %f %f %f\n", i, fdims[0], fdims[1], fdims[2], fdims[3]);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_TEXDIMS+i, fdims);
- }
- s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = -1;
- }
-
- if( s_bAlphaChanged ) {
- glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, C_ALPHA, (lastAlpha&0xff)/255.0f, ((lastAlpha>>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f);
- }
-
- if( s_bZBiasChanged ) {
- u32 bits;
- float ffrac = 255.0f/256.0f;
- float ftemp[4];
- switch(bpmem.ztex2.type) {
- case 0:
- bits = 8;
- ftemp[0] = ffrac/(256.0f*256.0f); ftemp[1] = ffrac/256.0f; ftemp[2] = ffrac; ftemp[3] = 0;
- break;
- case 1:
- bits = 16;
- ftemp[0] = 0; ftemp[1] = ffrac/(256.0f*256.0f); ftemp[2] = ffrac/256.0f; ftemp[3] = ffrac;
- break;
- case 2:
- bits = 24;
- ftemp[0] = ffrac/(256.0f*256.0f); ftemp[1] = ffrac/256.0f; ftemp[2] = ffrac; ftemp[3] = 0;
- break;
- }
- //ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_ZBIAS, ftemp);
- glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, C_ZBIAS+1, 0, 0, 0, (float)( (((int)lastZBias<<8)>>8))/16777216.0f);
- }
-
- // indirect incoming texture scales, update all!
- if( s_bIndTexScaleChanged ) {
- float f[8];
-
- for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
- int srctexmap = bpmem.tevindref.getTexMap(i);
- int texcoord = bpmem.tevindref.getTexCoord(i);
- TCoordInfo& tc = bpmem.texcoords[texcoord];
-
- f[2*i] = bpmem.texscale[i/2].getScaleS(i&1) * (float)(tc.s.scale_minus_1+1) / (float)(lastTexDims[srctexmap]&0xffff);
- f[2*i+1] = bpmem.texscale[i/2].getScaleT(i&1) * (float)(tc.t.scale_minus_1+1) / (float)((lastTexDims[srctexmap]>>16)&0xfff);
-
- PRIM_LOG("tex indscale%d: %f %f\n", i, f[2*i], f[2*i+1]);
- }
-
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_INDTEXSCALE, f);
-
- if( bpmem.genMode.numindstages > 2 )
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_INDTEXSCALE+1, &f[4]);
-
- s_bIndTexScaleChanged = false;
- }
-
- if( s_nIndTexMtxChanged ) {
- for(int i = 0; i < 3; ++i) {
- if( s_nIndTexMtxChanged & (1<>16) ) {
- lastAlpha = (lastAlpha&~0xff0000)|((alpha.hex&0xff)<<16);
- s_bAlphaChanged = true;
- }
-}
-
-void PixelShaderMngr::SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt)
-{
- u32 wh = width|(height<<16)|(wraps<<28)|(wrapt<<30);
- if( lastTexDims[texmapid] != wh ) {
- lastTexDims[texmapid] = wh;
- if( s_nTexDimsChanged[0] == -1 ) {
- s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = texmapid;
- }
- else {
- if( s_nTexDimsChanged[0] > texmapid ) s_nTexDimsChanged[0] = texmapid;
- else if( s_nTexDimsChanged[1] < texmapid ) s_nTexDimsChanged[1] = texmapid;
- }
- }
-}
-
-void PixelShaderMngr::SetZTetureBias(u32 bias)
-{
- if( lastZBias != bias ) {
- s_bZBiasChanged = true;
- lastZBias = bias;
- }
-}
-
-void PixelShaderMngr::SetIndTexScaleChanged()
-{
- s_bIndTexScaleChanged = true;
-}
-
-void PixelShaderMngr::SetIndMatrixChanged(int matrixidx)
-{
- s_nIndTexMtxChanged |= 1 << matrixidx;
-}
-
-void PixelShaderMngr::SetGenModeChanged()
-{
-}
-
-void PixelShaderMngr::SetTevCombinerChanged(int id)
-{
-}
-
-void PixelShaderMngr::SetTevKSelChanged(int id)
-{
-}
-
-void PixelShaderMngr::SetTevOrderChanged(int id)
-{
-}
-
-void PixelShaderMngr::SetTevIndirectChanged(int id)
-{
-}
-
-void PixelShaderMngr::SetZTetureOpChanged()
-{
- s_bZBiasChanged = true;
-}
-
-void PixelShaderMngr::SetTexturesUsed(u32 nonpow2tex)
-{
- if( s_texturemask != nonpow2tex ) {
- u32 mask = s_texturemask ^ nonpow2tex;
- for(int i = 0; i < 8; ++i) {
- if( mask & (0x10101< i ) s_nTexDimsChanged[0] = i;
- else if( s_nTexDimsChanged[1] < i ) s_nTexDimsChanged[1] = i;
- }
- }
- s_texturemask = nonpow2tex;
- }
-}
-
-void PixelShaderMngr::SetTexDimsChanged(int texmapid)
-{
- if( s_nTexDimsChanged[0] > texmapid ) s_nTexDimsChanged[0] = texmapid;
- else if( s_nTexDimsChanged[1] < texmapid ) s_nTexDimsChanged[1] = texmapid;
- SetIndTexScaleChanged();
-}
-
-void PixelShaderMngr::SetColorMatrix(const float* pmatrix, const float* pfConstAdd)
-{
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX, pmatrix);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+1, pmatrix+4);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+2, pmatrix+8);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+3, pmatrix+12);
- glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+4, pfConstAdd);
-}
-
-GLuint PixelShaderMngr::GetColorMatrixProgram()
-{
- return s_ColorMatrixProgram;
-}
+#include "VertexShader.h" // for texture projection mode
+#include "PixelShaderManager.h"
// old tev->pixelshader notes
//
@@ -513,6 +31,12 @@ GLuint PixelShaderMngr::GetColorMatrixProgram()
// according to GXTevColorArg table above
// output is given by .outreg
// tevtemp is set according to swapmodetables and
+
+void WriteStage(char *&p, int n);
+void WrapNonPow2Tex(char* &p, const char* var, int texmap);
+void WriteAlphaCompare(char *&p, int num, int comp);
+bool WriteAlphaTest(char *&p);
+
const float epsilon = 1.0f/255.0f;
const char *tevKSelTableC[] = // KCSEL
@@ -719,90 +243,6 @@ const char* tevIndBiasAdd[] = {"-128.0f", "1.0f", "1.0f", "1.0f" }; // indexed b
const char* tevIndWrapStart[] = {"0", "256", "128", "64", "32", "16", "0.001" };
const char* tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "8.0f" };
-void PixelShaderMngr::GetPixelShaderId(PixelShaderMngr::PIXELSHADERUID& uid)
-{
- u32 projtexcoords = 0;
- for (u32 i = 0; i < bpmem.genMode.numtevstages+1; i++) {
- if( bpmem.tevorders[i/2].getEnable(i&1) ) {
- int texcoord = bpmem.tevorders[i/2].getTexCoord(i&1);
- if( xfregs.texcoords[texcoord].texmtxinfo.projection )
- projtexcoords |= 1<>16)&0xff)<<12)|(projtexcoords<<20)|((u32)bpmem.ztex2.op<<28)
- |(zbufrender<<30)|(zBufRenderToCol0<<31);
-
- s_curuid.values[0] = (s_curuid.values[0]&~0x0ff00000)|(projtexcoords<<20);
-
- // swap table
- for(int i = 0; i < 8; i += 2)
- ((u8*)&uid.values[1])[i/2] = (bpmem.tevksel[i].hex&0xf)|((bpmem.tevksel[i+1].hex&0xf)<<4);
-
- uid.values[2] = s_texturemask;
- int hdr = 3;
-
- u32* pcurvalue = &uid.values[hdr];
- for(u32 i = 0; i < bpmem.genMode.numtevstages+1; ++i) {
- TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC;
- TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[i].alphaC;
-
- u32 val0 = cc.hex&0xffffff;
- u32 val1 = ac.hex&0xffffff;
- val0 |= bpmem.tevksel[i/2].getKC(i&1)<<24;
- val1 |= bpmem.tevksel[i/2].getKA(i&1)<<24;
-
- pcurvalue[0] = val0;
- pcurvalue[1] = val1;
- pcurvalue+=2;
- }
-
- for(u32 i = 0; i < (bpmem.genMode.numtevstages+1)/2; ++i) {
- u32 val0, val1;
- if( bpmem.tevorders[i].hex&0x40 ) val0 = bpmem.tevorders[i].hex&0x3ff;
- else val0 = bpmem.tevorders[i].hex&0x380;
- if( bpmem.tevorders[i].hex&0x40000 ) val1 = (bpmem.tevorders[i].hex&0x3ff000)>>12;
- else val1 = (bpmem.tevorders[i].hex&0x380000)>>12;
-
- switch(i % 3) {
- case 0: pcurvalue[0] = val0|(val1<<10); break;
- case 1: pcurvalue[0] |= val0<<20; pcurvalue[1] = val1; pcurvalue++; break;
- case 2: pcurvalue[1] |= (val0<<10)|(val1<<20); pcurvalue++; break;
- }
- }
-
- if( (bpmem.genMode.numtevstages+1)&1 ) { // odd
- u32 val0;
- if( bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x40 ) val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x3ff;
- else val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x380;
-
- switch(bpmem.genMode.numtevstages % 3) {
- case 0: pcurvalue[0] = val0; break;
- case 1: pcurvalue[0] |= val0<<20; break;
- case 2: pcurvalue[1] |= (val0<<10); pcurvalue++; break;
- }
- }
-
- if( (bpmem.genMode.numtevstages % 3) != 2 )
- ++pcurvalue;
-
- uid.tevstages = (u32)(pcurvalue-&uid.values[0]-hdr);
-
- for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
- u32 val = bpmem.tevind[i].hex&0x1fffff; // 21 bits
- switch(i%3) {
- case 0: pcurvalue[0] = val; break;
- case 1: pcurvalue[0] |= val<<21; pcurvalue[1] = val>>11; ++pcurvalue; break;
- case 2: pcurvalue[0] |= val<<10; ++pcurvalue; break;
- }
- }
-
- uid.indstages = (u32)(pcurvalue-&uid.values[0]-2-uid.tevstages);
-}
-
#define WRITE p+=sprintf
const char *swapColors = "rgba";
@@ -822,7 +262,7 @@ void BuildSwapModeTable()
}
static char text[16384];
-bool PixelShaderMngr::GeneratePixelShader(FRAGMENTSHADER& ps)
+bool GeneratePixelShader(FRAGMENTSHADER& ps)
{
DVSTARTPROFILE();
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.h
index f41c0203b4..51333825cf 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShader.h
@@ -21,6 +21,25 @@
#include "Render.h"
#include "BPStructs.h"
+#define I_COLORS "color"
+#define I_KCOLORS "k"
+#define I_ALPHA "alphaRef"
+#define I_TEXDIMS "texdim"
+#define I_ZBIAS "czbias"
+#define I_INDTEXSCALE "cindscale"
+#define I_INDTEXMTX "cindmtx"
+
+#define C_COLORS 0
+#define C_KCOLORS (C_COLORS+4)
+#define C_ALPHA (C_KCOLORS+4)
+#define C_TEXDIMS (C_ALPHA+1)
+#define C_ZBIAS (C_TEXDIMS+8)
+#define C_INDTEXSCALE (C_ZBIAS+2)
+#define C_INDTEXMTX (C_INDTEXSCALE+2)
+#define C_ENVCONST_END (C_INDTEXMTX+6)
+
+#define C_COLORMATRIX (C_INDTEXMTX+6)
+
struct FRAGMENTSHADER
{
FRAGMENTSHADER() : glprogid(0) { }
@@ -31,124 +50,6 @@ struct FRAGMENTSHADER
#endif
};
-class PixelShaderMngr
-{
- class PIXELSHADERUID
- {
- public:
- PIXELSHADERUID() { values = new u32[3+32+6+11]; tevstages = indstages = 0; }
- ~PIXELSHADERUID() { delete[] values; }
- PIXELSHADERUID(const PIXELSHADERUID& r)
- {
- values = new u32[4+32+6+11];
- tevstages = r.tevstages; indstages = r.indstages;
- int N = tevstages + indstages + 3;
- _assert_(N <= 4+32+6+11);
- for(int i = 0; i < N; ++i)
- values[i] = r.values[i];
- }
-
- bool operator <(const PIXELSHADERUID& _Right) const
- {
- if( values[0] < _Right.values[0] )
- return true;
- else if( values[0] > _Right.values[0] )
- return false;
-
- int N = tevstages + 3; // numTevStages*3/2+1
- int i = 1;
- for(; i < N; ++i) {
- if( values[i] < _Right.values[i] )
- return true;
- else if( values[i] > _Right.values[i] )
- return false;
- }
-
- N += indstages;
- for(; i < N; ++i) {
- if( values[i] < _Right.values[i] )
- return true;
- else if( values[i] > _Right.values[i] )
- return false;
- }
-
- return false;
- }
-
- bool operator ==(const PIXELSHADERUID& _Right) const
- {
- if( values[0] != _Right.values[0] )
- return false;
-
- int N = tevstages + 3; // numTevStages*3/2+1
- int i = 1;
- for(; i < N; ++i) {
- if( values[i] != _Right.values[i] )
- return false;
- }
-
- N += indstages;
- for(; i < N; ++i) {
- if( values[i] != _Right.values[i] )
- return false;
- }
-
- return true;
- }
-
- u32* values;
- u16 tevstages, indstages;
- };
-
- struct PSCacheEntry
- {
- FRAGMENTSHADER shader;
- int frameCount;
- PSCacheEntry() : frameCount(0) {}
- ~PSCacheEntry() {}
- void Destroy() {
- glDeleteProgramsARB(1, &shader.glprogid);
- }
- };
-
- typedef std::map PSCache;
-
- static FRAGMENTSHADER* pShaderLast; // last used shader
- static PSCache pshaders;
-
- static bool GeneratePixelShader(FRAGMENTSHADER& ps);
- static void GetPixelShaderId(PIXELSHADERUID&);
- static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)
-
-public:
- static void Init();
- static void Cleanup();
- static void Shutdown();
- static FRAGMENTSHADER* GetShader();
- static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
-
- static void SetConstants(FRAGMENTSHADER& ps); // sets pixel shader constants
-
- // constant management, should be called after memory is committed
- static void SetColorChanged(int type, int index);
- static void SetAlpha(const AlphaFunc& alpha);
- static void SetDestAlpha(const ConstantAlpha& alpha);
- static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
- static void SetZTetureBias(u32 bias);
- static void SetIndTexScaleChanged();
- static void SetIndMatrixChanged(int matrixidx);
-
- static void SetGenModeChanged();
- static void SetTevCombinerChanged(int id);
- static void SetTevKSelChanged(int id);
- static void SetTevOrderChanged(int id);
- static void SetTevIndirectChanged(int id);
- static void SetZTetureOpChanged();
- static void SetTexturesUsed(u32 nonpow2tex);
- static void SetTexDimsChanged(int texmapid);
-
- static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
- static GLuint GetColorMatrixProgram();
-};
+bool GeneratePixelShader(FRAGMENTSHADER& ps);
#endif
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp
new file mode 100644
index 0000000000..6351a16c7e
--- /dev/null
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp
@@ -0,0 +1,567 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Globals.h"
+
+#include
+
+#include "Common.h"
+#include "VertexShader.h"
+#include "PixelShaderManager.h"
+#include "PixelShader.h"
+
+PixelShaderMngr::PSCache PixelShaderMngr::pshaders;
+FRAGMENTSHADER* PixelShaderMngr::pShaderLast = NULL;
+PixelShaderMngr::PIXELSHADERUID PixelShaderMngr::s_curuid;
+
+static int s_nMaxPixelInstructions;
+static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
+static int s_nTexDimsChanged[2], s_nIndTexMtxChanged = 0; //min, max
+static bool s_bAlphaChanged, s_bZBiasChanged, s_bIndTexScaleChanged;
+static float lastRGBAfull[2][4][4] = {0};
+static u32 lastAlpha = 0;
+static u32 lastTexDims[8]={0};
+static u32 lastZBias = 0;
+
+// lower byte describes if a texture is nonpow2 or pow2
+// next byte describes whether the repeat wrap mode is enabled for the s channel
+// next byte is for t channel
+u32 s_texturemask = 0;
+
+static int maptocoord[8]; // indexed by texture map, holds the texcoord associated with the map
+static u32 maptocoord_mask=0;
+
+static GLuint s_ColorMatrixProgram=0;
+
+void PixelShaderMngr::Init()
+{
+ s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
+ s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = -1;
+ s_nIndTexMtxChanged = 15;
+ s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = true;
+ GL_REPORT_ERRORD();
+ for(int i = 0; i < 8; ++i) maptocoord[i] = -1;
+ maptocoord_mask = 0;
+ memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
+
+ glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, &s_nMaxPixelInstructions);
+
+ int maxinst, maxattribs;
+ glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &maxinst);
+ glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, &maxattribs);
+ ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs);
+
+ char pmatrixprog[1024];
+ sprintf(pmatrixprog, "!!ARBfp1.0"
+ "TEMP R0;\n"
+ "TEMP R1;\n"
+ "TEX R0, fragment.texcoord[0], texture[0], RECT;\n"
+ "DP4 R1.w, R0, program.env[%d];\n"
+ "DP4 R1.z, R0, program.env[%d];\n"
+ "DP4 R1.x, R0, program.env[%d];\n"
+ "DP4 R1.y, R0, program.env[%d];\n"
+ "ADD result.color, R1, program.env[%d];\n"
+ "END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4);
+ glGenProgramsARB( 1, &s_ColorMatrixProgram );
+ glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram );
+
+ glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
+
+ GLenum err=GL_NO_ERROR;
+ GL_REPORT_ERROR();
+ if( err != GL_NO_ERROR ) {
+ ERROR_LOG("Failed to create color matrix fragment program\n");
+
+ SAFE_RELEASE_PROG(s_ColorMatrixProgram);
+ }
+}
+
+void PixelShaderMngr::Shutdown()
+{
+ SAFE_RELEASE_PROG(s_ColorMatrixProgram);
+ PSCache::iterator iter = pshaders.begin();
+ for (;iter!=pshaders.end();iter++)
+ iter->second.Destroy();
+ pshaders.clear();
+}
+
+FRAGMENTSHADER* PixelShaderMngr::GetShader()
+{
+ DVSTARTPROFILE();
+ PIXELSHADERUID uid;
+ GetPixelShaderId(uid);
+
+ PSCache::iterator iter = pshaders.find(uid);
+
+ if (iter != pshaders.end()) {
+ iter->second.frameCount=frameCount;
+ PSCacheEntry &entry = iter->second;
+ if (&entry.shader != pShaderLast)
+ {
+ pShaderLast = &entry.shader;
+ }
+ return pShaderLast;
+ }
+
+ PSCacheEntry& newentry = pshaders[uid];
+
+ if (!GeneratePixelShader(newentry.shader)) {
+ ERROR_LOG("failed to create pixel shader\n");
+ return NULL;
+ }
+
+ //Make an entry in the table
+ newentry.frameCount=frameCount;
+
+ pShaderLast = &newentry.shader;
+ INCSTAT(stats.numPixelShadersCreated);
+ SETSTAT(stats.numPixelShadersAlive, pshaders.size());
+ return pShaderLast;
+}
+
+void PixelShaderMngr::Cleanup()
+{
+ PSCache::iterator iter = pshaders.begin();
+ while(iter != pshaders.end()) {
+ PSCacheEntry &entry = iter->second;
+ if (entry.frameCount= 0 ) {
+ float fdims[4];
+ for(int i = s_nTexDimsChanged[0]; i <= s_nTexDimsChanged[1]; ++i) {
+ if( s_texturemask & (1<= 0 ) {
+ TCoordInfo& tc = bpmem.texcoords[maptocoord[i]];
+ fdims[0] = (float)(lastTexDims[i]&0xffff);
+ fdims[1] = (float)((lastTexDims[i]>>16)&0xfff);
+ fdims[2] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[i]&0xffff);
+ fdims[3] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[i]>>16)&0xfff);
+ }
+ else {
+ fdims[0] = (float)(lastTexDims[i]&0xffff);
+ fdims[1] = (float)((lastTexDims[i]>>16)&0xfff);
+ fdims[2] = 1.0f;
+ fdims[3] = 1.0f;
+ }
+ }
+ else {
+ if( maptocoord[i] >= 0 ) {
+ TCoordInfo& tc = bpmem.texcoords[maptocoord[i]];
+ fdims[0] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[i]&0xffff);
+ fdims[1] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[i]>>16)&0xfff);
+ fdims[2] = 1.0f/(float)(tc.s.scale_minus_1+1);
+ fdims[3] = 1.0f/(float)(tc.t.scale_minus_1+1);
+ }
+ else {
+ fdims[0] = 1.0f;
+ fdims[1] = 1.0f;
+ fdims[2] = 1.0f/(float)(lastTexDims[i]&0xffff);
+ fdims[3] = 1.0f/(float)((lastTexDims[i]>>16)&0xfff);
+ }
+ }
+
+ PRIM_LOG("texdims%d: %f %f %f %f\n", i, fdims[0], fdims[1], fdims[2], fdims[3]);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_TEXDIMS+i, fdims);
+ }
+ s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = -1;
+ }
+
+ if( s_bAlphaChanged ) {
+ glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, C_ALPHA, (lastAlpha&0xff)/255.0f, ((lastAlpha>>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f);
+ }
+
+ if( s_bZBiasChanged ) {
+ u32 bits;
+ float ffrac = 255.0f/256.0f;
+ float ftemp[4];
+ switch(bpmem.ztex2.type) {
+ case 0:
+ bits = 8;
+ ftemp[0] = ffrac/(256.0f*256.0f); ftemp[1] = ffrac/256.0f; ftemp[2] = ffrac; ftemp[3] = 0;
+ break;
+ case 1:
+ bits = 16;
+ ftemp[0] = 0; ftemp[1] = ffrac/(256.0f*256.0f); ftemp[2] = ffrac/256.0f; ftemp[3] = ffrac;
+ break;
+ case 2:
+ bits = 24;
+ ftemp[0] = ffrac/(256.0f*256.0f); ftemp[1] = ffrac/256.0f; ftemp[2] = ffrac; ftemp[3] = 0;
+ break;
+ }
+ //ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_ZBIAS, ftemp);
+ glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, C_ZBIAS+1, 0, 0, 0, (float)( (((int)lastZBias<<8)>>8))/16777216.0f);
+ }
+
+ // indirect incoming texture scales, update all!
+ if( s_bIndTexScaleChanged ) {
+ float f[8];
+
+ for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
+ int srctexmap = bpmem.tevindref.getTexMap(i);
+ int texcoord = bpmem.tevindref.getTexCoord(i);
+ TCoordInfo& tc = bpmem.texcoords[texcoord];
+
+ f[2*i] = bpmem.texscale[i/2].getScaleS(i&1) * (float)(tc.s.scale_minus_1+1) / (float)(lastTexDims[srctexmap]&0xffff);
+ f[2*i+1] = bpmem.texscale[i/2].getScaleT(i&1) * (float)(tc.t.scale_minus_1+1) / (float)((lastTexDims[srctexmap]>>16)&0xfff);
+
+ PRIM_LOG("tex indscale%d: %f %f\n", i, f[2*i], f[2*i+1]);
+ }
+
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_INDTEXSCALE, f);
+
+ if( bpmem.genMode.numindstages > 2 )
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_INDTEXSCALE+1, &f[4]);
+
+ s_bIndTexScaleChanged = false;
+ }
+
+ if( s_nIndTexMtxChanged ) {
+ for(int i = 0; i < 3; ++i) {
+ if( s_nIndTexMtxChanged & (1<>16) ) {
+ lastAlpha = (lastAlpha&~0xff0000)|((alpha.hex&0xff)<<16);
+ s_bAlphaChanged = true;
+ }
+}
+
+void PixelShaderMngr::SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt)
+{
+ u32 wh = width|(height<<16)|(wraps<<28)|(wrapt<<30);
+ if( lastTexDims[texmapid] != wh ) {
+ lastTexDims[texmapid] = wh;
+ if( s_nTexDimsChanged[0] == -1 ) {
+ s_nTexDimsChanged[0] = s_nTexDimsChanged[1] = texmapid;
+ }
+ else {
+ if( s_nTexDimsChanged[0] > texmapid ) s_nTexDimsChanged[0] = texmapid;
+ else if( s_nTexDimsChanged[1] < texmapid ) s_nTexDimsChanged[1] = texmapid;
+ }
+ }
+}
+
+void PixelShaderMngr::SetZTetureBias(u32 bias)
+{
+ if( lastZBias != bias ) {
+ s_bZBiasChanged = true;
+ lastZBias = bias;
+ }
+}
+
+void PixelShaderMngr::SetIndTexScaleChanged()
+{
+ s_bIndTexScaleChanged = true;
+}
+
+void PixelShaderMngr::SetIndMatrixChanged(int matrixidx)
+{
+ s_nIndTexMtxChanged |= 1 << matrixidx;
+}
+
+void PixelShaderMngr::SetGenModeChanged()
+{
+}
+
+void PixelShaderMngr::SetTevCombinerChanged(int id)
+{
+}
+
+void PixelShaderMngr::SetTevKSelChanged(int id)
+{
+}
+
+void PixelShaderMngr::SetTevOrderChanged(int id)
+{
+}
+
+void PixelShaderMngr::SetTevIndirectChanged(int id)
+{
+}
+
+void PixelShaderMngr::SetZTetureOpChanged()
+{
+ s_bZBiasChanged = true;
+}
+
+void PixelShaderMngr::SetTexturesUsed(u32 nonpow2tex)
+{
+ if( s_texturemask != nonpow2tex ) {
+ u32 mask = s_texturemask ^ nonpow2tex;
+ for(int i = 0; i < 8; ++i) {
+ if( mask & (0x10101< i ) s_nTexDimsChanged[0] = i;
+ else if( s_nTexDimsChanged[1] < i ) s_nTexDimsChanged[1] = i;
+ }
+ }
+ s_texturemask = nonpow2tex;
+ }
+}
+
+void PixelShaderMngr::SetTexDimsChanged(int texmapid)
+{
+ if( s_nTexDimsChanged[0] > texmapid ) s_nTexDimsChanged[0] = texmapid;
+ else if( s_nTexDimsChanged[1] < texmapid ) s_nTexDimsChanged[1] = texmapid;
+ SetIndTexScaleChanged();
+}
+
+void PixelShaderMngr::SetColorMatrix(const float* pmatrix, const float* pfConstAdd)
+{
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX, pmatrix);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+1, pmatrix+4);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+2, pmatrix+8);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+3, pmatrix+12);
+ glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, C_COLORMATRIX+4, pfConstAdd);
+}
+
+GLuint PixelShaderMngr::GetColorMatrixProgram()
+{
+ return s_ColorMatrixProgram;
+}
+
+void PixelShaderMngr::GetPixelShaderId(PixelShaderMngr::PIXELSHADERUID& uid)
+{
+ u32 projtexcoords = 0;
+ for (u32 i = 0; i < bpmem.genMode.numtevstages+1; i++) {
+ if( bpmem.tevorders[i/2].getEnable(i&1) ) {
+ int texcoord = bpmem.tevorders[i/2].getTexCoord(i&1);
+ if( xfregs.texcoords[texcoord].texmtxinfo.projection )
+ projtexcoords |= 1<>16)&0xff)<<12)|(projtexcoords<<20)|((u32)bpmem.ztex2.op<<28)
+ |(zbufrender<<30)|(zBufRenderToCol0<<31);
+
+ s_curuid.values[0] = (s_curuid.values[0]&~0x0ff00000)|(projtexcoords<<20);
+
+ // swap table
+ for(int i = 0; i < 8; i += 2)
+ ((u8*)&uid.values[1])[i/2] = (bpmem.tevksel[i].hex&0xf)|((bpmem.tevksel[i+1].hex&0xf)<<4);
+
+ uid.values[2] = s_texturemask;
+ int hdr = 3;
+
+ u32* pcurvalue = &uid.values[hdr];
+ for(u32 i = 0; i < bpmem.genMode.numtevstages+1; ++i) {
+ TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC;
+ TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[i].alphaC;
+
+ u32 val0 = cc.hex&0xffffff;
+ u32 val1 = ac.hex&0xffffff;
+ val0 |= bpmem.tevksel[i/2].getKC(i&1)<<24;
+ val1 |= bpmem.tevksel[i/2].getKA(i&1)<<24;
+
+ pcurvalue[0] = val0;
+ pcurvalue[1] = val1;
+ pcurvalue+=2;
+ }
+
+ for(u32 i = 0; i < (bpmem.genMode.numtevstages+1)/2; ++i) {
+ u32 val0, val1;
+ if( bpmem.tevorders[i].hex&0x40 ) val0 = bpmem.tevorders[i].hex&0x3ff;
+ else val0 = bpmem.tevorders[i].hex&0x380;
+ if( bpmem.tevorders[i].hex&0x40000 ) val1 = (bpmem.tevorders[i].hex&0x3ff000)>>12;
+ else val1 = (bpmem.tevorders[i].hex&0x380000)>>12;
+
+ switch(i % 3) {
+ case 0: pcurvalue[0] = val0|(val1<<10); break;
+ case 1: pcurvalue[0] |= val0<<20; pcurvalue[1] = val1; pcurvalue++; break;
+ case 2: pcurvalue[1] |= (val0<<10)|(val1<<20); pcurvalue++; break;
+ }
+ }
+
+ if( (bpmem.genMode.numtevstages+1)&1 ) { // odd
+ u32 val0;
+ if( bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x40 ) val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x3ff;
+ else val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x380;
+
+ switch(bpmem.genMode.numtevstages % 3) {
+ case 0: pcurvalue[0] = val0; break;
+ case 1: pcurvalue[0] |= val0<<20; break;
+ case 2: pcurvalue[1] |= (val0<<10); pcurvalue++; break;
+ }
+ }
+
+ if( (bpmem.genMode.numtevstages % 3) != 2 )
+ ++pcurvalue;
+
+ uid.tevstages = (u32)(pcurvalue-&uid.values[0]-hdr);
+
+ for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
+ u32 val = bpmem.tevind[i].hex&0x1fffff; // 21 bits
+ switch(i%3) {
+ case 0: pcurvalue[0] = val; break;
+ case 1: pcurvalue[0] |= val<<21; pcurvalue[1] = val>>11; ++pcurvalue; break;
+ case 2: pcurvalue[0] |= val<<10; ++pcurvalue; break;
+ }
+ }
+
+ uid.indstages = (u32)(pcurvalue-&uid.values[0]-2-uid.tevstages);
+}
\ No newline at end of file
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h
new file mode 100644
index 0000000000..174996365b
--- /dev/null
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.h
@@ -0,0 +1,145 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _PIXELSHADERMANAGER_H
+#define _PIXELSHADERMANAGER_H
+
+#include "PixelShader.h"
+
+extern u32 s_texturemask;
+
+class PixelShaderMngr
+{
+ class PIXELSHADERUID
+ {
+ public:
+ PIXELSHADERUID() { values = new u32[3+32+6+11]; tevstages = indstages = 0; }
+ ~PIXELSHADERUID() { delete[] values; }
+ PIXELSHADERUID(const PIXELSHADERUID& r)
+ {
+ values = new u32[4+32+6+11];
+ tevstages = r.tevstages; indstages = r.indstages;
+ int N = tevstages + indstages + 3;
+ _assert_(N <= 4+32+6+11);
+ for(int i = 0; i < N; ++i)
+ values[i] = r.values[i];
+ }
+
+ bool operator <(const PIXELSHADERUID& _Right) const
+ {
+ if( values[0] < _Right.values[0] )
+ return true;
+ else if( values[0] > _Right.values[0] )
+ return false;
+
+ int N = tevstages + 3; // numTevStages*3/2+1
+ int i = 1;
+ for(; i < N; ++i) {
+ if( values[i] < _Right.values[i] )
+ return true;
+ else if( values[i] > _Right.values[i] )
+ return false;
+ }
+
+ N += indstages;
+ for(; i < N; ++i) {
+ if( values[i] < _Right.values[i] )
+ return true;
+ else if( values[i] > _Right.values[i] )
+ return false;
+ }
+
+ return false;
+ }
+
+ bool operator ==(const PIXELSHADERUID& _Right) const
+ {
+ if( values[0] != _Right.values[0] )
+ return false;
+
+ int N = tevstages + 3; // numTevStages*3/2+1
+ int i = 1;
+ for(; i < N; ++i) {
+ if( values[i] != _Right.values[i] )
+ return false;
+ }
+
+ N += indstages;
+ for(; i < N; ++i) {
+ if( values[i] != _Right.values[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ u32* values;
+ u16 tevstages, indstages;
+ };
+
+ struct PSCacheEntry
+ {
+ FRAGMENTSHADER shader;
+ int frameCount;
+ PSCacheEntry() : frameCount(0) {}
+ ~PSCacheEntry() {}
+ void Destroy() {
+ glDeleteProgramsARB(1, &shader.glprogid);
+ }
+ };
+
+ typedef std::map PSCache;
+
+ static FRAGMENTSHADER* pShaderLast; // last used shader
+ static PSCache pshaders;
+
+ static void GetPixelShaderId(PIXELSHADERUID&);
+ static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)
+
+public:
+ static void Init();
+ static void Cleanup();
+ static void Shutdown();
+ static FRAGMENTSHADER* GetShader();
+ static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
+
+ static void SetConstants(FRAGMENTSHADER& ps); // sets pixel shader constants
+
+ // constant management, should be called after memory is committed
+ static void SetColorChanged(int type, int index);
+ static void SetAlpha(const AlphaFunc& alpha);
+ static void SetDestAlpha(const ConstantAlpha& alpha);
+ static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
+ static void SetZTetureBias(u32 bias);
+ static void SetIndTexScaleChanged();
+ static void SetIndMatrixChanged(int matrixidx);
+
+ static void SetGenModeChanged();
+ static void SetTevCombinerChanged(int id);
+ static void SetTevKSelChanged(int id);
+ static void SetTevOrderChanged(int id);
+ static void SetTevIndirectChanged(int id);
+ static void SetZTetureOpChanged();
+ static void SetTexturesUsed(u32 nonpow2tex);
+ static void SetTexDimsChanged(int texmapid);
+
+ static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
+ static GLuint GetColorMatrixProgram();
+};
+
+
+#endif
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
index 707b249590..515a460694 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
@@ -25,7 +25,7 @@
#include "TextureMngr.h"
#include "rasterfont.h"
#include "VertexShader.h"
-#include "PixelShader.h"
+#include "PixelShaderManager.h"
#include "VertexLoader.h"
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
index 3525c310a3..e3a177927f 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
@@ -27,8 +27,8 @@
#include "BPStructs.h"
#include "TextureDecoder.h"
#include "TextureMngr.h"
-#include "PixelShader.h"
-#include "VertexShader.h"
+#include "PixelShaderManager.h"
+#include "VertexShaderManager.h"
u8 *TextureMngr::temp = NULL;
TextureMngr::TexCache TextureMngr::textures;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
index 3967618883..5e256c7560 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp
@@ -25,8 +25,8 @@
#include "BPStructs.h"
#include "DataReader.h"
-#include "VertexShader.h"
-#include "PixelShader.h"
+#include "VertexShaderManager.h"
+#include "PixelShaderManager.h"
#include "TextureMngr.h"
#include "MemoryUtil.h"
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp
index f181549440..646f6d3768 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.cpp
@@ -20,790 +20,18 @@
#include
#include "Render.h"
#include "VertexShader.h"
+#include "VertexShaderManager.h"
#include "BPStructs.h"
#include "VertexLoader.h"
-// shader variables
-#define I_POSNORMALMATRIX "cpnmtx"
-#define I_PROJECTION "cproj"
-#define I_MATERIALS "cmtrl"
-#define I_LIGHTS "clights"
-#define I_TEXMATRICES "ctexmtx"
-#define I_TRANSFORMMATRICES "ctrmtx"
-#define I_NORMALMATRICES "cnmtx"
-#define I_POSTTRANSFORMMATRICES "cpostmtx"
-#define I_FOGPARAMS "cfog"
-
-#define C_POSNORMALMATRIX 0
-#define C_PROJECTION (C_POSNORMALMATRIX+6)
-#define C_MATERIALS (C_PROJECTION+4)
-#define C_LIGHTS (C_MATERIALS+4)
-#define C_TEXMATRICES (C_LIGHTS+40)
-#define C_TRANSFORMMATRICES (C_TEXMATRICES+24)
-#define C_NORMALMATRICES (C_TRANSFORMMATRICES+64)
-#define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES+32)
-#define C_FOGPARAMS (C_POSTTRANSFORMMATRICES+64)
-
-VertexShaderMngr::VSCache VertexShaderMngr::vshaders;
-VERTEXSHADER* VertexShaderMngr::pShaderLast = NULL;
-TMatrixIndexA VertexShaderMngr::MatrixIndexA;
-TMatrixIndexB VertexShaderMngr::MatrixIndexB;
-float VertexShaderMngr::rawViewport[6] = {0};
-float VertexShaderMngr::rawProjection[7] = {0};
-float GC_ALIGNED16(g_fProjectionMatrix[16]);
-
-static int s_nMaxVertexInstructions;
-
-////////////////////////
-// Internal Variables //
-////////////////////////
-XFRegisters xfregs;
-static u32 xfmem[XFMEM_SIZE];
-static float s_fMaterials[16];
-
-// track changes
-static bool bTexMatricesChanged[2], bPosNormalMatrixChanged, bProjectionChanged, bViewportChanged;
-int nMaterialsChanged;
-static int nTransformMatricesChanged[2]; // min,max
-static int nNormalMatricesChanged[2]; // min,max
-static int nPostTransformMatricesChanged[2]; // min,max
-static int nLightsChanged[2]; // min,max
-
-void VertexShaderMngr::Init()
-{
- nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
- nNormalMatricesChanged[0] = nNormalMatricesChanged[1] = -1;
- nPostTransformMatricesChanged[0] = nPostTransformMatricesChanged[1] = -1;
- nLightsChanged[0] = nLightsChanged[1] = -1;
- bTexMatricesChanged[0] = bTexMatricesChanged[1] = false;
- bPosNormalMatrixChanged = bProjectionChanged = bViewportChanged = false;
- nMaterialsChanged = 0;
-
- memset(&xfregs, 0, sizeof(xfregs));
- memset(xfmem, 0, sizeof(xfmem));
-
- glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &s_nMaxVertexInstructions);
-}
-
-void VertexShaderMngr::Shutdown()
-{
- VSCache::iterator iter = vshaders.begin();
- for (;iter!=vshaders.end();iter++)
- iter->second.Destroy();
- vshaders.clear();
-}
-
-VERTEXSHADER* VertexShaderMngr::GetShader(u32 components)
-{
- DVSTARTPROFILE();
- VERTEXSHADERUID uid;
- GetVertexShaderId(uid, components);
-
- VSCache::iterator iter = vshaders.find(uid);
-
- if (iter != vshaders.end()) {
- iter->second.frameCount=frameCount;
- VSCacheEntry &entry = iter->second;
- if (&entry.shader != pShaderLast) {
- pShaderLast = &entry.shader;
- }
- return pShaderLast;
- }
-
- VSCacheEntry& entry = vshaders[uid];
-
- if (!GenerateVertexShader(entry.shader, components)) {
- ERROR_LOG("failed to create vertex shader\n");
- }
-
- //Make an entry in the table
- entry.frameCount=frameCount;
-
- pShaderLast = &entry.shader;
- INCSTAT(stats.numVertexShadersCreated);
- SETSTAT(stats.numVertexShadersAlive,vshaders.size());
- return pShaderLast;
-}
-
-void VertexShaderMngr::Cleanup()
-{
- VSCache::iterator iter=vshaders.begin();
- while (iter != vshaders.end()) {
- VSCacheEntry &entry = iter->second;
- if (entry.frameCount < frameCount-200) {
- entry.Destroy();
-#ifdef _WIN32
- iter = vshaders.erase(iter);
-#else
- vshaders.erase(iter++);
-#endif
- }
- else {
- ++iter;
- }
- }
-
-// static int frame = 0;
-// if( frame++ > 30 ) {
-// VSCache::iterator iter=vshaders.begin();
-// while(iter!=vshaders.end()) {
-// iter->second.Destroy();
-// ++iter;
-// }
-// vshaders.clear();
-// }
-
- SETSTAT(stats.numPixelShadersAlive,vshaders.size());
-}
-
-bool VertexShaderMngr::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
-{
- char stropt[64];
- sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions);
-#ifdef _WIN32
- const char* opts[] = {"-profileopts",stropt,"-O2", "-q", NULL};
-#else
- const char* opts[] = {"-profileopts",stropt,"-q", NULL};
-#endif
- CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts);
- if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) {
- ERROR_LOG("Failed to load vs %s:\n", cgGetLastListing(g_cgcontext));
- ERROR_LOG(pstrprogram);
- return false;
- }
-
- //ERROR_LOG(pstrprogram);
- //ERROR_LOG("id: %d\n", g_Config.iSaveTargetId);
-
- char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
- char* plocal = strstr(pcompiledprog, "program.local");
-
- while( plocal != NULL ) {
- const char* penv = " program.env";
- memcpy(plocal, penv, 13);
- plocal = strstr(plocal+13, "program.local");
- }
-
- glGenProgramsARB( 1, &vs.glprogid );
- glBindProgramARB( GL_VERTEX_PROGRAM_ARB, vs.glprogid );
- glProgramStringARB( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
-
- GLenum err = GL_NO_ERROR;
- GL_REPORT_ERROR();
- if( err != GL_NO_ERROR ) {
- ERROR_LOG(pstrprogram);
- ERROR_LOG(pcompiledprog);
- }
-
- cgDestroyProgram(tempprog);
-
-#ifdef _DEBUG
- vs.strprog = pstrprogram;
-#endif
-
- return true;
-}
-
-// TODO: this array is misdeclared. Why teh f** does it go through the compilers?
-const u16 s_mtrltable[16][2] = {0, 0, 0, 1, 1, 1, 0, 2,
- 2, 1, 0, 3, 1, 2, 0, 3,
- 3, 1, 0, 4, 1, 3, 0, 4,
- 2, 2, 0, 4, 1, 3, 0, 4};
-
-/// syncs the shader constant buffers with xfmem
-void VertexShaderMngr::SetConstants(VERTEXSHADER& vs)
-{
- //nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256;
- //nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96;
- //nPostTransformMatricesChanged[0] = 0; nPostTransformMatricesChanged[1] = 256;
- //nLightsChanged[0] = 0; nLightsChanged[1] = 0x80;
- //bPosNormalMatrixChanged = true;
- //bTexMatricesChanged[0] = bTexMatricesChanged[1] = true;
- //bProjectionChanged = true;
-// bPosNormalMatrixChanged = bTexMatricesChanged[0] = bTexMatricesChanged[1] = true;
-// nMaterialsChanged = 15;
-
- if (nTransformMatricesChanged[0] >= 0) {
- int startn = nTransformMatricesChanged[0]/4;
- int endn = (nTransformMatricesChanged[1]+3)/4;
- const float* pstart = (const float*)&xfmem[startn*4];
- for(int i = startn; i < endn; ++i, pstart += 4)
- glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, C_TRANSFORMMATRICES+i, pstart);
- nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
- }
- if (nNormalMatricesChanged[0] >= 0) {
- int startn = nNormalMatricesChanged[0]/3;
- int endn = (nNormalMatricesChanged[1]+2)/3;
- const float* pnstart = (const float*)&xfmem[XFMEM_NORMALMATRICES+3*startn];
-
- for(int i = startn; i < endn; ++i, pnstart += 3)
- glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, C_NORMALMATRICES+i, pnstart);
-
- nNormalMatricesChanged[0] = nNormalMatricesChanged[1] = -1;
- }
-
- if (nPostTransformMatricesChanged[0] >= 0) {
- int startn = nPostTransformMatricesChanged[0]/4;
- int endn = (nPostTransformMatricesChanged[1]+3)/4;
- const float* pstart = (const float*)&xfmem[XFMEM_POSTMATRICES+startn*4];
- for(int i = startn; i < endn; ++i, pstart += 4)
- glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, C_POSTTRANSFORMMATRICES+i, pstart);
- }
-
- if (nLightsChanged[0] >= 0) {
- // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
- int istart = nLightsChanged[0]/0x10;
- int iend = (nLightsChanged[1]+15)/0x10;
- const float* xfmemptr = (const float*)&xfmem[0x10*istart+XFMEM_LIGHTS];
-
- for(int i = istart; i < iend; ++i) {
- u32 color = *(const u32*)(xfmemptr+3);
- glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, C_LIGHTS+5*i,
- ((color>>24)&0xFF)/255.0f, ((color>>16)&0xFF)/255.0f, ((color>>8)&0xFF)/255.0f, ((color)&0xFF)/255.0f);
- xfmemptr += 4;
- for(int j = 0; j < 4; ++j, xfmemptr += 3) {
- if( j == 1 && fabs(xfmemptr[0]) < 0.00001f && fabs(xfmemptr[1]) < 0.00001f && fabs(xfmemptr[2]) < 0.00001f) {
- // dist atten, make sure not equal to 0!!!
- glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, C_LIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
- }
- else
- glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, C_LIGHTS+5*i+j+1, xfmemptr);
- }
- }
-
- nLightsChanged[0] = nLightsChanged[1] = -1;
- }
-
- if (nMaterialsChanged) {
- for(int i = 0; i < 4; ++i) {
- if( nMaterialsChanged&(1<= MatrixIndexA.PosNormalMtxIdx*4 && (u32)start < MatrixIndexA.PosNormalMtxIdx*4+12) ||
- ((u32)start >= XFMEM_NORMALMATRICES+(MatrixIndexA.PosNormalMtxIdx&31)*3 && (u32)start < XFMEM_NORMALMATRICES+(MatrixIndexA.PosNormalMtxIdx&31)*3+9) ) {
- bPosNormalMatrixChanged = true;
- }
-
- if (((u32)start >= MatrixIndexA.Tex0MtxIdx*4 && (u32)start < MatrixIndexA.Tex0MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexA.Tex1MtxIdx*4 && (u32)start < MatrixIndexA.Tex1MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexA.Tex2MtxIdx*4 && (u32)start < MatrixIndexA.Tex2MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexA.Tex3MtxIdx*4 && (u32)start < MatrixIndexA.Tex3MtxIdx*4+12)) {
- bTexMatricesChanged[0] = true;
- }
-
- if (((u32)start >= MatrixIndexB.Tex4MtxIdx*4 && (u32)start < MatrixIndexB.Tex4MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexB.Tex5MtxIdx*4 && (u32)start < MatrixIndexB.Tex5MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexB.Tex6MtxIdx*4 && (u32)start < MatrixIndexB.Tex6MtxIdx*4+12) ||
- ((u32)start >= MatrixIndexB.Tex7MtxIdx*4 && (u32)start < MatrixIndexB.Tex7MtxIdx*4+12)) {
- bTexMatricesChanged[1] = true;
- }
-
- if (start < XFMEM_POSMATRICES_END ) {
- if (nTransformMatricesChanged[0] == -1) {
- nTransformMatricesChanged[0] = start;
- nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end;
- }
- else {
- if (nTransformMatricesChanged[0] > start) nTransformMatricesChanged[0] = start;
- if (nTransformMatricesChanged[1] < end) nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end;
- }
- }
-
- if (start < XFMEM_NORMALMATRICES_END && end > XFMEM_NORMALMATRICES ) {
- int _start = start < XFMEM_NORMALMATRICES ? 0 : start-XFMEM_NORMALMATRICES;
- int _end = end < XFMEM_NORMALMATRICES_END ? end-XFMEM_NORMALMATRICES : XFMEM_NORMALMATRICES_END-XFMEM_NORMALMATRICES;
-
- if (nNormalMatricesChanged[0] == -1 ) {
- nNormalMatricesChanged[0] = _start;
- nNormalMatricesChanged[1] = _end;
- }
- else {
- if (nNormalMatricesChanged[0] > _start) nNormalMatricesChanged[0] = _start;
- if (nNormalMatricesChanged[1] < _end) nNormalMatricesChanged[1] = _end;
- }
- }
-
- if (start < XFMEM_POSTMATRICES_END && end > XFMEM_POSTMATRICES ) {
- int _start = start < XFMEM_POSTMATRICES ? XFMEM_POSTMATRICES : start-XFMEM_POSTMATRICES;
- int _end = end < XFMEM_POSTMATRICES_END ? end-XFMEM_POSTMATRICES : XFMEM_POSTMATRICES_END-XFMEM_POSTMATRICES;
-
- if (nPostTransformMatricesChanged[0] == -1 ) {
- nPostTransformMatricesChanged[0] = _start;
- nPostTransformMatricesChanged[1] = _end;
- }
- else {
- if (nPostTransformMatricesChanged[0] > _start) nPostTransformMatricesChanged[0] = _start;
- if (nPostTransformMatricesChanged[1] < _end) nPostTransformMatricesChanged[1] = _end;
- }
- }
-
- if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS) {
- int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS;
- int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS;
-
- if (nLightsChanged[0] == -1 ) {
- nLightsChanged[0] = _start;
- nLightsChanged[1] = _end;
- }
- else {
- if (nLightsChanged[0] > _start) nLightsChanged[0] = _start;
- if (nLightsChanged[1] < _end) nLightsChanged[1] = _end;
- }
- }
-}
-
-void VertexShaderMngr::SetTexMatrixChangedA(u32 Value)
-{
- if (MatrixIndexA.Hex != Value) {
- VertexManager::Flush();
- if (MatrixIndexA.PosNormalMtxIdx != (Value&0x3f))
- bPosNormalMatrixChanged = true;
- bTexMatricesChanged[0] = true;
- MatrixIndexA.Hex = Value;
- }
-}
-
-void VertexShaderMngr::SetTexMatrixChangedB(u32 Value)
-{
- if (MatrixIndexB.Hex != Value) {
- VertexManager::Flush();
- bTexMatricesChanged[1] = true;
- MatrixIndexB.Hex = Value;
- }
-}
-
-void VertexShaderMngr::SetViewport(float* _Viewport)
-{
- // check for paper mario
- for (size_t i = 0; i < ARRAYSIZE(rawViewport); ++i) {
- if( *(u32*)(_Viewport + i) == 0x7f800000 )
- return; // invalid number
- }
-
- memcpy(rawViewport, _Viewport, sizeof(rawViewport));
- bViewportChanged = true;
-}
-
-void VertexShaderMngr::SetViewportChanged()
-{
- bViewportChanged = true;
-}
-
-void VertexShaderMngr::SetProjection(float* _pProjection, int constantIndex)
-{
- memcpy(rawProjection, _pProjection, sizeof(rawProjection));
- bProjectionChanged = true;
-}
-
-size_t VertexShaderMngr::SaveLoadState(char *ptr, BOOL save)
-{
- BEGINSAVELOAD;
-
- SAVELOAD(&xfregs,sizeof(xfregs));
- SAVELOAD(xfmem,XFMEM_SIZE*sizeof(u32));
- SAVELOAD(rawViewport,sizeof(rawViewport));
- SAVELOAD(rawProjection,sizeof(rawProjection));
- SAVELOAD(&MatrixIndexA,sizeof(TMatrixIndexA));
- SAVELOAD(&MatrixIndexB,sizeof(TMatrixIndexB));
-
- if (!save) {
- // invalidate all
- InvalidateXFRange(0,0x1000);
- }
-
- ENDSAVELOAD;
-}
-
-// LoadXFReg 0x10
-void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
-{
-
- u32 address = baseAddress;
- for (int i=0; i<(int)transferSize; i++)
- {
- address = baseAddress + i;
-
- // Setup a Matrix
- if (address < 0x1000)
- {
- VertexManager::Flush();
- InvalidateXFRange(address, address+transferSize);
- //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
-
- u32* p1 = &xfmem[address];
- memcpy_gc(p1, &pData[i], transferSize*4);
- i += transferSize;
- }
- else if (address<0x2000)
- {
- u32 data = pData[i];
- switch (address)
- {
- case 0x1000: // error
- break;
- case 0x1001: // diagnostics
- break;
- case 0x1002: // internal state 0
- break;
- case 0x1003: // internal state 1
- break;
- case 0x1004: // xf_clock
- break;
- case 0x1005: // clipdisable
- if (data & 1) { // disable clipping detection
- }
- if (data & 2) { // disable trivial rejection
- }
- if (data & 4) { // disable cpoly clipping acceleration
- }
- break;
- case 0x1006: //SetGPMetric
- break;
- case 0x1008: //__GXXfVtxSpecs, wrote 0004
- xfregs.hostinfo = *(INVTXSPEC*)&data;
- break;
- case 0x1009: //GXSetNumChans (no)
- if (xfregs.nNumChans != (data&3) ) {
- VertexManager::Flush();
- xfregs.nNumChans = data&3;
- }
- break;
- case 0x100a: //GXSetChanAmbientcolor
- if (xfregs.colChans[0].ambColor != data) {
- VertexManager::Flush();
- nMaterialsChanged |= 1;
- xfregs.colChans[0].ambColor = data;
- s_fMaterials[0] = ((data>>24)&0xFF)/255.0f;
- s_fMaterials[1] = ((data>>16)&0xFF)/255.0f;
- s_fMaterials[2] = ((data>>8)&0xFF)/255.0f;
- s_fMaterials[3] = ((data)&0xFF)/255.0f;
- }
- break;
- case 0x100b: //GXSetChanAmbientcolor
- if (xfregs.colChans[1].ambColor != data) {
- VertexManager::Flush();
- nMaterialsChanged |= 2;
- xfregs.colChans[1].ambColor = data;
- s_fMaterials[4] = ((data>>24)&0xFF)/255.0f;
- s_fMaterials[5] = ((data>>16)&0xFF)/255.0f;
- s_fMaterials[6] = ((data>>8)&0xFF)/255.0f;
- s_fMaterials[7] = ((data)&0xFF)/255.0f;
- }
- break;
- case 0x100c: //GXSetChanMatcolor (rgba)
- if (xfregs.colChans[0].matColor != data) {
- VertexManager::Flush();
- nMaterialsChanged |= 4;
- xfregs.colChans[0].matColor = data;
- s_fMaterials[8] = ((data>>24)&0xFF)/255.0f;
- s_fMaterials[9] = ((data>>16)&0xFF)/255.0f;
- s_fMaterials[10] = ((data>>8)&0xFF)/255.0f;
- s_fMaterials[11] = ((data)&0xFF)/255.0f;
- }
- break;
- case 0x100d: //GXSetChanMatcolor (rgba)
- if (xfregs.colChans[1].matColor != data) {
- VertexManager::Flush();
- nMaterialsChanged |= 8;
- xfregs.colChans[1].matColor = data;
- s_fMaterials[12] = ((data>>24)&0xFF)/255.0f;
- s_fMaterials[13] = ((data>>16)&0xFF)/255.0f;
- s_fMaterials[14] = ((data>>8)&0xFF)/255.0f;
- s_fMaterials[15] = ((data)&0xFF)/255.0f;
- }
- break;
-
- case 0x100e: // color0
- if (xfregs.colChans[0].color.hex != (data&0x7fff) ) {
- VertexManager::Flush();
- xfregs.colChans[0].color.hex = data;
- }
- break;
- case 0x100f: // color1
- if (xfregs.colChans[1].color.hex != (data&0x7fff) ) {
- VertexManager::Flush();
- xfregs.colChans[1].color.hex = data;
- }
- break;
- case 0x1010: // alpha0
- if (xfregs.colChans[0].alpha.hex != (data&0x7fff) ) {
- VertexManager::Flush();
- xfregs.colChans[0].alpha.hex = data;
- }
- break;
- case 0x1011: // alpha1
- if (xfregs.colChans[1].alpha.hex != (data&0x7fff) ) {
- VertexManager::Flush();
- xfregs.colChans[1].alpha.hex = data;
- }
- break;
- case 0x1012: // dual tex transform
- if (xfregs.bEnableDualTexTransform != (data&1)) {
- VertexManager::Flush();
- xfregs.bEnableDualTexTransform = data&1;
- }
- break;
-
- case 0x1013:
- case 0x1014:
- case 0x1015:
- case 0x1016:
- case 0x1017:
- DEBUG_LOG("xf addr: %x=%x\n", address, data);
- break;
- case 0x1018:
- //_assert_msg_(GX_XF, 0, "XF matrixindex0");
- VertexShaderMngr::SetTexMatrixChangedA(data); //?
- break;
- case 0x1019:
- //_assert_msg_(GX_XF, 0, "XF matrixindex1");
- VertexShaderMngr::SetTexMatrixChangedB(data); //?
- break;
-
- case 0x101a:
- VertexManager::Flush();
- VertexShaderMngr::SetViewport((float*)&pData[i]);
- i += 6;
- break;
-
- case 0x101c: // paper mario writes 16777216.0f, 1677721.75
- break;
- case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
- break;
-
- case 0x1020:
- VertexManager::Flush();
- VertexShaderMngr::SetProjection((float*)&pData[i]);
- i += 7;
- return;
-
- case 0x103f: // GXSetNumTexGens
- if (xfregs.numTexGens != data) {
- VertexManager::Flush();
- xfregs.numTexGens = data;
- }
- break;
-
- case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break;
- case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break;
- case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break;
- case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break;
- case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break;
- case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break;
- case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break;
- case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break;
-
- case 0x1048:
- case 0x1049:
- case 0x104a:
- case 0x104b:
- case 0x104c:
- case 0x104d:
- case 0x104e:
- case 0x104f:
- DEBUG_LOG("xf addr: %x=%x\n", address, data);
- break;
- case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break;
- case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break;
- case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break;
- case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break;
- case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break;
- case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break;
- case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break;
- case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
-
- default:
- DEBUG_LOG("xf addr: %x=%x\n", address, data);
- break;
- }
- }
- else if (address>=0x4000)
- {
- // MessageBox(NULL, "1", "1", MB_OK);
- //4010 __GXSetGenMode
- }
- }
-}
-
-// Check docs for this sucker...
-void VertexShaderMngr::LoadIndexedXF(u32 val, int array)
-{
- int index = val>>16;
- int address = val&0xFFF; //check mask
- int size = ((val>>12)&0xF)+1;
- //load stuff from array to address in xf mem
-
- VertexManager::Flush();
- InvalidateXFRange(address, address+size);
- //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size);
-
- for (int i = 0; i < size; i++)
- xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array]*index + i*4);
-}
-
-float* VertexShaderMngr::GetPosNormalMat()
-{
- return (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
-}
-
-void VertexShaderMngr::GetVertexShaderId(VERTEXSHADERUID& id, u32 components)
-{
- u32 zbufrender = (bpmem.ztex2.op==ZTEXTURE_ADD)||Renderer::GetZBufferTarget()!=0;
- id.values[0] = components|(xfregs.numTexGens<<23)|(xfregs.nNumChans<<27)|((u32)xfregs.bEnableDualTexTransform<<29)|(zbufrender<<30);
-
- for(int i = 0; i < 2; ++i) {
- id.values[1+i] = xfregs.colChans[i].color.enablelighting?(u32)xfregs.colChans[i].color.hex:(u32)xfregs.colChans[i].color.matsource;
- id.values[1+i] |= (xfregs.colChans[i].alpha.enablelighting?(u32)xfregs.colChans[i].alpha.hex:(u32)xfregs.colChans[i].alpha.matsource)<<15;
- }
- // fog
- id.values[1] |= (((u32)bpmem.fog.c_proj_fsel.fsel&3)<<30);
- id.values[2] |= (((u32)bpmem.fog.c_proj_fsel.fsel>>2)<<30);
-
- u32* pcurvalue = &id.values[3];
-
- for(int i = 0; i < xfregs.numTexGens; ++i) {
- TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
- if( tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP )
- tinfo.hex &= 0x7ff;
- if( tinfo.texgentype != XF_TEXGEN_REGULAR )
- tinfo.projection = 0;
-
- u32 val = ((tinfo.hex>>1)&0x1ffff);
- if( xfregs.bEnableDualTexTransform && tinfo.texgentype == XF_TEXGEN_REGULAR ) {
- // rewrite normalization and post index
- val |= ((u32)xfregs.texcoords[i].postmtxinfo.index<<17)|((u32)xfregs.texcoords[i].postmtxinfo.normalize<<23);
- }
-
- switch(i & 3) {
- case 0: pcurvalue[0] |= val; break;
- case 1: pcurvalue[0] |= val<<24; pcurvalue[1] = val>>8; ++pcurvalue; break;
- case 2: pcurvalue[0] |= val<<16; pcurvalue[1] = val>>16; ++pcurvalue; break;
- case 3: pcurvalue[0] |= val<<8; ++pcurvalue; break;
- }
- }
-}
-
static char text[16384];
#define WRITE p+=sprintf
#define LIGHTS_POS ""
-bool VertexShaderMngr::GenerateVertexShader(VERTEXSHADER& vs, u32 components)
+char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char* dest, int coloralpha);
+
+bool GenerateVertexShader(VERTEXSHADER& vs, u32 components)
{
DVSTARTPROFILE();
@@ -1180,7 +408,7 @@ bool VertexShaderMngr::GenerateVertexShader(VERTEXSHADER& vs, u32 components)
}
// coloralpha - 1 if color, 2 if alpha
-char* VertexShaderMngr::GenerateLightShader(char* p, int index, const LitChannel& chan, const char* dest, int coloralpha)
+char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char* dest, int coloralpha)
{
const char* swizzle = "xyzw";
if( coloralpha == 1 ) swizzle = "xyz";
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.h
index d3f3f79255..1207eaec02 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShader.h
@@ -18,7 +18,6 @@
#ifndef GCOGL_VERTEXSHADER_H
#define GCOGL_VERTEXSHADER_H
-#include