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:
parent
ad440b9e47
commit
fd70f99f04
|
@ -28,7 +28,7 @@
|
||||||
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
|
// 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
|
// It would likely be a lot more efficient to build this incrementally as the attributes
|
||||||
// are set...
|
// are set...
|
||||||
void GetPixelShaderId(PIXELSHADERUID &uid, u32 dstAlphaEnable)
|
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable)
|
||||||
{
|
{
|
||||||
u32 projtexcoords = 0;
|
u32 projtexcoords = 0;
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; i++) {
|
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)
|
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);
|
((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 |
|
uid.values[3] = (u32)bpmem.fog.c_proj_fsel.fsel |
|
||||||
((u32)bpmem.fog.c_proj_fsel.proj << 3);
|
((u32)bpmem.fog.c_proj_fsel.proj << 3);
|
||||||
|
@ -130,8 +130,8 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 dstAlphaEnable)
|
||||||
// output is given by .outreg
|
// output is given by .outreg
|
||||||
// tevtemp is set according to swapmodetables and
|
// tevtemp is set according to swapmodetables and
|
||||||
|
|
||||||
static void WriteStage(char *&p, int n);
|
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);
|
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 void WriteAlphaCompare(char *&p, int num, int comp);
|
||||||
static bool WriteAlphaTest(char *&p, bool HLSL);
|
static bool WriteAlphaTest(char *&p, bool HLSL);
|
||||||
static void WriteFog(char *&p);
|
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
|
text[sizeof(text) - 1] = 0x7C; // canary
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
@ -391,13 +391,30 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 ");
|
WRITE(p, "uniform sampler2D ");
|
||||||
bool bfirst = true;
|
bool bfirst = true;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
WRITE(p, "%s samp%d : register(s%d)", bfirst ? "" : ",",i, i);
|
if (!(texture_mask & (1<<i))) {
|
||||||
|
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",",i, i);
|
||||||
bfirst = false;
|
bfirst = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
WRITE(p, ";\n");
|
WRITE(p, ";\n");
|
||||||
|
}
|
||||||
|
|
||||||
WRITE(p, "\n");
|
WRITE(p, "\n");
|
||||||
|
|
||||||
|
@ -459,7 +476,7 @@ const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL)
|
||||||
|
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
sprintf(buffer, "float3 indtex%d", i);
|
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++)
|
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) {
|
if (numTexgen >= 7) {
|
||||||
WRITE(p, "float4 clipPos = float4(uv0.w, uv1.w, uv2.w, uv3.w);\n");
|
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;
|
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 *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap];
|
||||||
char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap];
|
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)) {
|
if (bpmem.tevorders[n/2].getEnable(n&1)) {
|
||||||
int texmap = bpmem.tevorders[n/2].getTexMap(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
|
else
|
||||||
WRITE(p, "textemp=float4(1,1,1,1);\n");
|
WRITE(p, "textemp=float4(1,1,1,1);\n");
|
||||||
|
@ -732,9 +749,37 @@ static void WriteStage(char *&p, int n)
|
||||||
WRITE(p, "\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)
|
||||||
{
|
{
|
||||||
|
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);
|
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)
|
static void WriteAlphaCompare(char *&p, int num, int comp)
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *GeneratePixelShader(bool dstAlphaEnable, bool HLSL = false);
|
const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL = false);
|
||||||
void GetPixelShaderId(PIXELSHADERUID &, u32 dstAlphaEnable);
|
void GetPixelShaderId(PIXELSHADERUID &, u32 s_texturemask, u32 dstAlphaEnable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,6 +40,11 @@ static u32 lastAlpha = 0;
|
||||||
static u32 lastTexDims[8]={0}; // width | height << 16 | wrap_s << 28 | wrap_t << 30
|
static u32 lastTexDims[8]={0}; // width | height << 16 | wrap_s << 28 | wrap_t << 30
|
||||||
static u32 lastZBias = 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;
|
||||||
|
|
||||||
void PixelShaderManager::Init()
|
void PixelShaderManager::Init()
|
||||||
{
|
{
|
||||||
s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
|
s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
|
||||||
|
@ -203,15 +208,26 @@ void PixelShaderManager::SetConstants()
|
||||||
|
|
||||||
void PixelShaderManager::SetPSTextureDims(int texid)
|
void PixelShaderManager::SetPSTextureDims(int texid)
|
||||||
{
|
{
|
||||||
// texdims.xy are reciprocals of the real texture dimensions
|
// non pow 2 textures - texdims.xy are the real texture dimensions used for wrapping
|
||||||
// texdims.zw are the scaled dimensions
|
// pow 2 textures - texdims.xy are reciprocals of the real texture dimensions
|
||||||
|
// both - texdims.zw are the scaled dimensions
|
||||||
float fdims[4];
|
float fdims[4];
|
||||||
|
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];
|
TCoordInfo& tc = bpmem.texcoords[texid];
|
||||||
fdims[0] = 1.0f / (float)(lastTexDims[texid] & 0xffff);
|
fdims[0] = 1.0f / (float)(lastTexDims[texid] & 0xffff);
|
||||||
fdims[1] = 1.0f / (float)((lastTexDims[texid] >> 16) & 0xfff);
|
fdims[1] = 1.0f / (float)((lastTexDims[texid] >> 16) & 0xfff);
|
||||||
fdims[2] = (float)(tc.s.scale_minus_1 + 1) * lastCustomTexScale[texid][0];
|
fdims[2] = (float)(tc.s.scale_minus_1 + 1) * lastCustomTexScale[texid][0];
|
||||||
fdims[3] = (float)(tc.t.scale_minus_1 + 1) * lastCustomTexScale[texid][1];
|
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]);
|
PRIM_LOG("texdims%d: %f %f %f %f\n", texid, fdims[0], fdims[1], fdims[2], fdims[3]);
|
||||||
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
|
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
|
||||||
|
@ -312,6 +328,23 @@ void PixelShaderManager::SetZTextureTypeChanged()
|
||||||
s_bZTextureTypeChanged = true;
|
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)
|
void PixelShaderManager::SetTexCoordChanged(u8 texmapid)
|
||||||
{
|
{
|
||||||
s_nTexDimsChanged |= 1 << 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+3, pmatrix+12);
|
||||||
SetPSConstant4fv(C_COLORMATRIX+4, pfConstAdd);
|
SetPSConstant4fv(C_COLORMATRIX+4, pfConstAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 PixelShaderManager::GetTextureMask()
|
||||||
|
{
|
||||||
|
return s_texturemask;
|
||||||
|
}
|
||||||
|
|
|
@ -46,10 +46,12 @@ public:
|
||||||
static void SetTevKSelChanged(int id);
|
static void SetTevKSelChanged(int id);
|
||||||
static void SetZTextureTypeChanged();
|
static void SetZTextureTypeChanged();
|
||||||
static void SetIndTexScaleChanged(u8 stagemask);
|
static void SetIndTexScaleChanged(u8 stagemask);
|
||||||
|
static void SetTexturesUsed(u32 nonpow2tex);
|
||||||
static void SetTexCoordChanged(u8 texmapid);
|
static void SetTexCoordChanged(u8 texmapid);
|
||||||
static void SetFogColorChanged();
|
static void SetFogColorChanged();
|
||||||
static void SetFogParamChanged();
|
static void SetFogParamChanged();
|
||||||
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
|
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
|
||||||
|
static u32 GetTextureMask();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ const char *GenerateVertexShader(u32 components)
|
||||||
break;
|
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)
|
if (xfregs.texcoords[i].postmtxinfo.normalize)
|
||||||
WRITE(p, "o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i);
|
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";
|
if (coloralpha == 1 ) swizzle = "xyz";
|
||||||
else if (coloralpha == 2 ) swizzle = "w";
|
else if (coloralpha == 2 ) swizzle = "w";
|
||||||
|
|
||||||
if (!(chan.attnfunc & 1))
|
if (!(chan.attnfunc & 1)) {
|
||||||
{
|
|
||||||
// atten disabled
|
// atten disabled
|
||||||
switch (chan.diffusefunc) {
|
switch (chan.diffusefunc) {
|
||||||
case LIGHTDIF_NONE:
|
case LIGHTDIF_NONE:
|
||||||
|
@ -486,9 +485,7 @@ char* GenerateLightShader(char* p, int index, const LitChannel& chan, const char
|
||||||
default: _assert_(0);
|
default: _assert_(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else { // spec and spot
|
||||||
{
|
|
||||||
// spec and spot
|
|
||||||
WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index);
|
WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index);
|
||||||
|
|
||||||
if (chan.attnfunc == 3) { // spot
|
if (chan.attnfunc == 3) { // spot
|
||||||
|
|
|
@ -67,7 +67,7 @@ void PixelShaderCache::SetShader()
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(uid, false);
|
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), false);
|
||||||
|
|
||||||
PSCache::iterator iter;
|
PSCache::iterator iter;
|
||||||
iter = PixelShaders.find(uid);
|
iter = PixelShaders.find(uid);
|
||||||
|
@ -85,7 +85,7 @@ void PixelShaderCache::SetShader()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HLSL = false;
|
bool HLSL = false;
|
||||||
const char *code = GeneratePixelShader(false, HLSL);
|
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), false, HLSL);
|
||||||
LPDIRECT3DPIXELSHADER9 shader = HLSL ? D3D::CompilePixelShader(code, (int)strlen(code), false) : CompileCgShader(code);
|
LPDIRECT3DPIXELSHADER9 shader = HLSL ? D3D::CompilePixelShader(code, (int)strlen(code), false) : CompileCgShader(code);
|
||||||
if (shader)
|
if (shader)
|
||||||
{
|
{
|
||||||
|
|
|
@ -198,6 +198,7 @@ void Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 nonpow2tex = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i)) {
|
if (usedtextures & (1 << i)) {
|
||||||
|
@ -210,14 +211,25 @@ void Flush()
|
||||||
|
|
||||||
if (tentry) {
|
if (tentry) {
|
||||||
// texture loaded fine, set dims for pixel shader
|
// texture loaded fine, set dims for pixel shader
|
||||||
|
if (tentry->isNonPow2) {
|
||||||
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, tentry->mode.wrap_s, tentry->mode.wrap_t);
|
||||||
|
nonpow2tex |= 1 << i;
|
||||||
|
if (tentry->mode.wrap_s > 0) nonpow2tex |= 1 << (8 + i);
|
||||||
|
if (tentry->mode.wrap_t > 0) nonpow2tex |= 1 << (16 + i);
|
||||||
|
}
|
||||||
// if texture is power of two, set to ones (since don't need scaling)
|
// if texture is power of two, set to ones (since don't need scaling)
|
||||||
// (the above seems to have changed - we set the width and height here too.
|
// (the above seems to have changed - we set the width and height here too.
|
||||||
|
else
|
||||||
|
{
|
||||||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PixelShaderManager::SetTexturesUsed(nonpow2tex);
|
||||||
|
|
||||||
|
|
||||||
int numVertices = indexGen.GetNumVerts();
|
int numVertices = indexGen.GetNumVerts();
|
||||||
if (numVertices)
|
if (numVertices)
|
||||||
|
|
|
@ -145,7 +145,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
u32 dstAlpha = dstAlphaEnable ? 1 : 0;
|
u32 dstAlpha = dstAlphaEnable ? 1 : 0;
|
||||||
GetPixelShaderId(uid, dstAlpha);
|
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), dstAlpha);
|
||||||
|
|
||||||
PSCache::iterator iter = pshaders.find(uid);
|
PSCache::iterator iter = pshaders.find(uid);
|
||||||
|
|
||||||
|
@ -160,7 +160,8 @@ FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
|
||||||
}
|
}
|
||||||
|
|
||||||
PSCacheEntry& newentry = pshaders[uid];
|
PSCacheEntry& newentry = pshaders[uid];
|
||||||
const char *code = GeneratePixelShader(dstAlphaEnable, false);
|
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(),
|
||||||
|
dstAlphaEnable);
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_Config.iLog & CONF_SAVESHADERS && code) {
|
if (g_Config.iLog & CONF_SAVESHADERS && code) {
|
||||||
|
|
|
@ -107,6 +107,22 @@ bool TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 rang
|
||||||
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
|
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
|
||||||
{
|
{
|
||||||
mode = newmode;
|
mode = newmode;
|
||||||
|
if (isRectangle)
|
||||||
|
{
|
||||||
|
// very limited!
|
||||||
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
|
||||||
|
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
|
||||||
|
(g_Config.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
|
if (newmode.wrap_s == 2 || newmode.wrap_t == 2)
|
||||||
|
DEBUG_LOG(VIDEO, "cannot support mirrorred repeat mode");
|
||||||
|
|
||||||
|
if (newmode.wrap_s == 1 || newmode.wrap_t == 1)
|
||||||
|
DEBUG_LOG(VIDEO, "cannot support repeat mode");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||||
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
|
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
|
@ -121,6 +137,7 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
|
||||||
(g_Config.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
|
(g_Config.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
|
||||||
|
}
|
||||||
|
|
||||||
if (g_Config.iMaxAnisotropy >= 1)
|
if (g_Config.iMaxAnisotropy >= 1)
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_Config.iMaxAnisotropy));
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_Config.iMaxAnisotropy));
|
||||||
|
@ -284,8 +301,9 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash)))
|
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash)))
|
||||||
{
|
{
|
||||||
entry.frameCount = frameCount;
|
entry.frameCount = frameCount;
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
// entry.isRectangle ? TextureMngr::EnableTex2D(texstage) : TextureMngr::EnableTexRECT(texstage);
|
||||||
|
glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||||
if (entry.mode.hex != tm0.hex)
|
if (entry.mode.hex != tm0.hex)
|
||||||
entry.SetTextureParameters(tm0);
|
entry.SetTextureParameters(tm0);
|
||||||
//DebugLog("%cC addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_Config.bSafeTextureCache ? 'S' : 'U'
|
//DebugLog("%cC addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_Config.bSafeTextureCache ? 'S' : 'U'
|
||||||
|
@ -299,7 +317,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
// Might speed up movie playback very, very slightly.
|
// Might speed up movie playback very, very slightly.
|
||||||
if (width == entry.w && height == entry.h && tex_format == entry.fmt)
|
if (width == entry.w && height == entry.h && tex_format == entry.fmt)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||||
if (entry.mode.hex != tm0.hex)
|
if (entry.mode.hex != tm0.hex)
|
||||||
entry.SetTextureParameters(tm0);
|
entry.SetTextureParameters(tm0);
|
||||||
skip_texture_create = true;
|
skip_texture_create = true;
|
||||||
|
@ -352,13 +370,19 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
//DebugLog("%c addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_Config.bSafeTextureCache ? 'S' : 'U'
|
//DebugLog("%c addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_Config.bSafeTextureCache ? 'S' : 'U'
|
||||||
// , address, tex_format, entry.hash, width, height);
|
// , address, tex_format, entry.hash, width, height);
|
||||||
|
|
||||||
|
|
||||||
entry.addr = address;
|
entry.addr = address;
|
||||||
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format);
|
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format);
|
||||||
entry.isRenderTarget = false;
|
entry.isRenderTarget = false;
|
||||||
|
|
||||||
|
// For static textures, we use NPOT.
|
||||||
|
entry.isRectangle = false;
|
||||||
|
// old code: entry.isRectangle = ((width & (width - 1)) || (height & (height - 1)));
|
||||||
|
|
||||||
|
GLenum target = entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D;
|
||||||
if (!skip_texture_create) {
|
if (!skip_texture_create) {
|
||||||
glGenTextures(1, (GLuint *)&entry.texture);
|
glGenTextures(1, (GLuint *)&entry.texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(target, entry.texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dfmt != PC_TEX_FMT_DXT1)
|
if (dfmt != PC_TEX_FMT_DXT1)
|
||||||
|
@ -411,7 +435,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tm0.min_filter & 3) == 1 || (tm0.min_filter & 3) == 2)
|
if (!entry.isRectangle && ((tm0.min_filter & 3) == 1 || (tm0.min_filter & 3) == 2))
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
||||||
|
@ -420,14 +444,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
entry.bHaveMipMaps = true;
|
entry.bHaveMipMaps = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
||||||
|
|
||||||
if (expandedWidth != width) // reset
|
if (expandedWidth != width) // reset
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
glCompressedTexImage2D(target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
||||||
expandedWidth, expandedHeight, 0, expandedWidth*expandedHeight/2, temp);
|
expandedWidth, expandedHeight, 0, expandedWidth*expandedHeight/2, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +468,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
char szDir[MAX_PATH];
|
char szDir[MAX_PATH];
|
||||||
bool bCheckedDumpDir = false;
|
bool bCheckedDumpDir = false;
|
||||||
|
|
||||||
sprintf(szDir, "%s/%s", FULL_DUMP_TEXTURES_DIR,((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str());
|
sprintf(szDir,"%s/%s",FULL_DUMP_TEXTURES_DIR,((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str());
|
||||||
|
|
||||||
if(!bCheckedDumpDir)
|
if(!bCheckedDumpDir)
|
||||||
{
|
{
|
||||||
|
@ -454,10 +478,10 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
bCheckedDumpDir = true;
|
bCheckedDumpDir = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(szTemp, "%s/%s_%08x_%i.tga", szDir, ((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str(), texHash, tex_format);
|
sprintf(szTemp, "%s/%s_%08x_%i.tga",szDir, ((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str(), texHash, tex_format);
|
||||||
if (!File::Exists(szTemp))
|
if (!File::Exists(szTemp))
|
||||||
{
|
{
|
||||||
SaveTexture(szTemp, GL_TEXTURE_2D, entry.texture, expandedWidth, expandedHeight);
|
SaveTexture(szTemp, target, entry.texture, expandedWidth, expandedHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,52 +523,48 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||||
if (!bIsInit)
|
if (!bIsInit)
|
||||||
{
|
{
|
||||||
glGenTextures(1, (GLuint *)&entry.texture);
|
glGenTextures(1, (GLuint *)&entry.texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_assert_(entry.texture);
|
_assert_(entry.texture);
|
||||||
bool bReInit = true;
|
|
||||||
GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
if (entry.w == w && entry.h == h)
|
if (entry.w == w && entry.h == h && entry.isRectangle)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||||
// for some reason mario sunshine errors here...
|
// for some reason mario sunshine errors here...
|
||||||
// Beyond Good and Evil does too, occasionally.
|
// Beyond Good and Evil does too, occasionally.
|
||||||
GLenum err = GL_REPORT_ERROR();
|
GL_REPORT_ERROR();
|
||||||
if (err == GL_NO_ERROR)
|
} else {
|
||||||
bReInit = false;
|
// Delete existing texture.
|
||||||
}
|
|
||||||
|
|
||||||
if (bReInit)
|
|
||||||
{
|
|
||||||
// necessary, for some reason opengl gives errors when texture isn't deleted
|
|
||||||
glDeleteTextures(1,(GLuint *)&entry.texture);
|
glDeleteTextures(1,(GLuint *)&entry.texture);
|
||||||
glGenTextures(1, (GLuint *)&entry.texture);
|
glGenTextures(1, (GLuint *)&entry.texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!bIsInit || !entry.isRenderTarget)
|
if (!bIsInit || !entry.isRenderTarget)
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.w = w;
|
entry.w = w;
|
||||||
entry.h = h;
|
entry.h = h;
|
||||||
|
entry.isRectangle = true;
|
||||||
entry.isRenderTarget = true;
|
entry.isRenderTarget = true;
|
||||||
entry.fmt = copyfmt;
|
entry.fmt = copyfmt;
|
||||||
|
|
||||||
|
@ -602,7 +622,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||||
|
|
||||||
if (copyfmt < 2)
|
if (copyfmt < 2)
|
||||||
{
|
{
|
||||||
// ????
|
|
||||||
fConstAdd[3] = 16.0f / 255.0f;
|
fConstAdd[3] = 16.0f / 255.0f;
|
||||||
colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
|
colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
|
||||||
}
|
}
|
||||||
|
@ -675,7 +694,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||||
|
|
||||||
Renderer::SetFramebuffer(s_TempFramebuffer);
|
Renderer::SetFramebuffer(s_TempFramebuffer);
|
||||||
// Bind texture to temporary framebuffer
|
// Bind texture to temporary framebuffer
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, entry.texture, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, entry.texture, 0);
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TextureMngr
|
||||||
public:
|
public:
|
||||||
struct TCacheEntry
|
struct TCacheEntry
|
||||||
{
|
{
|
||||||
TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0), scaleX(1.0f), scaleY(1.0f), isRenderTarget(false), isUpsideDown(false), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; }
|
TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0), scaleX(1.0f), scaleY(1.0f), isRenderTarget(false), isUpsideDown(false), isRectangle(true), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; }
|
||||||
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
|
@ -48,6 +48,7 @@ public:
|
||||||
bool isRenderTarget; // if render texture, then rendertex is filled with the direct copy of the render target
|
bool isRenderTarget; // if render texture, then rendertex is filled with the direct copy of the render target
|
||||||
// later conversions would have to convert properly from rendertexfmt to texfmt
|
// later conversions would have to convert properly from rendertexfmt to texfmt
|
||||||
bool isUpsideDown;
|
bool isUpsideDown;
|
||||||
|
bool isRectangle; // if nonpow2, use GL_TEXTURE_2D, else GL_TEXTURE_RECTANGLE_NV
|
||||||
bool bHaveMipMaps;
|
bool bHaveMipMaps;
|
||||||
|
|
||||||
void SetTextureParameters(TexMode0& newmode);
|
void SetTextureParameters(TexMode0& newmode);
|
||||||
|
|
|
@ -207,6 +207,7 @@ void Flush()
|
||||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||||
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
||||||
|
|
||||||
|
u32 nonpow2tex = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i))
|
if (usedtextures & (1 << i))
|
||||||
|
@ -219,10 +220,22 @@ void Flush()
|
||||||
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format);
|
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format);
|
||||||
|
|
||||||
if (tentry != NULL)
|
if (tentry != NULL)
|
||||||
|
{
|
||||||
|
// texture loaded fine, set dims for pixel shader
|
||||||
|
if (tentry->isRectangle)
|
||||||
|
{
|
||||||
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, tentry->mode.wrap_s, tentry->mode.wrap_t);
|
||||||
|
nonpow2tex |= 1 << i;
|
||||||
|
if (tentry->mode.wrap_s > 0) nonpow2tex |= 1 << (8 + i);
|
||||||
|
if (tentry->mode.wrap_t > 0) nonpow2tex |= 1 << (16 + i);
|
||||||
|
}
|
||||||
|
// if texture is power of two, set to ones (since don't need scaling)
|
||||||
|
// (the above seems to have changed - we set the width and height here too.
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// 0s are probably for no manual wrapping needed.
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||||
|
}
|
||||||
// texture is hires - pass the scaling size
|
// texture is hires - pass the scaling size
|
||||||
if (tentry->scaleX != 1.0f || tentry->scaleY != 1.0f)
|
if (tentry->scaleX != 1.0f || tentry->scaleY != 1.0f)
|
||||||
PixelShaderManager::SetCustomTexScale(i, tentry->scaleX, tentry->scaleY);
|
PixelShaderManager::SetCustomTexScale(i, tentry->scaleX, tentry->scaleY);
|
||||||
|
@ -231,7 +244,7 @@ void Flush()
|
||||||
// save the textures
|
// save the textures
|
||||||
char strfile[255];
|
char strfile[255];
|
||||||
sprintf(strfile, "%sframes/tex%.3d_%d.tga", FULL_DUMP_DIR, g_Config.iSaveTargetId, i);
|
sprintf(strfile, "%sframes/tex%.3d_%d.tga", FULL_DUMP_DIR, g_Config.iSaveTargetId, i);
|
||||||
SaveTexture(strfile, GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h);
|
SaveTexture(strfile, tentry->isRectangle?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -239,6 +252,8 @@ void Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PixelShaderManager::SetTexturesUsed(nonpow2tex);
|
||||||
|
|
||||||
FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false);
|
FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false);
|
||||||
VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components);
|
VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue