Skip to content

Commit

Permalink
Flip texcoord vertically when texturing from FBO to compensate for Op…
Browse files Browse the repository at this point in the history
…enGL coordinate systems
  • Loading branch information
hrydgard committed Feb 14, 2013
1 parent de626e3 commit 2301a3b
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 12 deletions.
15 changes: 10 additions & 5 deletions GPU/GLES/DisplayListInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,22 +542,26 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
break;

case GE_CMD_TEXTUREMAPENABLE:
gstate_c.textureChanged = true;
if (diff)
gstate_c.textureChanged = true;
break;

case GE_CMD_LIGHTINGENABLE:
break;

case GE_CMD_FOGCOLOR:
shaderManager_->DirtyUniform(DIRTY_FOGCOLOR);
if (diff)
shaderManager_->DirtyUniform(DIRTY_FOGCOLOR);
break;

case GE_CMD_FOG1:
shaderManager_->DirtyUniform(DIRTY_FOGCOEF);
if (diff)
shaderManager_->DirtyUniform(DIRTY_FOGCOEF);
break;

case GE_CMD_FOG2:
shaderManager_->DirtyUniform(DIRTY_FOGCOEF);
if (diff)
shaderManager_->DirtyUniform(DIRTY_FOGCOEF);
break;

case GE_CMD_FOGENABLE:
Expand Down Expand Up @@ -618,6 +622,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_TEXADDR6:
case GE_CMD_TEXADDR7:
gstate_c.textureChanged = true;
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;

case GE_CMD_TEXBUFWIDTH0:
Expand Down Expand Up @@ -667,7 +672,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {

case GE_CMD_TEXSIZE0:
gstate_c.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
gstate_c.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
gstate_c.curTextureHeight = 1 << ((gstate.texsize[0] >> 8) & 0xf);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
//fall thru - ignoring the mipmap sizes for now
case GE_CMD_TEXSIZE1:
Expand Down
5 changes: 4 additions & 1 deletion GPU/GLES/ShaderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs)
glUniform1i(u_tex, 0);
// The rest, use the "dirty" mechanism.
dirtyUniforms = DIRTY_ALL;
use();
}

LinkedShader::~LinkedShader() {
Expand Down Expand Up @@ -264,8 +265,10 @@ void LinkedShader::updateUniforms() {

// Texturing
if (u_uvscaleoffset != -1 && (dirtyUniforms & DIRTY_UVSCALEOFFSET)) {
float uvscaleoff[4] = { gstate_c.uScale, gstate_c.vScale, gstate_c.uOff, gstate_c.vOff};
float uvscaleoff[4] = {gstate_c.uScale, gstate_c.vScale, gstate_c.uOff, gstate_c.vOff};
if (gstate.isModeThrough()) {
// We never get here because we don't use HW transform with through mode.
// Although - why don't we?
uvscaleoff[0] /= gstate_c.curTextureWidth;
uvscaleoff[1] /= gstate_c.curTextureHeight;
uvscaleoff[2] /= gstate_c.curTextureWidth;
Expand Down
29 changes: 23 additions & 6 deletions GPU/GLES/TextureCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@
#include "TextureCache.h"
#include "../Core/Config.h"

// If a texture hasn't been seen for 200 frames, get rid of it.
// If a texture hasn't been seen for this many frames, get rid of it.
#define TEXTURE_KILL_AGE 200
float maxAnisotropyLevel ;

u32 RoundUpToPowerOf2(u32 v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}

TextureCache::TextureCache() {
lastBoundTexture = -1;
Expand Down Expand Up @@ -681,22 +692,28 @@ void TextureCache::SetTexture() {

TexCache::iterator iter = cache.find(cachekey);
TexCacheEntry *entry = NULL;
gstate_c.flipTexture = false;

if (iter != cache.end()) {
entry = &iter->second;
// Check for FBO - slow!
if (entry->fbo) {
int w = 1 << (gstate.texsize[0] & 0xf);
int h = 1 << ((gstate.texsize[0] >> 8) & 0xf);

fbo_bind_color_as_texture(entry->fbo, 0);
UpdateSamplingParams(*entry, false);

int fbow, fboh;
fbo_get_dimensions(entry->fbo, &fbow, &fboh);

// Almost certain this isn't right.
gstate_c.curTextureWidth = fbow;
gstate_c.curTextureHeight = fboh;
// This isn't right.
gstate_c.curTextureWidth = w; //w; //RoundUpToPowerOf2(fbow);
gstate_c.curTextureHeight = h; // RoundUpToPowerOf2(fboh);
gstate_c.flipTexture = true;
entry->lastFrame = gpuStats.numFrames;
return;
}

//Validate the texture here (width, height etc)

int dim = gstate.texsize[0] & 0xF0F;
Expand Down
1 change: 1 addition & 0 deletions GPU/GLES/TextureCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,6 @@ class TextureCache
u16 *clutBuf16;

int lastBoundTexture;
float maxAnisotropyLevel;
};

2 changes: 2 additions & 0 deletions GPU/GLES/TransformPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
memcpy(&transformed[index].x, v, 3 * sizeof(float));
transformed[index].fog = fogCoef;
memcpy(&transformed[index].u, uv, 2 * sizeof(float));
if (gstate_c.flipTexture)
transformed[index].v = 1.0f - transformed[index].v * 2.0f;
for (int i = 0; i < 4; i++) {
transformed[index].color0[i] = c0[i] * 255.0f;
}
Expand Down
6 changes: 6 additions & 0 deletions GPU/GLES/VertexShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ void ComputeVertexShaderID(VertexShaderID *id, int prim)
id->d[0] |= ((int)enableFog) << 2;
id->d[0] |= doTexture << 3;
id->d[0] |= (hasColor & 1) << 4;
if (doTexture)
id->d[0] |= (gstate_c.flipTexture & 1) << 5;

if (CanUseHardwareTransform(prim)) {
id->d[0] |= 1 << 8;
id->d[0] |= (hasNormal & 1) << 9;
Expand Down Expand Up @@ -139,6 +142,7 @@ void GenerateVertexShader(int prim, char *buffer) {
bool hasColor = (gstate.vertType & GE_VTYPE_COL_MASK) != 0 || !hwXForm;
bool hasNormal = (gstate.vertType & GE_VTYPE_NRM_MASK) != 0 && hwXForm;
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
bool flipV = gstate_c.flipTexture;

DoLightComputation doLight[4] = {LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF};
if (hwXForm) {
Expand Down Expand Up @@ -396,6 +400,8 @@ void GenerateVertexShader(int prim, char *buffer) {
// ILLEGAL
break;
}
if (flipV)
WRITE(p, " v_texcoord.y = 1.0f - v_texcoord.y;\n");
}

// Compute fogdepth
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPUState.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ struct GPUStateCache

float uScale,vScale;
float uOff,vOff;
bool flipTexture;

float zMin, zMax;
float lightpos[4][3];
float lightdir[4][3];
Expand Down

11 comments on commit 2301a3b

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few issues in HW mode since this commit.

  1. HW mode crashs when start FF type-0 , SW mode is okay
  2. Render to texture effect disappears for HW mode .
  3. Some games missing textures in HW mode

3

@hrydgard
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for testing. A crash is a little surprising, but this is the kind of fix that will break many things that have "worked accidentally" until now...

I still can't figure out a good way to estimate the correct size for the FBO:s we create...

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is first time i seen crash with either HW/SW T&L .I will do more testing when i back home tonight .

However , inverted and oversized FBO issue indeed fixed :)

@Carter07
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bottom part of screen in games that were inverted is not displayed correctly:
Tested Harvest Moon and Dragoneers Aria.

2013-02-15 13 22 53 v0 6-474

@hrydgard
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, I know. Also the screen is slightly cut off on the rightside.

It looks like it's rendering to 512x256 rather than 480x272?

@Carter07
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, it may be 512x256, however the total number of pixel displayed seems the same.
Here a comparison between jpcsp and ppsspp.

jpcsp
ppsspp

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Humm the w and h return both 512 for this game .

59:28:508 GLES\TextureCache.cpp:713 N[G3D]: w=512, h=512

        int w = 1 << (gstate.texsize[0] & 0xf);
        int h = 1 << ((gstate.texsize[0] >> 8) & 0xf);

        gstate_c.curTextureWidth = w; //w;  //RoundUpToPowerOf2(fbow);
        gstate_c.curTextureHeight = h;  // RoundUpToPowerOf2(fboh);
        NOTICE_LOG(G3D,"w=%i, h=%i",w,h);

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to set the width and height to fixed value which is 480 and 272 respectively and with transformed[index].v = 1.0f - transformed[index].v , then render correct .

        gstate_c.curTextureWidth = 480; //w;  //RoundUpToPowerOf2(fbow);
        gstate_c.curTextureHeight = 272;  // RoundUpToPowerOf2(fboh);

1

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the above changes ( i'm sure not 100% correct ) , fix Super Robot Taisen MX , RR2 and Dissidia Final Fantasy

1

2

@hrydgard
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding 480 and 272 will probably work for many games but isn't really "correct". I have another idea which should have the same results, stay tuned.

@dbz400
Copy link
Contributor

@dbz400 dbz400 commented on 2301a3b Feb 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep , like the bloom effect of FF type-0 will be incorrect . Looking forward to your implementation

Please sign in to comment.