Imagination PowerVR SDK Blog

PVRTexLib: Crash with mip maps generation


#1

Using the previous or latest version of the texture lib I have implemented for the first time the generation of mip maps with the CompressPVR function.


The problem is the function will crash most all of the time (either static lib, 32 or 64 windows)





Now I wonder if it is broken or if I am using it incorrectly:




    // make a CPVRTexture instance with data passed

    CPVRTexture sOriginalTexture(

      width,   // u32Width,

      height, // u32Height,

      0,               // u32MipMapCount,

      1,               // u32NumSurfaces,

      false,            // bBorder,

      false,            // bTwiddled,

      false,            // bCubeMap,

      false,            // bVolume,

      false,            // bFalseMips,

      alpha?1:0,        // bHasAlpha

      false,            // bVerticallyFlipped

      eInt8StandardPixelType,    // ePixelType,

      0.0f,             // fNormalMap,

      rgba     // pPixelData

      );





    // create texture to encode to

    CPVRTexture sCompressedTexture( sOriginalTexture.getHeader() );

    sCompressedTexture.setMipMapCount( 2 );

    sCompressedTexture.setPixelType( OGL_PVRTC4 );



    // encode texture

    PVRTextureUtilities PVRU;

    PVRU.CompressPVR( sOriginalTexture, sCompressedTexture );

[/CODE]



rgba is an array which always containing rgb and alpha, widthheight pixels. No padding.



I clone the format and set the map count to a value which allows generating enough levels down to 16x16 (in this example on top I placed the number 2).



Calling CompressPVR will result in a crash. Removing the mip map count will produce nice results.



The texture I tried it with was 512x512, but also a smaller one crashed.

<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;// make a CPVRTexture instance with data passed<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;CPVRTexture sOriginalTexture(<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width,&nbsp;&nbsp;&nbsp;// u32Width,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height, // u32Height,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // u32MipMapCount,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // u32NumSurfaces,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bBorder,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bTwiddled,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bCubeMap,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bVolume,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bFalseMips,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alpha?1:0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // bHasAlpha<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bVerticallyFlipped<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eInt8StandardPixelType,&nbsp;&nbsp;&nbsp;&nbsp;// ePixelType,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.0f,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// fNormalMap,<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rgba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// pPixelData<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br /> <br /><br /> <br /><br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;// create texture to encode to<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;CPVRTexture sCompressedTexture( sOriginalTexture.getHeader() );<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;sCompressedTexture.setMipMapCount( 2 );<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;sCompressedTexture.setPixelType( OGL_PVRTC4 );<br /> <br /><br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;// encode texture<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;PVRTextureUtilities PVRU;<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;PVRU.CompressPVR( sOriginalTexture, sCompressedTexture );<br /> <br />





rgba is an array which always containing rgb and alpha, width
height pixels. No padding.





I clone the format and set the map count to a value which allows generating enough levels down to 16x16 (in this example on top I placed the number 2).





Calling CompressPVR will result in a crash. Removing the mip map count will produce nice results.





The texture I tried it with was 512x512, but also a smaller one crashed.



#2

Hi Pierre,





The function you actually want to be using is ProcessRawPVR. If you

simply set the MipMap count, the compressor gets confused and tries to

read data that simply doesn’t exist (I’m trying to make this more clear

in the next version of PVRTexLib).





If you create a new CPVRTextureHeader, and set its MIP map count to 2,

then pass your original texture and this header into it, it will add the

desired MIP map levels. After this, initialise your compressed texture

and do the set-up as you are now, minus the setMipMapCount.





In case that’s not clear:


<pre =“BBcode”> // make a CPVRTexture instance with data passed

    CPVRTexture sOriginalTexture(

      width,   // u32Width,

      height, // u32Height,

      0,               // u32MipMapCount,

      1,               // u32NumSurfaces,

      false,            // bBorder,

      false,            // bTwiddled,

      false,            // bCubeMap,

      false,            // bVolume,

      false,            // bFalseMips,

      alpha?1:0,        // bHasAlpha

      false,            // bVerticallyFlipped

      eInt8StandardPixelType,    // ePixelType,

      0.0f,             // fNormalMap,

      rgba     // pPixelData

      );



    CPVRTextureHeader sProcessHeader( sOriginalTexture.getHeader() );

    sProcessHeader.setMipMapCount( 2 );

    PVRTextureUtilities PVRU;

    PVRU.ProcessRawPVR(sOriginalTexture,sProcessHeader,false,0.0f,0.0f,0.0f,false,eRESIZE_NEAREST);;

  // create texture to encode to

    CPVRTexture sCompressedTexture( sOriginalTexture.getHeader() );

    sCompressedTexture.setPixelType( OGL_PVRTC4 );



    // encode texture

    PVRU.CompressPVR( sOriginalTexture, sCompressedTexture );
[/CODE]

Hope this helps!

Thanks,

Tobias   

<br><pre ="BBcode">&nbsp;// make a CPVRTexture instance with data passed<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;CPVRTexture sOriginalTexture(<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width,&nbsp;&nbsp;&nbsp;// u32Width,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height, // u32Height,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // u32MipMapCount,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // u32NumSurfaces,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bBorder,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bTwiddled,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bCubeMap,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bVolume,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bFalseMips,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alpha?1:0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // bHasAlpha<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// bVerticallyFlipped<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eInt8StandardPixelType,&nbsp;&nbsp;&nbsp;&nbsp;// ePixelType,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.0f,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// fNormalMap,<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rgba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// pPixelData<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br /> <br><br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;CPVRTextureHeader sProcessHeader( sOriginalTexture.getHeader() );<br /> <br>&nbsp;&nbsp;&nbsp; sProcessHeader.setMipMapCount( 2 );<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;PVRTextureUtilities PVRU;<br><br>&nbsp;&nbsp;&nbsp; PVRU.ProcessRawPVR(sOriginalTexture,sProcessHeader,false,0.0f,0.0f,0.0f,false,eRESIZE_NEAREST);;<br /> <br> &nbsp; // create texture to encode to<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;CPVRTexture sCompressedTexture( sOriginalTexture.getHeader() );<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;sCompressedTexture.setPixelType( OGL_PVRTC4 );<br /> <br><br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;// encode texture<br /> <br>&nbsp;&nbsp;&nbsp;&nbsp;PVRU.CompressPVR( sOriginalTexture, sCompressedTexture ); </pre><br />

Hope this helps!

Thanks,

Tobias   


#3

Thank you Tobias, this helps a lot.





The funny part is, it did work a few times and I actually had a nice .pvr which contained the mipmaps. Just it did not work all the time.


And fopr me personally it was unclear. I think it would be nice if at least it would not crash but throw some error which I can catch. :slight_smile:


I also just noticed (and a bit too late) that the documentation is actually using it as you showed me. Just I did not see the line of code with ProcessRawPVR while flying over it. :slight_smile: