BC3/DXT within PVR3 container format.

This topic contains 3 replies, has 2 voices, and was last updated by  Tobias Hector 4 years, 4 months ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #31295

    chump
    Member

    From the PVR file format specification, the texture data part (after the header and the metadata) is said to be;

    for each MIP-Map Level in MIP-Map Count
    for each Surface in Num. Surfaces
    for each Face in Num. Faces
    for each Slice in Depth
    for each Row in Height
    for each Pixel in Width
    Byte data[Size_Based_On_PixelFormat]
    end
    end
    end
    end
    end
    end

    Is there anything more specific than this or worth noting about when the texture might be in BC3 format (or really, any DXT format)? In moving from the PVR2 container format to this I am iterating through mip-mips in the above way (and mipmaps/faces for cubemaps) and just getting complete garbage despite the fact that the texture is okay within the TexTool.

    Thanks

    #37378

    Hi Chump,

    So for all compressed data the layout is a little different, though still effectively the same. All compressed data formats have a “minimum width/height” which is the lowest number of pixels than can be represented by any given block/region in a compressed image. There is a function in our tools, “PVRTGetFormatMinDims” which lists these dimensions for each format if you need a reference.

    The first step is to align the width and heigh values to these minimum width/heights, so for a min width/height of 4, a 511×511 image becomes 512×512. This constitutes any texture padding done to meet the compression format’s requirements, and is essentially garbage data, but it needs to exist for the format to be valid. All you then need to do is work out the number of blocks/regions from this, and copy that many. At this point there are only 2D compression formats, so depth will function as a number of individual slices, and can for now be treated normally.

    For each individual block/region, the bits per pixel are listed in another function; “PVRTGetBitsPerPixel” which helps determine the block/region size.

    So to update the specification, it looks like this:
    for each MIP-Map Level in MIP-Map Count
    for each Surface in Num. Surfaces
    for each Face in Num. Faces
    for each Block/Region by aligned Depth (Based_On_PixelFormat)
    for each Block/Region by aligned Height (Based_On_PixelFormat)
    for each Block/Region by aligned Width (Based_On_PixelFormat)
    Byte data[Size_Based_On_PixelFormat]
    end
    end
    end
    end
    end
    end

    I hope that makes sense?

    Let me know if you need further clarification. I’ll also file a bug to update the documentation with an explanation.

    Regards,
    Tobias

    #37379

    chump
    Member

    Maybe I should have been clearer in the original post and mentioned ‘is there anything more specific than this, but for the exception of the three inner loops which wouldn’t really apply being block based.

    Or putting it another way, this is what I’m having a problem with.

    for each MIP-Map Level in MIP-Map Count
    for each Surface in Num. Surfaces
    for each Face in Num. Faces
    glCompressedTeximage2D(Level, etc)
    end
    end
    end

    Only in my case, I have no Surfaces and only have faces for Cube maps. In the cases of a plain old 2d textures only the outer loop is relevant, which still isn’t working for me.

    Naturally in iterating through the above logic there’s a pointer being adjusted to step through the data but the size of the adjustment looks to be correct and actually based on a prior PVR2 and DDS implementation to calculate.

    In fact, this new PVR3 version is very similar to the prior version, it looks at the header, moves the pointer beyond that and the meta data to get to the texture data and then goes through the loops as above. If I understand correctly, past the header and meta the only difference between PVR2 and PVR3 is that the ordering of those for each loops has changed. IIRC the ‘for each MIP-Map Level in MIP-Map Count’ used to be the inner loop in PVR2.

    So I have almost the same code as before for when it gets the texture data part of the PVR3 format, but with the loops switched round – all size calculations have not changed and appear to be correct for DXT given they work in the DDS and PVR2 implementations and appear to be the correct size in debugging/single stepping.

    But I’m getting garbage of course.

    Has any additional padding/alignment been put in outside of that for non pow2 textures (and the textures I’m processing are pow2 anyway)?

    #37380

    Hi Chump,

    Ah ok, you’re right when you say that the MIP Map part has moved outward – it’s to be more in line with OpenGL, since it’s easier to load into GL this way around, and no harder to load it into DirectX. Have you looked at how the PVRtools code handles this?

    As for NPOT padding etc., there’s no padding beyond what’s needed to fill out the blocks themselves, hence what I mentioned above. PVR files continue to be tightly packed with no support for additional padding. If you want to post some code/pseudo code, either here (or dm me, or to DevTech@imgtec.com) I can have a look at it if you want?

    Thanks,
    Tobias

Viewing 4 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic.