diff options
| author | hrydgard <hrydgard@gmail.com> | 2008-12-26 10:43:18 +0000 |
|---|---|---|
| committer | hrydgard <hrydgard@gmail.com> | 2008-12-26 10:43:18 +0000 |
| commit | fa9f5c44fb4d8ae3d6b2b43ec31ce9cbbe1e2d7d (patch) | |
| tree | b0d15f77aff8d18000d44fd66e090f2457ceed8f /Source/Core/VideoCommon | |
| parent | 3669d711a2e7e6ceae13b428106ab309865311f2 (diff) | |
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
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/Src/PixelShader.cpp | 93 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/PixelShader.h | 51 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexShader.cpp | 46 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexShader.h | 49 |
4 files changed, 239 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/Src/PixelShader.cpp b/Source/Core/VideoCommon/Src/PixelShader.cpp index 9b5615be18..779898bafa 100644 --- a/Source/Core/VideoCommon/Src/PixelShader.cpp +++ b/Source/Core/VideoCommon/Src/PixelShader.cpp @@ -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 diff --git a/Source/Core/VideoCommon/Src/PixelShader.h b/Source/Core/VideoCommon/Src/PixelShader.h index 9823a2870b..876daefb2f 100644 --- a/Source/Core/VideoCommon/Src/PixelShader.h +++ b/Source/Core/VideoCommon/Src/PixelShader.h @@ -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 diff --git a/Source/Core/VideoCommon/Src/VertexShader.cpp b/Source/Core/VideoCommon/Src/VertexShader.cpp index 04acf1c651..5fd307b881 100644 --- a/Source/Core/VideoCommon/Src/VertexShader.cpp +++ b/Source/Core/VideoCommon/Src/VertexShader.cpp @@ -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 diff --git a/Source/Core/VideoCommon/Src/VertexShader.h b/Source/Core/VideoCommon/Src/VertexShader.h index 309a6ab8b5..2680581acb 100644 --- a/Source/Core/VideoCommon/Src/VertexShader.h +++ b/Source/Core/VideoCommon/Src/VertexShader.h @@ -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 |
