More code movin' .. split Vertex/Pixelshadermngr into xxCache and xxManager.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1677 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-12-26 10:43:18 +00:00
parent 3669d711a2
commit fa9f5c44fb
17 changed files with 436 additions and 424 deletions

View File

@ -24,6 +24,99 @@
#include "XFMemory.h" // for texture projection mode
#include "BPMemory.h"
// Mash together all the inputs that contribute to the code of a generated pixel shader into
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u32 zBufRenderToCol0)
{
u32 projtexcoords = 0;
for (u32 i = 0; i < (u32)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 << texcoord;
}
}
uid.values[0] = (u32)bpmem.genMode.numtevstages |
((u32)bpmem.genMode.numindstages << 4) |
((u32)bpmem.genMode.numtexgens << 7) |
((u32)bpmem.dstalpha.enable << 11) |
((u32)((bpmem.alphaFunc.hex >> 16) & 0xff) << 12) |
(projtexcoords << 20) |
((u32)bpmem.ztex2.op << 28) |
(zbufrender << 30) |
(zBufRenderToCol0 << 31);
uid.values[0] = (uid.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 < (u32)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 < ((u32)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;
}
}
// yeah, well ....
uid.indstages = (u32)(pcurvalue - &uid.values[0] - 2 - uid.tevstages);
}
// old tev->pixelshader notes
//
// color for this stage (alpha, color) is given by bpmem.tevorders[0].colorchan0

View File

@ -39,6 +39,57 @@
#define C_COLORMATRIX (C_INDTEXMTX+6)
class PIXELSHADERUID
{
public:
u32 values[4+32+6+11];
u16 tevstages, indstages;
PIXELSHADERUID() {
memset(values, 0, (4+32+6+11) * 4);
tevstages = indstages = 0;
}
PIXELSHADERUID(const PIXELSHADERUID& r)
{
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];
}
int GetNumValues() const {
return tevstages + indstages + 3; // numTevStages*3/2+1
}
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 = GetNumValues();
for (int i = 1; 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 = GetNumValues();
for (int i = 1; i < N; ++i) {
if (values[i] != _Right.values[i])
return false;
}
return true;
}
};
char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool bRenderZToCol0);
void GetPixelShaderId(PIXELSHADERUID &, u32 s_texturemask, u32 zbufrender, u32 zBufRenderToCol0);
#endif

View File

@ -23,6 +23,52 @@
#include "BPMemory.h"
#include "VertexShader.h"
// Mash together all the inputs that contribute to the code of a generated vertex shader into
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
void GetVertexShaderId(VERTEXSHADERUID& vid, u32 components, u32 zbufrender)
{
vid.values[0] = components |
(xfregs.numTexGens << 23) |
(xfregs.nNumChans << 27) |
((u32)xfregs.bEnableDualTexTransform << 29) |
(zbufrender << 30);
for (int i = 0; i < 2; ++i) {
vid.values[1+i] = xfregs.colChans[i].color.enablelighting ?
(u32)xfregs.colChans[i].color.hex :
(u32)xfregs.colChans[i].color.matsource;
vid.values[1+i] |= (xfregs.colChans[i].alpha.enablelighting ?
(u32)xfregs.colChans[i].alpha.hex :
(u32)xfregs.colChans[i].alpha.matsource) << 15;
}
// fog
vid.values[1] |= (((u32)bpmem.fog.c_proj_fsel.fsel & 3) << 30);
vid.values[2] |= (((u32)bpmem.fog.c_proj_fsel.fsel >> 2) << 30);
u32* pcurvalue = &vid.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

View File

@ -46,6 +46,55 @@
#define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES+32)
#define C_FOGPARAMS (C_POSTTRANSFORMMATRICES+64)
class VERTEXSHADERUID
{
public:
u32 values[9];
VERTEXSHADERUID() {
memset(values, 0, sizeof(values));
}
VERTEXSHADERUID(const VERTEXSHADERUID& r) {
for (size_t i = 0; i < sizeof(values) / sizeof(u32); ++i)
values[i] = r.values[i];
}
int GetNumValues() const {
return (((values[0] >> 23) & 0xf)*3 + 3)/4 + 3; // numTexGens*3/4+1
}
bool operator <(const VERTEXSHADERUID& _Right) const
{
if (values[0] < _Right.values[0])
return true;
else if (values[0] > _Right.values[0])
return false;
int N = GetNumValues();
for (int i = 1; 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 VERTEXSHADERUID& _Right) const
{
if (values[0] != _Right.values[0])
return false;
int N = GetNumValues();
for (int i = 1; i < N; ++i) {
if (values[i] != _Right.values[i])
return false;
}
return true;
}
};
char *GenerateVertexShader(u32 components, bool has_zbuffer_target);
void GetVertexShaderId(VERTEXSHADERUID& vid, u32 components, u32 zbufrender);
#endif