Skip to content

Assorted PS3 texture export/conversion fixes - #17

Open
hydnhntr wants to merge 4 commits into
Nenkai:masterfrom
hydnhntr:feature/txs3-ps3-export
Open

Assorted PS3 texture export/conversion fixes#17
hydnhntr wants to merge 4 commits into
Nenkai:masterfrom
hydnhntr:feature/txs3-ps3-export

Conversation

@hydnhntr

@hydnhntr hydnhntr commented Sep 28, 2025

Copy link
Copy Markdown

I finally found the time to wrap this and some other issues that cropped up along the way.

Reversed channels

In the ‘Swap channels for DDS’ block, each pixel’s bytes were first reversed ([A, R, G, B][B, G, R, A]), before the individual channels were extracted using the InR/InG/InB/InA remap offsets. The remapping offsets describe the pixel’s original, un-reversed byte layout, so applying them after the reversal incorrectly read each channel.

BCED00393/projects/gt5p/arcade/JP/image/gt5p/common/hot.dds
Before a8r8g8b8_hot_68x72
After a8r8g8b8_hot_68x72

Linear row pitch

Uncompressed linear layout textures can have their rows padded to a hardware aligned pitch (assuming 1024 bytes), wider than the actual texture, eg

GTHD_Logo_H.dds (420×120) has a pitch of 2048 bytes per row, but only 1680 bytes of actual pixel data.

NPUA80019/project-ps3/image/gthd/GTHD_Logo_H.dds
Before a8r8g8b8_gthd_logo_h_420x120
After a8r8g8b8_gthd_logo_h_420x120

DDS mip-count

Previosuly when extracting BCED00393/character/ma__0051 (5 textures, each with up to 10 mips) it’d fault with Offset and length were out of bounds....

Now all 5 textures convert but only the base level (0), as mip export isn’t a feature.

multitex_ma__0051_mips_tex0

Does this need to be flipped vertically?

BufferId reference

PGLUCellTextureInfo.Read() never sets BufferId (unlike the PS4/PSP readers) and stays as 0. TextureSet3 resolved each texture’s buffer via Buffers[(int)textureInfo.BufferId], so with a multi-buffer container any texture after the first would still read the first (0) and fault.

BCED00393/crs/race.txs (6 textures) used to throw (Specified argument was out of the range of valid values.).

multitex_race_d8r8g8b8_tex1

Is this supposed to be noise?

Testing

I picked samples from GTHD and GT5P which have a combo of features to validate these changes against.

2D

Index Format Layout Dimensions Mips Pitch bytes Row bytes
NPUA80019/project-ps3/image/component/dialog_head2.png
A8R8G8B8Linear2×20188
NPUA80019/project-ps3/image/component/numberinput_up.png
A8R8G8B8Linear11×816444
NPUA80019/project-ps3/image/arcade/common/popup_item_button.png
A8R8G8B8Linear155×2411024620
BCED00393/projects/gt5p/race/GB/image/race_display/ps3/GT4_meter_texture_point.png
A8R8G8B8Linear9×916436
BCED00393/projects/component/image/component/scr2_2.png
Smallest dimensions (12px square)
A8R8G8B8Linear6×213224
NPUA80019/project-ps3/image/gthd/GTHD_Logo_H.dds
Channel and pitch bugs
A8R8G8B8Linear420×120120481680
BCED00393/projects/gt5p/arcade/JP/image/gt5p/common/hot.dds
Channel bug
A8R8G8B8Linear68×721272272
NPUA80019/project-ps3/image/guide/notice/JP/notice_0_480.dds
DXT1Linear640×4801
NPUA80019/project-ps3/image/option/white.dds
DXT1Swizzled4×41
NPUA80019/project-ps3/image/component/ps3/btn_sys1_1.dds
DXT3Linear32×561
NPUA80019/project-ps3/image/gthd/manual/HD_Ctl_Menu.dds
DXT3Linear1648×7481
NPUA80019/project-ps3/image/component/ps3/dot.dds
DXT5Linear12×121
NPUA80019/project-ps3/image/quick/line_dot_q.dds
DXT5Linear4×1001
NPUA80019/project-ps3/image/gthd/icon_ranking.dds
DXT5Linear116×881
NPUA80019/project-ps3/image/gthd/panel_nomal.dds
DXT5Linear336×3361
NPUA80019/project-ps3/image/guide/direction/JP/direction_07_1080.dds
DXT5Linear1648×7481
BCED00393/character/ma__0051
Mip-chain example
0A8R8G8B8Swizzled256×2569
1DXT5Swizzled256×2569
2DXT5Swizzled128×2569
3DXT5Swizzled512×51210
4DXT5Swizzled256×2569
BCED00393/crs/race.txs
Only D8R8G8B8 example (textures 1–3)
0A8R8G8B8Swizzled128×641
1D8R8G8B8Swizzled128×1281
2D8R8G8B8Swizzled256×2561
3D8R8G8B8Swizzled64×641
4A8R8G8B8Swizzled128×1281
5A8R8G8B8Swizzled128×1281

Cubemap

Format Layout Dimensions Mips
BCED00393/scene/texset/tx0001
A8R8G8B8Swizzled128×1281
NPUA80019/projects-ps3/trial/US/image/gthd/colorchipenv.dds
Cubemap with mip levels and exhibited the DDS mip-count bug
A8R8G8B8Swizzled128×1288

@hydnhntr
hydnhntr marked this pull request as draft September 28, 2025 04:53
@hydnhntr
hydnhntr marked this pull request as ready for review September 28, 2025 06:29
@Nenkai

Nenkai commented Sep 28, 2025

Copy link
Copy Markdown
Owner

I don't completely remember why I added endian swap in the first place, but it must've been a good reason

Namely I believed that the pixel components in the pixel buffers are in big-endian according to PPC in the first place, regardless of remap

If you can, I would make sure that it works correctly across the majority of textures, namely i'd check GTHD, GT5P/5 and track textures

@hydnhntr

hydnhntr commented Nov 2, 2025

Copy link
Copy Markdown
Author

Edit: outdated, see PR body for latest changes.


Small update after looking at GTHD Concept’s UI textures:

Format Output Asset
DXT45 cursor_chrome_DXT45 NPUA80019/project-ps3/image/component/ps3/cursor_chrome.dds
A8R8G8B8 cursor_chrome NPUA80019/project-ps3/image/cursor/cursor_chrome.dds

cursors.zip


Screenshot 2025-11-02 at 8 08 34 PM

The uncompressed A8R8G8B8 version is currently ignoring the pitch, and includes the padding in the output.

I’m unsure how to handle this, whether to rejig the data inside CreateDDSData() or whether Pfimage can be passed a stride.

var i = Image.LoadPixelData<Bgra32>(dds.Data, (int)Utils.MiscUtils.AlignValue((uint)dds.Width, 4), dds.Height);

I also needed to remove the manual alignment above, as it was resulting in a mismatch in the expected length of data.

@hydnhntr hydnhntr changed the title Fix CELL_GCM_TEXTURE_A8R8G8B8 outputs’ reversed channels Assorted PS3 texture export/conversion fixes Sep 6, 2026
@hydnhntr

hydnhntr commented Sep 6, 2026

Copy link
Copy Markdown
Author

@Nenkai 11 months later and finally some updates ready for review

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

Successfully merging this pull request may close these issues.

2 participants