SDEX games incorrect upscaling in HLE #936

Open
olivieryuyu opened this Issue Mar 24, 2016 · 31 comments

Comments

Projects
None yet
6 participants
@olivieryuyu

sdf

on top of being slow, there is gfx bug not related to scaling or filtering apparently

@AmbientMalice

This comment has been minimized.

Show comment
Hide comment
@AmbientMalice

AmbientMalice Mar 24, 2016

Contributor

Fixed in LLE, kinda. (Game develops different visual errors.)

Contributor

AmbientMalice commented Mar 24, 2016

Fixed in LLE, kinda. (Game develops different visual errors.)

@olivieryuyu olivieryuyu changed the title from Nintama Rantarou 64: square everywhere, even in native mode (??) to Nintama Rantarou 64: square everywhere, even in native mode (??) (HLE) Mar 24, 2016

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Mar 24, 2016

SD Hiryuu no Ken Densetsu: the same

sdfsdf

SD Hiryuu no Ken Densetsu: the same

sdfsdf

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Mar 24, 2016

Susume! Taisen Puzzle Dama Toukon! Maruma

qsds

Susume! Taisen Puzzle Dama Toukon! Maruma

qsds

@olivieryuyu olivieryuyu changed the title from Nintama Rantarou 64: square everywhere, even in native mode (??) (HLE) to SDEX games with square everywhere, even in native mode (??) (HLE) Mar 24, 2016

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Mar 24, 2016

Pro Mahjong Tsuwamono 64 same

sdfsdf

Pro Mahjong Tsuwamono 64 same

sdfsdf

@standard-two-simplex

This comment has been minimized.

Show comment
Hide comment
@standard-two-simplex

standard-two-simplex Jul 25, 2016

Contributor

I corrected sprite sizes and applied the new filtering method. Most of the issues are gone.
44a60e1

Contributor

standard-two-simplex commented Jul 25, 2016

I corrected sprite sizes and applied the new filtering method. Most of the issues are gone.
44a60e1

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Jul 25, 2016

interesting!

olivieryuyu commented Jul 25, 2016

interesting!

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Nov 18, 2016

@gonetz

Could it be the usage by the devs of the effect of gSPObjRenderMode, G_OBJRM_WIDEN?

I tried to figure out this is working in your code, no idea where it is :(

olivieryuyu commented Nov 18, 2016

@gonetz

Could it be the usage by the devs of the effect of gSPObjRenderMode, G_OBJRM_WIDEN?

I tried to figure out this is working in your code, no idea where it is :(

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Nov 18, 2016

Owner

I don ' t know about that rendermode

Owner

gonetz commented Nov 18, 2016

I don ' t know about that rendermode

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Nov 18, 2016

http://n64devkit.square7.ch/n64man/gsp/gSPObjRenderMode.htm

G_OBJRM_WIDEN
Enlarges the drawn image by 3/8 pixel (texel?) in the positive S and T directions. This mode is used to prevent blank space from opening up at the seams when a large rotating object is displayed from texture memory (TMEM) by combining sprites. This mode is effective when combining and drawing opaque sprites. It is unnecessary for translucent sprites because the seams are filled by processing by the blender (BL).

olivieryuyu commented Nov 18, 2016

http://n64devkit.square7.ch/n64man/gsp/gSPObjRenderMode.htm

G_OBJRM_WIDEN
Enlarges the drawn image by 3/8 pixel (texel?) in the positive S and T directions. This mode is used to prevent blank space from opening up at the seams when a large rotating object is displayed from texture memory (TMEM) by combining sprites. This mode is effective when combining and drawing opaque sprites. It is unnecessary for translucent sprites because the seams are filled by processing by the blender (BL).

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Nov 18, 2016

Owner

Hmm. I need to read the code. May be it is processed somewhere, but I don't remember that.

Owner

gonetz commented Nov 18, 2016

Hmm. I need to read the code. May be it is processed somewhere, but I don't remember that.

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Nov 18, 2016

as far as I can see in gSP.cpp:

if (gDP.otherMode.cycleType != G_CYC_COPY) {
if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_1) != 0) {
lrs -= 1.0f / scaleW;
lrt -= 1.0f / scaleH;
} else if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_2) != 0) {
lrs -= 1.0f;
lrt -= 1.0f;

No idea why only in copy mode only the shrink happens. Why not in another cycles?

No G_OBJRM_WIDEN

olivieryuyu commented Nov 18, 2016

as far as I can see in gSP.cpp:

if (gDP.otherMode.cycleType != G_CYC_COPY) {
if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_1) != 0) {
lrs -= 1.0f / scaleW;
lrt -= 1.0f / scaleH;
} else if ((gSP.objRendermode&G_OBJRM_SHRINKSIZE_2) != 0) {
lrs -= 1.0f;
lrt -= 1.0f;

No idea why only in copy mode only the shrink happens. Why not in another cycles?

No G_OBJRM_WIDEN

@Frank-74

This comment has been minimized.

Show comment
Hide comment
@Frank-74

Frank-74 Nov 18, 2016

Wonder is this the reason for Winback texture gaps?

GLideN64
gliden64_win_back_000

Glide64
glide64_win_back_04

Wonder is this the reason for Winback texture gaps?

GLideN64
gliden64_win_back_000

Glide64
glide64_win_back_04

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Nov 18, 2016

Owner

It is old bug iirc. An it is 3D.

Owner

gonetz commented Nov 18, 2016

It is old bug iirc. An it is 3D.

@standard-two-simplex

This comment has been minimized.

Show comment
Hide comment
@standard-two-simplex

standard-two-simplex Nov 18, 2016

Contributor

The sizes of the sprites are incorrect. I remember comparing them in HLE and LLE. That solves some of the issues, but there is still a general texture coordinate issue.

Contributor

standard-two-simplex commented Nov 18, 2016

The sizes of the sprites are incorrect. I remember comparing them in HLE and LLE. That solves some of the issues, but there is still a general texture coordinate issue.

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Nov 18, 2016

Do you know in texel the difference or the proportion compared to the sprite size between lle and hle?

Do you know in texel the difference or the proportion compared to the sprite size between lle and hle?

@standard-two-simplex

This comment has been minimized.

Show comment
Hide comment
@standard-two-simplex

standard-two-simplex Nov 18, 2016

Contributor

Do you know in texel the difference or the proportion compared to the sprite size between lle and hle?

Not sure I understand what you mean. In HLE sprites are one texel short, except in copy mode (31 vs 32 on the first screenshot). I am speaking the measures GlideN64 gives to them.

44a60e1

Look at that. I think I messed up that branch, but I got it working with that change (remove the -1) and a hacky way of handling texture coordinates. I'm trying to reproduce it on current master, but I'm having some trouble.

Contributor

standard-two-simplex commented Nov 18, 2016

Do you know in texel the difference or the proportion compared to the sprite size between lle and hle?

Not sure I understand what you mean. In HLE sprites are one texel short, except in copy mode (31 vs 32 on the first screenshot). I am speaking the measures GlideN64 gives to them.

44a60e1

Look at that. I think I messed up that branch, but I got it working with that change (remove the -1) and a hacky way of handling texture coordinates. I'm trying to reproduce it on current master, but I'm having some trouble.

@olivieryuyu olivieryuyu reopened this Nov 18, 2016

@standard-two-simplex

This comment has been minimized.

Show comment
Hide comment
@standard-two-simplex

standard-two-simplex Dec 1, 2016

Contributor

I investigated this a little bit.

The problem seems to be in sprite coordinate creation, in ObjCoordinates constructor. This is how the sprite is handled in HLE. In LLE the rsp plugin readies a texrect command, which then the graphic plugin (GlideN64 executes).

The sprite size seems incorrect currently. In LLE sprite sizes are 1 pixel larger than in HLE when not in copy mode. I can't see any real reason why to subtract 1 to lrx and lry and only add it back in copy mode. It is true that the N64 game manual recommends setting size - 1 for texrec creation commands when in copy mode, but since this primitives don't go through gDPTextureRectangle() in HLE, I can't see a reason to separate cases.

The texture coordinates, however, coincide in both LLE and HLE, but I get different results. In LLE mode, I measure them after the last addition is done in drawTextureRectangle(). If I measure it earlier, there is a small discrepancy of dsdx, dtdy, which has scaleX, scaleY counterparts for sprites. Surprisingly, I tried subtracting this value and I got a nice picture, but this makes sense as the texture coordinates at the lower right were too big for some reason. However it might not be the right value to subtract, and I see no real reason why doing it should be the correct approach.

6301e99
8942511
Here are the small changes that make this games work. I think that the first commit is correct, but I seriously doubt the second one is accurate.

@gonetz Any ideas why the same texture coordinates are giving different result? The only difference is that in LLE the primitives are rendered through drawTextureRectangle() and in HLE through drawScreenSpaceTriangle().

I checked the flags @olivieryuyu suggested and objRendermode is set to 0, so they shouldn't be used anyway.

Contributor

standard-two-simplex commented Dec 1, 2016

I investigated this a little bit.

The problem seems to be in sprite coordinate creation, in ObjCoordinates constructor. This is how the sprite is handled in HLE. In LLE the rsp plugin readies a texrect command, which then the graphic plugin (GlideN64 executes).

The sprite size seems incorrect currently. In LLE sprite sizes are 1 pixel larger than in HLE when not in copy mode. I can't see any real reason why to subtract 1 to lrx and lry and only add it back in copy mode. It is true that the N64 game manual recommends setting size - 1 for texrec creation commands when in copy mode, but since this primitives don't go through gDPTextureRectangle() in HLE, I can't see a reason to separate cases.

The texture coordinates, however, coincide in both LLE and HLE, but I get different results. In LLE mode, I measure them after the last addition is done in drawTextureRectangle(). If I measure it earlier, there is a small discrepancy of dsdx, dtdy, which has scaleX, scaleY counterparts for sprites. Surprisingly, I tried subtracting this value and I got a nice picture, but this makes sense as the texture coordinates at the lower right were too big for some reason. However it might not be the right value to subtract, and I see no real reason why doing it should be the correct approach.

6301e99
8942511
Here are the small changes that make this games work. I think that the first commit is correct, but I seriously doubt the second one is accurate.

@gonetz Any ideas why the same texture coordinates are giving different result? The only difference is that in LLE the primitives are rendered through drawTextureRectangle() and in HLE through drawScreenSpaceTriangle().

I checked the flags @olivieryuyu suggested and objRendermode is set to 0, so they shouldn't be used anyway.

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Dec 2, 2016

Owner

Any ideas why the same texture coordinates are giving different result? The only difference is that in LLE the primitives are rendered through drawTextureRectangle() and in HLE through drawScreenSpaceTriangle()

texrect command does not provide texture coordinates for all 4 vertices. lrs and lrt calculated from other texrects parameters. drawTexturedRect passes ready GL texture coordinates to vertex shader.

drawScreenSpaceTriangle works as drawTriangles : it passes vertices with N64 texture coordinate to vertex shader. Vertex shader calculates GL coordinates.

Vertex shader does the same calculations as texrect, so result should be the same for the same input.

However, there are 2 nuances:

  • texrect:
	texST[t].s0 = _params.uls * shiftScaleS - gSP.textureTile[t]->fuls;
	texST[t].s1 = (_params.lrs + _params.dsdx) * shiftScaleS - gSP.textureTile[t]->fuls;
	texST[t].t0 = _params.ult * shiftScaleT - gSP.textureTile[t]->fult;
	texST[t].t1 = (_params.lrt + _params.dtdy) * shiftScaleT - gSP.textureTile[t]->fult;

ObjCoordinates does not add dsdx and dtdy.

edit: it should not matter, because in gDPTextureRectangle

	lrs = s + (lrx - ulx - 1) * dsdx;
	lrt = t + (lry - uly - 1) * dtdy;

thus
s + (lrx - ulx - 1) * dsdx + dsdx == s + (lrx - ulx ) * dsdx

  • texrect has hacks, which may force texture clamp. drawScreenSpaceTriangle has not. It also may change result.
Owner

gonetz commented Dec 2, 2016

Any ideas why the same texture coordinates are giving different result? The only difference is that in LLE the primitives are rendered through drawTextureRectangle() and in HLE through drawScreenSpaceTriangle()

texrect command does not provide texture coordinates for all 4 vertices. lrs and lrt calculated from other texrects parameters. drawTexturedRect passes ready GL texture coordinates to vertex shader.

drawScreenSpaceTriangle works as drawTriangles : it passes vertices with N64 texture coordinate to vertex shader. Vertex shader calculates GL coordinates.

Vertex shader does the same calculations as texrect, so result should be the same for the same input.

However, there are 2 nuances:

  • texrect:
	texST[t].s0 = _params.uls * shiftScaleS - gSP.textureTile[t]->fuls;
	texST[t].s1 = (_params.lrs + _params.dsdx) * shiftScaleS - gSP.textureTile[t]->fuls;
	texST[t].t0 = _params.ult * shiftScaleT - gSP.textureTile[t]->fult;
	texST[t].t1 = (_params.lrt + _params.dtdy) * shiftScaleT - gSP.textureTile[t]->fult;

ObjCoordinates does not add dsdx and dtdy.

edit: it should not matter, because in gDPTextureRectangle

	lrs = s + (lrx - ulx - 1) * dsdx;
	lrt = t + (lry - uly - 1) * dtdy;

thus
s + (lrx - ulx - 1) * dsdx + dsdx == s + (lrx - ulx ) * dsdx

  • texrect has hacks, which may force texture clamp. drawScreenSpaceTriangle has not. It also may change result.
@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Dec 2, 2016

those games uses gSPBgRect1Cyc?

those games uses gSPBgRect1Cyc?

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Dec 2, 2016

Owner

SD Hiryuu no Ken Densetsu does.

Owner

gonetz commented Dec 2, 2016

SD Hiryuu no Ken Densetsu does.

@LegendOfDragoon

This comment has been minimized.

Show comment
Hide comment
@LegendOfDragoon

LegendOfDragoon Dec 19, 2016

@olivieryuyu by any chance, do you have a demo with source code for S2DEX?

@olivieryuyu by any chance, do you have a demo with source code for S2DEX?

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment

olivieryuyu commented Dec 19, 2016

spriteex.zip

here you go

@LegendOfDragoon

This comment has been minimized.

Show comment
Hide comment
@LegendOfDragoon

LegendOfDragoon Dec 19, 2016

thanks a lot @olivieryuyu! Imo, fixing S2DEX is important 😄 .

thanks a lot @olivieryuyu! Imo, fixing S2DEX is important 😄 .

@LegendOfDragoon

This comment has been minimized.

Show comment
Hide comment
@LegendOfDragoon

LegendOfDragoon Dec 20, 2016

while searching for data on certain macros, I came across this https://github.com/shlomnissan/ultra64demos/tree/master/gs2dex . Do you kno where I can get the ROM for this? I'm collecting demos so that I can learn more about HLE gfx 😄 .

while searching for data on certain macros, I came across this https://github.com/shlomnissan/ultra64demos/tree/master/gs2dex . Do you kno where I can get the ROM for this? I'm collecting demos so that I can learn more about HLE gfx 😄 .

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment

nope

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Jun 30, 2017

it seems that Culture Brain does not use the normal S2DEX ucode. Need further checks but it looks so.

Amazing ...

it seems that Culture Brain does not use the normal S2DEX ucode. Need further checks but it looks so.

Amazing ...

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Sep 1, 2017

I was incorrect, Culture Brain used the normal ucode SDEX ucode.

I was incorrect, Culture Brain used the normal ucode SDEX ucode.

standard-two-simplex added a commit to standard-two-simplex/GLideN64 that referenced this issue Sep 27, 2017

gonetz added a commit that referenced this issue Sep 28, 2017

@gonetz gonetz closed this in feb0e53 Oct 4, 2017

@gonetz gonetz reopened this Jan 7, 2018

@gonetz

This comment has been minimized.

Show comment
Hide comment
@gonetz

gonetz Jan 7, 2018

Owner

Reopen since the fix is reverted.

Owner

gonetz commented Jan 7, 2018

Reopen since the fix is reverted.

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Jun 19, 2018

@gonetz

I started to investigate the issue but it seems the bugs has been reduced (without being totally fixed).

image

What changed this?

@gonetz

I started to investigate the issue but it seems the bugs has been reduced (without being totally fixed).

image

What changed this?

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Jul 20, 2018

the issue is not at microcode level, the issue is about upscaling!!!!

See how it looks like in HLE in 0x320*0x240

320

It is perfect!!!

in other resolutions:

640

the native option does not prevent this issue.

It used to be wrong even at 0x320*0x240 (square everywhere) but it is not anymore the case.

olivieryuyu commented Jul 20, 2018

the issue is not at microcode level, the issue is about upscaling!!!!

See how it looks like in HLE in 0x320*0x240

320

It is perfect!!!

in other resolutions:

640

the native option does not prevent this issue.

It used to be wrong even at 0x320*0x240 (square everywhere) but it is not anymore the case.

@olivieryuyu

This comment has been minimized.

Show comment
Hide comment
@olivieryuyu

olivieryuyu Jul 20, 2018

it used to be correct with the version of the 5 November in any resolution!

i guess the new issue started as from this commit:

737338c

correct

olivieryuyu commented Jul 20, 2018

it used to be correct with the version of the 5 November in any resolution!

i guess the new issue started as from this commit:

737338c

correct

@olivieryuyu olivieryuyu changed the title from SDEX games with square everywhere, even in native mode (??) (HLE) to SDEX games incorrect upscaling in HLE Jul 20, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment