problem while loading PVRTC using glCompressedTexSubImage2D and PBO

Tagged: , ,

This topic contains 9 replies, has 3 voices, and was last updated by  Zulkarnine 2 years, 5 months ago.

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #49293

    Zulkarnine
    Member

    Hello,
    I have been trying to update a compressed texture of PVRTC_2BPPV2 format using PBO using OpenGL_ES 3. But every time it fails with the code GL_INVALID_OPERATION.

    I am using following code to do the task:

    {//buffer: (GLubyte*)holds the raw pixel data
    //width:	width of the texture
    //height: 	heigth of the texture
    //NUM_OF_BITS_PER_PIXEL = 2 since PVRTC_2BPPV2 is used
    //so the actual data size is: (width*height*2)/8 bytes
    
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    
    glGenTextures ( 1, &texId );
    glBindTexture ( GL_TEXTURE_2D, texId );
    
    glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,width,height,0,(width*height*2)/8,0);
    
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glBindTexture ( GL_TEXTURE_2D, 0 );
    	
    //creating PBO
    
    glGenBuffers(1,&pboID);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID );
    glBufferData(GL_PIXEL_UNPACK_BUFFER, (width * height * 2)/8, 0, GL_STREAM_DRAW);
    GLubyte* colorptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, (width * height * 2)/8, GL_MAP_WRITE_BIT);
    
    if(colorptr)
    {	
    	breturen = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    	if(!breturen)
    	{
    		//something wrong happened
    	}
    }
    
    glBindTexture( GL_TEXTURE_2D, texId );
    glCompressedTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,(width*height*2)/8,0);
    
    memcpy(colorptr, buffer, (sizeof(GLubyte) * width * height *2)/8);
    
    free ( buffer );
    
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0 );
    glBindTexture( GL_TEXTURE_2D, 0 );}

    I have tried similarly using non-compressed textures with PBO which succeeds.
    Again I have tried updating PVRTC_2BPPV2 texture using glCompressedTexSubImage2D without PBO and it succeeds too.

    But the combination of Compressed texture along with PBO fails every time.

    Is it not supported to update a portion/whole compressed texture using PBO or is the problem related to the emulator?

    Looking forward to your replies.
    Thanks.

    #49301

    Joe Davis
    Member

    Hi Zulkarnine,

    Is it not supported to update a portion/whole compressed texture using PBO or is the problem related to the emulator?

    Unfortunately, it is not possible to replace regions of a PVRTC image.

    The PVRTC extension spec can be found in the Khronos registry: GL_IMG_texture_compression_pvrtc

    Issue 5 in the specification details the sub-texturing limitations of the format:

    5] Is sub-texturing supported?

    Resolution: Only for the reloading of complete
    images. Sub-images are not supportable because the PVRTC
    algorithm uses significant adjacency information, so there is
    no discrete block of texels that can be decoded as a standalone
    sub-unit, and so it follows that no stand alone sub-unit of
    data can be loaded without changing the decoding of surrounding
    texels.

    Regards,
    Joe

    #49304

    Zulkarnine
    Member

    Hello Joe,
    Thank you for your reply.

    I modified the code in the following way so that the whole texture is updated:

    //buffer: (GLubyte*)holds the raw pixel data
    //width:	width of the texture
    //height: 	heigth of the texture
    //NUM_OF_BITS_PER_PIXEL = 2 since PVRTC_2BPPV2 is used
    //so the actual data size is: (width*height*2)/8 bytes
    
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    
    glGenTextures ( 1, &texId );
    glBindTexture ( GL_TEXTURE_2D, texId );
    
    glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,width,height,0,(width*height*2)/8,0);
    
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glBindTexture ( GL_TEXTURE_2D, 0 );
    	
    //creating PBO
    
    glGenBuffers(1,&pboID);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID );
    glBufferData(GL_PIXEL_UNPACK_BUFFER, (width * height * 2)/8, 0, GL_STREAM_DRAW);
    GLubyte* colorptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, (width * height * 2)/8, GL_MAP_WRITE_BIT);
    
    if(colorptr)
    {	
    	GLuint breturen = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    	if(!breturen)
    	{
    		//something wrong happened
    	}
    }
    
    glBindTexture( GL_TEXTURE_2D, texId );
    glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,width,height,0,(width*height*2)/8,0);	
    
    memcpy(colorptr, buffer, (sizeof(GLubyte) * width * height *2)/8);
    
    free ( buffer );
    
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0 );
    glBindTexture( GL_TEXTURE_2D, 0 );

    basically i changed:

    glCompressedTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,(width*height*2)/8,0);
    

    to:

    glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,width,height,0,(width*height*2)/8,0);

    But this didn’t help either. The textures is completely blank.

    Am I doing something wrong or is PBO (Pixel Buffer Object) not supported with compressed textures?
    Or is it a hardware bug?

    Thanks again for your kind reply.

    #49306

    glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,width,height,0,(width*height*2)/8,0);

    Unfortunately, it is not possible to replace regions of a PVRTC image.

    The PVRTC extension spec can be found in the Khronos registry: GL_IMG_texture_compression_pvrtc

    Joe, it looks like Zulkarnine is using PVRTC_2BPPV2, which is defined in a different GLES extension:

    * https://www.khronos.org/registry/gles/extensions/IMG/IMG_texture_compression_pvrtc2.txt

    This extension states (in a couple different places):

    2] Is sub-texturing supported?

    Resolution: Yes, at block boundaries. This is 4×4 texels for
    the 4bpp format and 8×4 for the 2bpp format. Note it is up to
    the user to ensure the compressor tool is used in the mode which
    removes block edge artefacts (sic) if subdata is going to be used for
    eg. a texture atlas.

    #49315

    Joe Davis
    Member

    Joe, it looks like Zulkarnine is using PVRTC_2BPPV2, which is defined in a different GLES extension

    Ah – you’re right. Apologies for not spotting PVRTC2 was being used here.

    Note it is up to
    the user to ensure the compressor tool is used in the mode which
    removes block edge artefacts [sic] if subdata is going to be used for
    eg. a texture atlas.

    I’m not sure if we are exposing this in PVRTexTool. I’ll speak to the lead for that tool and will update this chain once I have an answer.

    #49321

    Zulkarnine
    Member

    Thank you Dark_Photon for pointing this out.

    Joe, it looks like Zulkarnine is using PVRTC_2BPPV2, which is defined in a different GLES extension:

    To be sure I tested with subTextures without PBO and it worked seamlessly. But I still can’t find why the texture/subTexture cannot be updated using PBO.

    Some sample results:
    1. RGB Full texture update (NO PBO):

    nonPVRTCfullImage

    2. PVRTC Full texture update (NO PBO): (Yes it’s a different texture and it should look like that)

    fullTexture-update

    3. RGB texture partial update + PBO :

    normalImageSubTextureUpdate

    4. PVRTC texture partial update + PBO :

    PVRTC_plus_PBO

    Don’t know what is going on in the last case and that is exactly what i’m having problem with 🙁

    Attachments:
    #49343

    Joe Davis
    Member

    PVRTC2 sub-texturing
    The PVRTexTool lead has given me an answer. The feature discussed in the PVRTC2 extension specification has not been added to PVRTexTool yet. I’ve filed a feature request in our tracker for this (BRN56735).

    If you would like to use the feature in the meantime, you could write your own tool to write the hard-edge flag for regions within a given PVRTC2 image. Section 3.1 (“Sub-texturing” bullet point) and section 3.3.2 of our “PVRTC and Texture Compression User Guide” explains how to do this. For a texture atlasing use case, you would need to set the hard-edge flag for the regions along the bottom row and rightmost column.

    Using PBOs to update textures
    Our “Understanding OpenGL ES: Multi-thread and multi-window rendering” blog post explains our recommendations for asynchronously updating buffers in OpenGL ES. We expect PBOs would further improve performance as the driver would not need to perform a memcpy from application memory to driver memory.

    #49354

    Zulkarnine
    Member

    Thanks for the detailed explanation but could you clarify the following things:

    1. Is “Hard Transition Flag” on section 3.3.2 and ‘hard-edge’ mode on section 3.1 mean the same thing?

    If you would like to use the feature in the meantime, you could write your own tool to write the hard-edge flag for regions within a given PVRTC2 image. Section 3.1 (“Sub-texturing” bullet point) and section 3.3.2 of our “PVRTC and Texture Compression User Guide” explains how to do this.

    2. Is hard-edge flag needed even when we are using

    glCompressedTexImage2D

    (NOT glCompressedTexSubImage2D)

    3. When I used glCompressedTexImage2D I got the same result as in [PVRTC texture partial update + PBO attachment (PVRTC_plus_PBO.png) ] in my previous reply. So, is this an emulator limitation? (I am using PVRFRAME version 10.0)

    4. You mentioned:

    The feature discussed in the PVRTC2 extension specification has not been added to PVRTexTool yet

    Is that feature (SubTexturing) a must in order to use PBO?

    #49396

    Joe Davis
    Member

    Is “Hard Transition Flag” on section 3.3.2 and ‘hard-edge’ mode on section 3.1 mean the same thing?

    Yes. I’ve filed a bug report against the document for this to be clarified in a future release (BRN56855).

    Is hard-edge flag needed even when we are using [glCompressedTexImage2D]

    No. The hard-edge flag is only needed to avoid artefacts in texture atlases created from PVRTC2 sub-textures.

    Is that feature [SubTexturing] a must in order to use PBO?

    After discussing this with the TexTool lead engineer, my understanding is that PBOs should work with full texture updates (e.g. glCompressedTexImage2D()). If you can share a binary with us that reproduces the issue, I’ll ask the PVRVFrame lead to investigate. You can share files with us confidentially by attaching them to a support ticket.

    #49400

    Zulkarnine
    Member

    Thank you for your reply.

    I have attached the sample binaries in the support ticket with PVRTrace files.

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