Improve Tex1 size optimization#21
Conversation
| 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 ---"); |
| Console.WriteLine($"HIGH WATER MARK (Max Block): {_usedGsBlocksIndices.Max(e => e)}"); | ||
| Console.WriteLine("---------------------------"); |
| if (endBlock > maxPaletteBlock) maxPaletteBlock = endBlock; | ||
| } | ||
|
|
||
| // The true required footprint |
| .ToList(); | ||
|
|
||
| // Cache to track which pixel arrays are already in VRAM | ||
| var allocatedTBPs = new Dictionary<byte[], ushort>(new ByteArrayComparer()); |
There was a problem hiding this comment.
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; | ||
| } | ||
| // ------------------------------- |
|
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. |
| 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 |
There was a problem hiding this comment.
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
|
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 |
|
A lot better now, Variations were broken before, fixed that back and cleaned up the code. |
|
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. |
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