Skip to content

Feature Request: Texture dump and replace #4630

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

Closed
Nezarn opened this issue Nov 24, 2013 · 15 comments
Closed

Feature Request: Texture dump and replace #4630

Nezarn opened this issue Nov 24, 2013 · 15 comments

Comments

@Nezarn
Copy link
Contributor

Nezarn commented Nov 24, 2013

It would be nice to have this feature, so that people can make for example highres texture pack for games. Dolphin has a nice implementation.

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Oct 30, 2014

So here's what I'm thinking:

  • Add an option to turn it on.
  • Force NonSSE for non-neon ARM when option is on (otherwise it won't work.)
  • Look up graphics by address, hash, and cluthash
    • Hopefully there are not too many addresses of the same texture.
    • Our texhash is not strong enough that it'd be safe to omit that, I think...
  • Add a method to dump textures - save all? GE debugger?
  • Determine if loading pngs for replaced textures is fast enough.
  • Allow the replaced textures to be a larger size (integer multiple only? any multiple?)
  • Deal with mipmap levels somehow? Separate hashes, or do we allow inserting miplevels with replacements?

-[Unknown]

@hrydgard
Copy link
Owner

hrydgard commented Nov 4, 2014

Doing this will practically "lock down" the texture hash so we really need to be sure this is the one we want to use. Dolphin has chosen an interesting path:
dolphin-emu/dolphin@2684c75

Combining a few parallell CRCs allows both a parallel implementation and using CRC hardware, where available. Might be a good choice, I don't know how it compares speed-wise to our algorithm.

As for mipmaps, we could either just generate them on load, or allow .DDS or another file format that can store mipmaps.

It would be possible to "preload" all replace-textures on game startup and keep them in a separate texture cache in order to avoid framerate hitches from loading .png, given enough RAM. Alternatively load them on a background thread as they are needed, using the original texture until they are done, although that might look ugly.

@unknownbrackets
Copy link
Collaborator

But, how will that perform on platforms where there's no hardware crc (arm pre-aarch32/64, x86 phones)?

Anyway, we should probably bench some more algorithms and see how they compare. Maybe it would be faster for neon anyway with some also-parallel algo. The current one is probably not that strong, but I've never actually run it through smhasher or anything to know how not-strong it is.

-[Unknown]

@LunaMoo
Copy link
Collaborator

LunaMoo commented Jul 18, 2015

It might be just remotely related, but I wonder if there would be any technical problem to do something similar also for movies? At least for the video part, as I understand it's just h264/mpeg4-avc so maybe it wouldn't be impossible to load higher quality video stream from external source while continue to make the game happy with whatever it needs from the original pmf?

I'm mostly interested in movies because pmf container isn't exactly easy to work with and would really preffer something I can create myself or at least reencode it later without using some warez programs flying around which most google results about pmf encoding/muxing leads towards.:c

@unknownbrackets
Copy link
Collaborator

Well, the way that games provide the video makes that a little complicated. They provide frames and can do whatever they want (such as custom looping or swapping video streams mid video), which a few games do.

We might be able to get the pts from the packets and map it to a video, but things would get complicated. Another complication is that the game can then do whatever it wants to the video - for example, draw subtitles on top, draw it behind characters, or even draw it not full screen. Since video decoding goes to memory, this requires a lot of somewhat complicated tracking to follow - it's something that would at best probably only work in some (maybe many) games.

Anyway, it's something that could be interesting, since applying an xBRZ filter to the video realtime wouldn't necessarily work except on very, very powerful computers. But it's definitely a lot of work - more than texture replacement.

-[Unknown]

@LunaMoo
Copy link
Collaborator

LunaMoo commented Jul 19, 2015

Cool, thanks for answer:3.
My simpleton brain made me think that it could just detect when game starts and when it should end movie and then kind of carelessly run the external video on top of everything detecting correct video by file name and maybe adding subtitles to the video itself when needed since it would be very little work in compare to whole process, but ouch it appears to be much more complex ~ especially counting weird uses of videos in some games.
Oh well, can't have everything.

@DonelBueno
Copy link

More into the topic, do you guys have any idea of when are you going to implement texture dumping/loading?

@DonelBueno
Copy link

Nothing?

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Apr 30, 2016

So here's an initial implementation of dumping and replacing:

master...unknownbrackets:tex-replace

This also allows overriding the hash range, for example if you know the part of a texture used is only 480x272, you can just specify that. It will load the png at that size, and hash only that area (well, at least the h, right now.)

Example textures.ini file:

[options]
hash = quick
version = 1

[hashranges]
0x090056d0,256,256 = 176,160
0x09936980,512,512 = 480,272
0x099bf1c0,512,512 = 480,272
0x09ad0240,512,512 = 480,272
0x09a47a00,512,512 = 480,272
0x0900c4d0,256,64 = 208,56

This causes it to only hash a smaller section of these particular textures, preventing some duplicate copies of textures. So it could be used (almost as a hack) to improve performance in some games.

Note: one thing that will inevitably confuse people is the alpha channel. Textures can and do have zero alpha with important colors, but many programs make it hard to work with PNGs that have a 0 alpha channel for all pixels.

Also, with the "save new textures" option enabled, this is capable of dumping scaled textures. That means theoretically, it could be used as a "cache" for texture scaling once it supports loading the PNGs. I'm expecting loading a PNG to be faster than actual xBRZ scaling, at least at higher levels (probably all levels?)

-[Unknown]

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented May 1, 2016

Well, pngs are fairly fast but there's definitely a penalty. If I let FF2 generate most of the different permutations in a certain area (~100 MB of PNGs at 1x) and then disable saving new textures, it's still dominated by loading those PNGs - 75% - 80%.

For most games, it'll probably be fine, and even 2x scaling is even more murderous in the same scene of FF2, if we disable the max texels per frame, etc. That being said, it could be worth storing the images with a faster compression format or no compression, optionally (since the time is all spent in inflate().)

-[Unknown]

@unknownbrackets
Copy link
Collaborator

Things we could still do here from #8715:

  1. Switch to / enable crc32c or xxh32.
  2. Support more formats, e.g. DDS, DXT, KTX, etc.
  3. Potentially use a format that combines all mip levels into a single file.
  4. Possibly support compressed formats (e.g. try .bc7.ktx or something?)
  5. Add support for using new/ as a texture source (would allow use as a "free" xBRZ disk cache.)
  6. Preload better on game startup to reduce hitching.
  7. Possibly cache decompressed texture data in RAM better.

-[Unknown]

@ghost
Copy link

ghost commented Jul 23, 2016

Any news on this feature, and/or when it's being added to PPSSPP?

@unknownbrackets
Copy link
Collaborator

Did you read #8715?

-[Unknown]

@matimachado
Copy link

Is there is currently a way to preload textures? like hrydgard saids "It would be possible to "preload" all replace-textures on game startup and keep them in a separate texture cache in order to avoid framerate hitches from loading .png, given enough RAM" ?

@unknownbrackets
Copy link
Collaborator

I'm going to close this since it's essentially implemented now - see #12059 for a possible improvement, related to my comment above in 2016.

-[Unknown]

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

No branches or pull requests

6 participants