Skip to content
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

Partial blocks and block counts (for PVRTC) #131

Closed
mlvdm opened this issue Jul 27, 2020 · 5 comments
Closed

Partial blocks and block counts (for PVRTC) #131

mlvdm opened this issue Jul 27, 2020 · 5 comments

Comments

@mlvdm
Copy link

mlvdm commented Jul 27, 2020

I was reading this spec (from here: http://github.khronos.org/KTX-Specification/) and have a few remarks

First, section 3.4 says pixelWidth pixelHeight pixelDepth must be multiples of block sizes. That is not a constraint on most rendering API any more (including VK). The restriction would (according to this spec) make it illegal to, for example, store a 3x3 single-mip image in a format that uses 4x4 blocks. I believe it's already possible to store such image in the container if that requirement is removed. (ie: the represented image is the top-left region of the block surface, and the rightmost or bottommost "padding" values in the last row and column of blocks are present but unused)

Second, section 2 says that num_blocks_x and num_blocks_y can be computed as max(1, ceil(...)), but that might not account for PVRTC formats, which, as far as I understand, for decoding refer to 4 blocks worth of data, so it might be max(2,...) for both X and Y in that case.

For this, I have found no actual spec that says how/why it is the way it is, but if one treats the "official" PVR tooling as the reference, it appears that it never generates surfaces with less than 2x2 blocks (which implies that, at least, it's >possible< to have more than a single data word in the tail of the mipchain). Note that manual inspection shows that these 4 data words seem to have different values, so presumably they are meaningful.
See for example the "canonical" sample .PVR file that comes with the SDK of which a copy exists here: https://github.com/toji/texture-tester/blob/master/textures/shannon-pvrtc-4bpp-rgba.pvr (in that particular file, the last 1x1 mip surface is found at file offset 174833 and is 32 bytes long (ie: 4 64bit blocks)).

@MarkCallow
Copy link
Contributor

We plan to remove the size restrictions from the format. See #123 (comment) and subsequent discussion. So I will close this issue.

We will likely add some non-normative text describing limitations imposed by some formats and APIs. It would be good to clarify the PVR limitations for that text. Have you looked at https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#PVRTC? It is a complete specification and explains the reason for the 2x2 blocks.

@mlvdm
Copy link
Author

mlvdm commented Jul 27, 2020

That spec actually says specifically "At least one word of PVRTC data must exist in each mip level of a texture." which is specifically not "At least 2x2 words of PVRTC data must exist in each mip level of a texture", which seems to leave open the existence of a 1x1 and a 2x2 variant of the smallest mips.

From the PVRTC format itself, it seems like it has the concept of wrapping around the edges, so you could view a single block as just wrapping around to itself in every direction. Anyway, I didn't find an unambiguous authoritative source that says "must be 1 word" or "must be 2x2 words", so I went with my observation of what I've seen in actual files as the best guess.

@lexaknyazev
Copy link
Member

From the OpenGL ES IMG_texture_compression_pvrtc extension:

  • For PVRTC 4BPP formats the imageSize is calculated as:
    (max(width, 8) * max(height, 8) * 4 + 7) / 8
  • For PVRTC 2BPP formats the imageSize is calculated as:
    (max(width, 16) * max(height, 8) * 2 + 7) / 8

Seems like 32 bytes is the minimum PVR image size possible.

@MarkCallow
Copy link
Contributor

@mlvdm https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#PVRTC is supposed to be an authoritative source and has the approval of Imagination. please file an issue about the contradiction you spotted at https://github.com/KhronosGroup/DataFormat. Same for any future problems you discover.

@mlvdm
Copy link
Author

mlvdm commented Jul 27, 2020

OK, put up a request on the other repository. Thanks @lexaknyazev for that other document, that does make it pretty conclusive that it's 2x2 for the data representation.

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

No branches or pull requests

3 participants