Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Banjo Tooie crashes when using hirestextures #1711

Open
Tenolius opened this issue Jan 29, 2018 · 16 comments
Open

Banjo Tooie crashes when using hirestextures #1711

Tenolius opened this issue Jan 29, 2018 · 16 comments

Comments

@Tenolius
Copy link

Hi. I am having this issue using the latest public GlideN64 3.0 release. The textures are loaded correctly right before the game starts, but the game crashes after the first 5-10 seconds (as soon as the Rareware logo appears), displaying the following screen:
project64_issue01
This is what the Project64.log indicates:
2018/01/29 10:14:17.040 22524,Error,Exception Handler,CMipsMemoryVM::FilterX86Exception,Invalid memory adderess: FFFFFFFC
2018/01/29 10:14:17.040 22524,Error,RSP,CN64System::RunRSP,exception generated
2018/01/29 10:14:17.040 22524,Error,User Interface,CNotificationImp::FatalError,CN64System::RunRSP()
Unknown memory action

Emulation stop

I tried using GlideN64 3.0 on both Project 64 2.3.2 and a Patreon build, and in both cases, the same issue occured. Moreover, this issue does not happen when using GlideN64 2.0. I already deleted the texture cache multiple times on the respective folder to build a new one, but still crashes. Any ideas what could be wrong? Thanks in advance

@fzurita
Copy link
Contributor

fzurita commented Jan 30, 2018

It sounds like a bug, it shouldn't really be crashing.

@Tenolius
Copy link
Author

As a side note. The gliden64.log file saved the following log last time it crashed: "Stream error while loading shader cache! Buffer is probably not big enough"

@ghost
Copy link

ghost commented Feb 21, 2018

I would also like to report the same issue. Using latest WIP build with PJ64 and 1964. Both crash at the exact same spot in the game (bringing up pause menu). If I disable the texture pack then it doesn't crash.

Project64.log:

2018/02/21 08:08:02.849 03516,Error,Exception Handler,CMipsMemoryVM::FilterX86Exception,Invalid memory adderess: FFFFFFFE
2018/02/21 08:08:02.849 03516,Error,RSP,CN64System::RunRSP,exception generated
2018/02/21 08:08:02.849 03516,Error,User Interface,CNotificationImp::FatalError,CN64System::RunRSP()
Unknown memory action

Emulation stop

crash

@Mushman
Copy link
Contributor

Mushman commented Mar 1, 2018

I initially reported this behaviour for Goldeneye 007 on Project 64 in #463. Interesting to see it occurs in other games too.

@gonetz
Copy link
Owner

gonetz commented Mar 10, 2018

Please give me link to the hires pack.

@Tenolius
Copy link
Author

@Mushman
Copy link
Contributor

Mushman commented Mar 11, 2018

In Goldeneye, you don't need to actually be using a texture pack. You just need to have enabled Texture dumping/editing mode.

@ghost
Copy link

ghost commented Mar 31, 2019

This still happens in the current master and my own compile - both debug and release. I am using zilmar spec DLL. Happened with 1964 and PJ64. Included is a log output up until the moment I bring up the watch. This includes all DebugMsg() logs too.

gliden64.log.zip

@carnivoroussociety
Copy link

carnivoroussociety commented Oct 18, 2019

I investigated this issue for GoldenEye 007 and logged every command. GlideN64 crashes while executing _ProcessDList() with the following error
First-chance exception at 0x536BDBD2 (GLideN64.dll) in 1964.exe: 0xC0000005: Access violation reading location 0x1FFFFFF

The failing commands are

RSP.cmd: 0xB1 (F3D_TRIX)
RSP.w0: 0xB1000BCD
RSP.w1: 0x00CEFECB
RSP.cmd: 0xBF (F3D_TRI1)
RSP.w0: 0xBF000000
RSP.w1: 0x008C8296

This is fine until it reaches this line of code in TextureCache::_loadHiresTexture()
_ricecrc = txfilter_checksum(addr, width, height, (unsigned short)(_pTexture->format << 8 | _pTexture->size), bpl, paladdr);
These are the arguments when it fails

addr 0x20000000
width 0x00000004
height 0x00000004
size 0x00000200
rowStride 0x00000008
palette 0x53E9E490

As 1964's base address is 0x20000000, this means info.texAddress is set to 0. As a hack I added the following code to _loadHiresTexture()

bool TextureCache::_loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 & _ricecrc)
{
	if (config.textureFilter.txHiresEnable == 0 || !TFH.isInited())
		return false;

	gDPLoadTileInfo & info = gDP.loadInfo[_pTexture->tMem];
	if (info.texAddress == 0)
		return false;

This appears to have fixed the issue.

@DonelBueno
Copy link

DonelBueno commented Oct 24, 2019

@carnivoroussociety Very nice discovery =)

It's probably the same for Perfect Dark.

@fzurita
Copy link
Contributor

fzurita commented Oct 24, 2019

@gonetz you should probably implement this fix.

@gonetz
Copy link
Owner

gonetz commented Oct 24, 2019

you should probably implement this fix.

Yes, I planned to check that, but forgot due to other tasks. However,

if (info.texAddress == 0)
		return false;

is not a fix, it is a hack, as carnivoroussociety said. I need to find why info.texAddress is zero to fix it properly.

@gonetz
Copy link
Owner

gonetz commented Oct 26, 2019

I investigated the problem with GE pause menu.
The problem is not simple and I uncertain how it should be fixed.

GE crashes when it tries to load mip-mapped textures.

N64 mip-mapping is a serious technical problem for hardware graphics plugins. GLideN64 solved it for original N64 textures. However, Rice format for hi-res textures has a design flaw regarding mip-mapping. Its texture checksum calculation method loads texture data from RDRAM, not from TMEM. It was done for speed, since full TMEM emulation requires some CPU resources. Thus, we need to know the address in RDRAM, from which texture was loaded to calculate texture CRC and find hi-res texture for it. "info.texAddress" is that address. As you may see, each address in TMEM has corresponding gDPLoadTileInfo, so when texture is loaded with LOAD_TILE or LOAD_BLOCK to some TMEM address, texture loading procedure fills gDPLoadTileInfo structure for that address. So, why info.texAddress is zero?

It is because N64 hardware usually loads all tiles of a mip-mapped texture with one LOAD_BLOCK command. It looks as this:

  • Tile 7 TMEM address set to 0. It is not zero, it is TMEM + 0.
  • LOAD_BLOCK uses Tile 7 to load texture data from some TEX_ADDRESS in RDRAM into TMEM, starting from Tile 7 TMEM address, that is from the beginning of TMEM. LOAD_BLOCK also sets texAddress for gDPLoadTileInfo structure to TEX_ADDRESS. That is, only one texture loading command was called and only one gDPLoadTileInfo structure was initialized.
  • After that, the game initializes tiles from 0 to 6. These tiles correspond to tiles of the mip-mapped texture, which just have been loaded. The first tile has size 32x32, the second one 16x16 and so on.

Each tile has an address in TMEM, but since no load command was executed for that address, corresponding gDPLoadTileInfo structure was not initialized. It is not a problem for GLideN64 texture checksum calculation, since it loads data from TMEM. However, for Rice format it is a problem.

I tried to dump textures for GE with Rice Video graphics plugin. It seems, that it can dump only first two tiles of mip-mapped textures. It probably is not a big problem for Rice Video since it can't do proper mip-mapping anyway. But actually it is a problem and probably a serious one. In fact, we can't create proper hi-res replacements for mip-mapped textures with Rice format. @Nerrel advises not to use mip-mapping at all because mip-mapping makes textures less detailed. However, it is the point of mip-mapping - objects on a distance must look less detailed, otherwise you loose sense of distance. Rare uses mip-mapping a lot in their games since it helps games to look more realistic.

Back to the problem: I can use carnivoroussociety's hack as a temporal workaround to avoid crashes. The problem with hi-res map-mapping in general requires more serious efforts to solve. May be new revision of Rice format will be necessary. However, it will be possible only if there will be texture artists really interested in creation of true hi-res mip-mapped textures.

gonetz added a commit that referenced this issue Oct 26, 2019
…en mip-mapped textures loaded.

See #1711 for details.
@oddMLan
Copy link
Contributor

oddMLan commented Oct 26, 2019

Aren't mipmapped textures just lower resolution versions of big textures? I don't know if this is the case for the N64, but some PS2 games use mipmapping cleverly to make gradients (modifying the luminance values of the main texture which each subsequent mipmap), in which case, the answer would be no. But if they're simply lower res versions of main textures, you could get the hires version of the main texture associated with the low res version, detect the respective mipmaps from the low res version, then procedurally generate a mipmapped version of the hires textures that replaces these mipmaps. Does it make sense?

@gonetz
Copy link
Owner

gonetz commented Oct 28, 2019

Aren't mipmapped textures just lower resolution versions of big textures?

Yes and no. Mipmapped texture consists of tiles, and starting from the second one each tile is a lower resolution versions of the previous one:
https://en.wikipedia.org/wiki/Mipmap

N64 mip-mapping has peculiarities. In particular, it may use detailed texture. Detailed texture is a special texture, which usually has different pattern. This detailed pattern is blended with the main pattern when object is near, so it looks more detailed. When object is far, only main pattern is seen.
When detailed texture is not used, N64 mip-mapping works as a standard one.

procedurally generate a mipmapped version of the hires textures that replaces these mipmaps.

I'm not sure that tiles in map-mapped texture are just lower resolution versions of the first tile. I suppose that in some cases it is not so, and texture artists could specially modify low-res tiles to decide which details to remove. It needs to be investigated. I agree that in general case plugin can generate mip-mapping tiles using the first most detailed one, or the second one in case of detailed textures. It can help to reduce moire, which is often noticeable when very high-res textures are used.

@gonetz
Copy link
Owner

gonetz commented Apr 21, 2024

Mip Map support for High resolution texture packs. #2818, #2826

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants