Project

General

Profile

Actions

Emulator Issues #13733

open

[Graphical emulation issue] CI texture TLUT address calculation is wrong

Added by Evoca about 2 months ago. Updated about 1 month ago.

Status:
Accepted
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

Game Name/ID?

Any game

What's the problem? Describe what went wrong.

Current implementation does something like the following (obviously not accurate):

tmem_addr = ( tmem_offset + tex_ci ) & tmem_bank_size_mask;
pixel_color = TMEMGetTlutValue(tmem_addr);

where tmem_offset is the offset of the TLUT begining in high bank TMEM and tex_ci is the current pixel index value of the texture.

As per my testing, the address of a TLUT value should be calculated by using an OR operation:

tmem_addr = ( tmem_offset | tex_ci ) & tmem_bank_size_mask;

Meaning that in real hardware there is no wrapping around high bank TMEM.

Is the issue present in the latest development version?

Yes, Issue occurring as of rev 2412-225

Is the issue present in the latest release?

Yes, as of rev 2409.0


Files

tlut_test.png (207 KB) tlut_test.png How it shows in hardware Evoca, 02/03/2025 08:47 PM
tlut_test.dff (1.61 MB) tlut_test.dff Fifo recording Evoca, 02/03/2025 08:47 PM
tlut_test_hardware_fifoplayer.png (54 KB) tlut_test_hardware_fifoplayer.png flacs, 02/11/2025 04:21 PM
Actions #1

Updated by flacs about 2 months ago

Actions #2

Updated by pokechu22 about 1 month ago

I looked at Dolphin's TMEM emulation about a week ago when this was first posted, and I didn't see anything that looked like we implement masking with tmem_bank_size_mask currently either. (I might have just missed it though.)

Actions #3

Updated by Evoca about 1 month ago

pokechu22 wrote in #note-2:

I looked at Dolphin's TMEM emulation about a week ago when this was first posted, and I didn't see anything that looked like we implement masking with tmem_bank_size_mask currently either. (I might have just missed it though.)

Sorry for the inconvenience, I was not really clear with the issue :,)

I used pseudo-code but the functionality is basically the same, for example the DecodeBytes_C8() function (https://github.com/dolphin-emu/dolphin/blob/c770e7c2766155799095d1a1df19f898a2db7bc5/Source/Core/VideoCommon/TextureDecoder_Generic.cpp#L85) receives a pointer to the tlut starting at tlutaddr (see https://github.com/dolphin-emu/dolphin/blob/c770e7c2766155799095d1a1df19f898a2db7bc5/Source/Core/VideoCommon/TextureInfo.cpp#L33C1-L33C68) and it has access to all the 256 TLUT values starting from there.

In real hardware the tlutaddr and the index value (val in DecodeBytes_C8()) are ORed together (meaning set bits from tlutaddr make certain TLUT values unreachable). As for real modifications (at least from what I see in the code above), the whole high tmem should be passed and val should be ORed with tlutaddr before accessing the tlut.

Actions

Also available in: Atom PDF