Skip to content

Improve Tex1 size optimization#21

Open
Silentwarior112 wants to merge 2 commits into
Nenkai:masterfrom
Silentwarior112:master
Open

Improve Tex1 size optimization#21
Silentwarior112 wants to merge 2 commits into
Nenkai:masterfrom
Silentwarior112:master

Conversation

@Silentwarior112
Copy link
Copy Markdown

Changes are in TextureSetBuilder and TextureSetPS2Base
As far as I can tell there isn't any visual change to models with this optimization in place.

Outputted Tex1 sizes went from ~50% over original size to only about ~8% over
(Seen on ho0030's menu model, dumped vs rebuilt)

TextureSetBuilder was using a standard dictionary for tracking unused GS memory blocks,
switched to a SortedDictionary to evaluate GS memory addresses sequentially

Identical texture/palette data was being written multiple times into the file.
Avoided duplication of pixel buffers by checking the hash of PackedImageData

The swizzler was calculating file boundaries based on dictionary entry counts rather than the physical highest used TBP.
Added calculation that scans the final TBP and CBP values to better determine the boundary

Updates to PSMCT16 stuff for fixing it later on

Copy link
Copy Markdown
Owner

@Nenkai Nenkai left a comment

Choose a reason for hiding this comment

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

What does the comments even mean in the code?

WriteClutPatches();

// Debug statements... HIGH WATER MARK (Max Block) is usually a lot higher than the last CSA, this may be a clue to further size optimization
Console.WriteLine("--- VRAM ALLOCATION MAP ---");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

?

Comment on lines +248 to +249
Console.WriteLine($"HIGH WATER MARK (Max Block): {_usedGsBlocksIndices.Max(e => e)}");
Console.WriteLine("---------------------------");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

?

if (endBlock > maxPaletteBlock) maxPaletteBlock = endBlock;
}

// The true required footprint
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

?

.ToList();

// Cache to track which pixel arrays are already in VRAM
var allocatedTBPs = new Dictionary<byte[], ushort>(new ByteArrayComparer());
Copy link
Copy Markdown
Owner

@Nenkai Nenkai May 25, 2026

Choose a reason for hiding this comment

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

Instead of holding a byte array raw, this should just be a hash.
Also, isn't this technically incorrect? You may have the same image bytes, but the format may be different.

If the pixel format is different, the memory layout will be different.

// Skip the allocation and memory writing phase completely
continue;
}
// -------------------------------
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Stray comment?

@Nenkai
Copy link
Copy Markdown
Owner

Nenkai commented May 25, 2026

It's been a while since I've last touched this code and I have a strong feeling that you've used an LLM to try and work around some of the pretty non-decent code I initially wrote for texture optimization

For this reason I cannot verify that this is fully functional as opposed to the initial implementation, but I would also appreciate if the comments in the code or if the algorithm was properly documented. I can already see one major issue which I commented on

This entire thing should be reworked from the start, if I have to be honest, from someone who understands the memory layout and general packing algorithms.

Comment on lines +920 to +937
public class ByteArrayComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y) {
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null || x.Length != y.Length) return false;
return x.AsSpan().SequenceEqual(y);
}

public int GetHashCode(byte[] obj) {
if (obj == null || obj.Length == 0) return 0;
int hash = 17;
hash = hash * 31 + obj.Length;
hash = hash * 31 + obj[0];
hash = hash * 31 + obj[obj.Length / 2];
hash = hash * 31 + obj[obj.Length - 1];
return hash;
}
} No newline at end of file
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This will 200% break.
You are supposed to hash the entirety of the array, not just.. the length, start, middle, and end of it?
A texture that has the same length and the same 3 specific bytes will be treated as the same texture entirely.

-> HashCode.AddBytes

@Silentwarior112
Copy link
Copy Markdown
Author

I admit it's LLM code. I'm primarily focused on using it to figure unknown stuff. reverse engineer and implement the really difficult concepts since they're good at it. As far as the specifics of the code in these more complex repos, moving forward I consider changes like this experimental and will only push a commit if I feel like it's a significant breakthrough and I want to get a human review.

I'll work on it some more and get back to you.

I originally tried to make some kind of progress on render commands, transparency and improving reflections but
have struggled for the last week to get anywhere.
I have a pretty decent understanding of that stuff now through it all, but I don't actually know what parts of the model tool
to really target. I wanted to maybe increase the amount of blueprinting when dumping, again not really sure.
I was interested in getting variation mods for cars (adding more colors) but there doesn't seem to be a great way to get to that without going all the way with the model tool.
I want to push through more of these walls, if you can remember anything to point me in the right direction about that stuff let me know.

@Silentwarior112
Copy link
Copy Markdown
Author

A lot better now, Variations were broken before, fixed that back and cleaned up the code.
Changed the hashing method and eked out a tiny bit more size savings.
The size difference between custom and original vary a good bit depending on what was inside the Tex1.
ho0030's is ~9% larger vs what used to be ~50%.
The size savings here should be good enough for modding purposes, I think there's enough headroom to add things.
I'll have to see if I can iron out the CSA > 0 stuff on PSMCT16

@Nenkai
Copy link
Copy Markdown
Owner

Nenkai commented May 25, 2026

I'll be leaving this open for reference purposes. The nature of this code being not well documented both in general and for the intent makes it unverifiable and too dangerous for merging.

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