Roll back r3833 for render targets but keep it for static textures. Most mirroring issues are OK and we shouldn't see any slowdown.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3844 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2009-07-19 08:17:41 +00:00
parent ad440b9e47
commit fd70f99f04
11 changed files with 220 additions and 90 deletions

View File

@ -28,7 +28,7 @@
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
// It would likely be a lot more efficient to build this incrementally as the attributes
// are set...
void GetPixelShaderId(PIXELSHADERUID &uid, u32 dstAlphaEnable)
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable)
{
u32 projtexcoords = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; i++) {
@ -51,7 +51,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 dstAlphaEnable)
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] = 0;
uid.values[2] = s_texturemask;
uid.values[3] = (u32)bpmem.fog.c_proj_fsel.fsel |
((u32)bpmem.fog.c_proj_fsel.proj << 3);
@ -130,8 +130,8 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 dstAlphaEnable)
// output is given by .outreg
// tevtemp is set according to swapmodetables and
static void WriteStage(char *&p, int n);
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap);
static void WriteStage(char *&p, int n, u32 texture_mask);
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask);
static void WriteAlphaCompare(char *&p, int num, int comp);
static bool WriteAlphaTest(char *&p, bool HLSL);
static void WriteFog(char *&p);
@ -368,7 +368,7 @@ static void BuildSwapModeTable()
}
}
const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL)
{
text[sizeof(text) - 1] = 0x7C; // canary
DVSTARTPROFILE();
@ -391,13 +391,30 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
}
}
WRITE(p, "uniform sampler2D ");
bool bfirst = true;
for (int i = 0; i < 8; ++i) {
WRITE(p, "%s samp%d : register(s%d)", bfirst ? "" : ",",i, i);
bfirst = false;
// Declare samplers
if (texture_mask) {
WRITE(p, "uniform samplerRECT ");
bool bfirst = true;
for (int i = 0; i < 8; ++i) {
if (texture_mask & (1<<i)) {
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i);
bfirst = false;
}
}
WRITE(p, ";\n");
}
if (texture_mask != 0xff) {
WRITE(p, "uniform sampler2D ");
bool bfirst = true;
for (int i = 0; i < 8; ++i) {
if (!(texture_mask & (1<<i))) {
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",",i, i);
bfirst = false;
}
}
WRITE(p, ";\n");
}
WRITE(p, ";\n");
WRITE(p, "\n");
@ -459,7 +476,7 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
char buffer[32];
sprintf(buffer, "float3 indtex%d", i);
SampleTexture(p, buffer, "tempcoord", "abg", bpmem.tevindref.getTexMap(i));
SampleTexture(p, buffer, "tempcoord", "abg", bpmem.tevindref.getTexMap(i), texture_mask);
}
}
@ -469,7 +486,7 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
}
for (int i = 0; i < numStages; i++)
WriteStage(p, i); //build the equation for this stage
WriteStage(p, i, texture_mask); //build the equation for this stage
if (numTexgen >= 7) {
WRITE(p, "float4 clipPos = float4(uv0.w, uv1.w, uv2.w, uv3.w);\n");
@ -512,7 +529,7 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
return text;
}
static void WriteStage(char *&p, int n)
static void WriteStage(char *&p, int n, u32 texture_mask)
{
char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap];
char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap];
@ -612,7 +629,7 @@ static void WriteStage(char *&p, int n)
}
}
WRITE(p, "rastemp=%s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap);
WRITE(p, "rastemp=%s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)],rasswap);
if (bpmem.tevorders[n/2].getEnable(n&1)) {
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
@ -625,7 +642,7 @@ static void WriteStage(char *&p, int n)
}
}
SampleTexture(p, "textemp", "tevcoord", texswap, texmap);
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask);
}
else
WRITE(p, "textemp=float4(1,1,1,1);\n");
@ -732,9 +749,37 @@ static void WriteStage(char *&p, int n)
WRITE(p, "\n");
}
void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap)
void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask)
{
WRITE(p, "%s=tex2D(samp%d,%s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
if (texture_mask & (1<<texmap)) {
// non pow 2
bool bwraps = (texture_mask & (0x100<<texmap)) ? true : false;
bool bwrapt = (texture_mask & (0x10000<<texmap)) ? true : false;
if (bwraps || bwrapt) {
if (bwraps) {
WRITE(p, "tempcoord.x = fmod(%s.x, "I_TEXDIMS"[%d].x);\n", texcoords, texmap);
}
else {
WRITE(p, "tempcoord.x = %s.x;\n", texcoords);
}
if (bwrapt) {
WRITE(p, "tempcoord.y = fmod(%s.y, "I_TEXDIMS"[%d].y);\n", texcoords, texmap);
}
else {
WRITE(p, "tempcoord.y = %s.y;\n", texcoords);
}
WRITE(p, "%s=texRECT(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap);
}
else {
WRITE(p, "%s=texRECT(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap);
}
}
else {
WRITE(p, "%s=tex2D(samp%d,%s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
}
}
static void WriteAlphaCompare(char *&p, int num, int comp)

View File

@ -92,7 +92,7 @@ public:
}
};
const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL = false);
void GetPixelShaderId(PIXELSHADERUID &, u32 dstAlphaEnable);
const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL = false);
void GetPixelShaderId(PIXELSHADERUID &, u32 s_texturemask, u32 dstAlphaEnable);
#endif

View File

@ -40,6 +40,11 @@ static u32 lastAlpha = 0;
static u32 lastTexDims[8]={0}; // width | height << 16 | wrap_s << 28 | wrap_t << 30
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;
void PixelShaderManager::Init()
{
s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
@ -203,15 +208,26 @@ void PixelShaderManager::SetConstants()
void PixelShaderManager::SetPSTextureDims(int texid)
{
// texdims.xy are reciprocals of the real texture dimensions
// texdims.zw are the scaled dimensions
// non pow 2 textures - texdims.xy are the real texture dimensions used for wrapping
// pow 2 textures - texdims.xy are reciprocals of the real texture dimensions
// both - texdims.zw are the scaled dimensions
float fdims[4];
TCoordInfo& tc = bpmem.texcoords[texid];
fdims[0] = 1.0f / (float)(lastTexDims[texid] & 0xffff);
fdims[1] = 1.0f / (float)((lastTexDims[texid] >> 16) & 0xfff);
fdims[2] = (float)(tc.s.scale_minus_1 + 1) * lastCustomTexScale[texid][0];
fdims[3] = (float)(tc.t.scale_minus_1 + 1) * lastCustomTexScale[texid][1];
if (s_texturemask & (1 << texid))
{
TCoordInfo& tc = bpmem.texcoords[texid];
fdims[0] = (float)(lastTexDims[texid] & 0xffff);
fdims[1] = (float)((lastTexDims[texid] >> 16) & 0xfff);
fdims[2] = (float)(tc.s.scale_minus_1 + 1)*lastCustomTexScale[texid][0];
fdims[3] = (float)(tc.t.scale_minus_1 + 1)*lastCustomTexScale[texid][1];
}
else
{
TCoordInfo& tc = bpmem.texcoords[texid];
fdims[0] = 1.0f / (float)(lastTexDims[texid] & 0xffff);
fdims[1] = 1.0f / (float)((lastTexDims[texid] >> 16) & 0xfff);
fdims[2] = (float)(tc.s.scale_minus_1 + 1) * lastCustomTexScale[texid][0];
fdims[3] = (float)(tc.t.scale_minus_1 + 1) * lastCustomTexScale[texid][1];
}
PRIM_LOG("texdims%d: %f %f %f %f\n", texid, fdims[0], fdims[1], fdims[2], fdims[3]);
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
@ -312,6 +328,23 @@ void PixelShaderManager::SetZTextureTypeChanged()
s_bZTextureTypeChanged = true;
}
void PixelShaderManager::SetTexturesUsed(u32 nonpow2tex)
{
if (s_texturemask != nonpow2tex)
{
for (int i = 0; i < 8; ++i)
{
if (nonpow2tex & (0x10101 << i))
{
// this check was previously implicit, but should it be here?
if (s_nTexDimsChanged )
s_nTexDimsChanged |= 1 << i;
}
}
s_texturemask = nonpow2tex;
}
}
void PixelShaderManager::SetTexCoordChanged(u8 texmapid)
{
s_nTexDimsChanged |= 1 << texmapid;
@ -335,3 +368,8 @@ void PixelShaderManager::SetColorMatrix(const float* pmatrix, const float* pfCon
SetPSConstant4fv(C_COLORMATRIX+3, pmatrix+12);
SetPSConstant4fv(C_COLORMATRIX+4, pfConstAdd);
}
u32 PixelShaderManager::GetTextureMask()
{
return s_texturemask;
}

View File

@ -46,10 +46,12 @@ public:
static void SetTevKSelChanged(int id);
static void SetZTextureTypeChanged();
static void SetIndTexScaleChanged(u8 stagemask);
static void SetTexturesUsed(u32 nonpow2tex);
static void SetTexCoordChanged(u8 texmapid);
static void SetFogColorChanged();
static void SetFogParamChanged();
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
static u32 GetTextureMask();
};

View File

@ -410,7 +410,7 @@ const char *GenerateVertexShader(u32 components)
break;
}
if (xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
if(xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
if (xfregs.texcoords[i].postmtxinfo.normalize)
WRITE(p, "o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i);
@ -470,8 +470,7 @@ char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char
if (coloralpha == 1 ) swizzle = "xyz";
else if (coloralpha == 2 ) swizzle = "w";
if (!(chan.attnfunc & 1))
{
if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
@ -486,9 +485,7 @@ char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char
default: _assert_(0);
}
}
else
{
// spec and spot
else { // spec and spot
WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index);
if (chan.attnfunc == 3) { // spot