-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Support unspecified linear size in DDS files #86336
Support unspecified linear size in DDS files #86336
Conversation
modules/dds/texture_loader_dds.cpp
Outdated
ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), Ref<Resource>()); | ||
if (flags & DDSD_LINEARSIZE) { | ||
// Image exporter specified a size for the top-level image; it should match our calculation | ||
ERR_FAIL_COND_V(size != pitch, Ref<Resource>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said in the issue this needs to be contextualised so it's clear what's wrong, as it's not clear from this message that it depends on the flag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I guess it wasn't clear to me what you meant by that comment. I wasn't previously aware of the existence of ERR_FAIL_COND_V_MSG()
, which is what I'm assuming you want me to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case yeah, sorry for unclear, tried to make the same point in there 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording sounds good 🙂
256ef4f
to
747ca1f
Compare
CC @BlueCube3310 Who has been doing a lot of work on DDS importing recently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes sense to me. It would be good to have @BlueCube3310's opinion too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes importing compressed non-power of 2 textures created by DirectX Texture Tool, great work!
@clayjohn If you don't mind, I'd like to get your thoughts about how to address the second half of #86330. The DDS file in question is 1024x1024, and (as I recall) contains 8 mipmap levels, down to 4x4. Unfortunately, the I spent some time tinkering with that, and got I am not sure what a viable path forward would be. Is it practical to plumb the number of mipmap levels all the way down to the renderer? Or should we try to detect cases where an image with pre-generated mipmaps (e.g., DDS) hasn't been mipmap'd down to 1x1, and just ignore the mipmaps (and generate our own, internally?) |
Not all exporters choose to populate that (optional) header field.
747ca1f
to
a344d7f
Compare
I would go with the second approach and have the importer complete the mip map chain in cases where it isn't fully supplied. That will be the easiest "fix" for this problem. |
Hmmm... easy in concept, perhaps more complicated in practice, since we're dealing with compressed images. That seems like a lot of work to do, just to generate mips for when a 512x512 texture has been crushed down to a 2x2 square on the screen... The missing mips are so close to the point of "I am a single pixel on the screen", that I wonder if we might get acceptable results by just duplicating the initial block of the last provided mipmap level. For example, the image from #86330 is 512x512, and the mipmap chain in the DDS ends at 8x8. That is 4 (2x2) blocks of DXT data. The 4x4 mipmap will be a single block, and then 2x2 and 1x1 aren't even fully utilized blocks. Maybe just take the top-left block of data from the 8x8 mipmap and copy it three times? It will be wrong for strong color gradients that have different colors in all four corners, but might yield acceptable results for less pathological cases. |
@LunaticInAHat that could work. A similar idea would be to extract the lowest mip level of the compressed texture. Copy that into an image, decompress, generate mipmaps, compress, then copy the source and generated mipmaps into a new image |
This reminds me of the Mipmaps > Limit option having no effect in the Import dock. |
Thanks, and congrats on your first merged Godot contribution! |
Cherry-picked for 4.2.2. |
Cherry-picked for 4.1.4. |
This PR adjusts the DDS image loader, to properly handle compressed DDS images which were created by tools that elected not to specify the size of the top-level image, in the DDS header.
In cases where the exporter did specify a size, we compare it against our locally-calculated size. In cases where the exporter did not specify, we check that they populated a 0 in the associated header field, to minimize the risk of trying to parse corrupt / malformed files.
This PR fixes a part of #86330. The image supplied in that bug report's reproduction project still does not import successfully, due to the Image subsystem expecting more mipmaps than are actually present in the file, however that appears to be a separate issue, not intrinsically related to the changes being made here (i.e., while that particular image is not fully fixed by this change, there exist other images that are)