Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: Corrupt compressed 2D texture array texture on NV

  1. #1
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    121

    Corrupt compressed 2D texture array texture on NV

    Hello,

    I am having trouble successfully using the texture arrays extension. The sample application provided by Nvidia in their OpenGL SDK works fine, but when I modify the example, it fails to work in some cases.

    This works:
    Uncompressed RGB texture, fully mipmapped (Nvidia sample) or not mipmapped at all.

    Using partial mipmap specification (not down to 1x1) on the uncompressed texture makes subsequent rendering with the texture corrupt.

    Also, using DXT compressed textures does not work at all, whether they are mipmapped or not.

    Has anybody managed to use texture arrays with 2D DXT textures? This seems like the target use-case of the extension so I don't know what to think... I am currently using a GTX 280.

    Here is my test code which creates and transfers the textures. I create 6 different texture configurations. Is anything blatantly wrong in there?

    I did not include the rendering loop, which is simply "clear, bind texture, bind shader, render quad" and which works for some texture configurations. If anybody is interested, I'd be happy to provide the whole testapp.

    Thanks!

    Code :
    // 3 DXT blocks (red, green and blue)
    unsigned char DXTRedBlock[8];
    DXTRedBlock[0] = 0;
    DXTRedBlock[1] = 248;
    DXTRedBlock[2] = 0;
    DXTRedBlock[3] = 248;
    DXTRedBlock[4] = 0;
    DXTRedBlock[5] = 0;
    DXTRedBlock[6] = 0;
    DXTRedBlock[7] = 0;
     
    unsigned char DXTGreenBlock[8];
    DXTGreenBlock[0] = 224;
    DXTGreenBlock[1] = 7;
    DXTGreenBlock[2] = 224;
    DXTGreenBlock[3] = 7;
    DXTGreenBlock[4] = 0;
    DXTGreenBlock[5] = 0;
    DXTGreenBlock[6] = 0;
    DXTGreenBlock[7] = 0;
     
    unsigned char DXTBlueBlock[8];
    DXTBlueBlock[0] = 31;
    DXTBlueBlock[1] = 0;
    DXTBlueBlock[2] = 31;
    DXTBlueBlock[3] = 0;
    DXTBlueBlock[4] = 0;
    DXTBlueBlock[5] = 0;
    DXTBlueBlock[6] = 0;
    DXTBlueBlock[7] = 0;
     
    // The 3 DXT blocks grouped
    unsigned char Blocks3[24];
    memcpy( Blocks3, DXTRedBlock, 8 );
    memcpy( Blocks3+8, DXTGreenBlock, 8 );
    memcpy( Blocks3+16, DXTBlueBlock, 8 );
     
    // 3 uncompressed 4x4 textures (Solid red, green and blue)
    unsigned char Red4x4[48];
    for( int i = 0; i < 48; i++ )
    	Red4x4[i] = (i % 3) == 0 ? 255 : 0;
     
    unsigned char Green4x4[48];
    for( int i = 0; i < 48; i++ )
    	Green4x4[i] = (i % 3) == 1 ? 255 : 0;
     
    unsigned char Blue4x4[48];
    for( int i = 0; i < 48; i++ )
    	Blue4x4[i] = (i % 3) == 2 ? 255 : 0;
     
    glGenTextures(nNbTextures, texid);
     
    // First texture array (NOT OK)
    // -DXT compressed
    // -Not mipmapped
    // -Level 0 allocated and then subloaded
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[0]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
     
    // Second texture array (NOT OK)
    // -DXT compressed
    // -Fully mipmapped (3 levels)
    // -Levels allocated and then subloaded
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[1]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 2, 2, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 0, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 1, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 2, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 1, 1, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 0, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 1, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 2, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
     
    // Third texture array (NOT OK)
    // -DXT compressed
    // -Fully mipmapped (3 levels)
    // -Mipmaps allocated and initialized at once
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[2]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 3, 0, 24, Blocks3);
    glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 2, 2, 3, 0, 24, Blocks3);
    glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 1, 2, 3, 0, 24, Blocks3);
     
    // Fourth texture array (OK)
    // -Uncompressed RGB8 data
    // -Not mipmapped
    // -Level 0 allocated and then subloaded
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[3]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, 4, 4, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);
     
    // Fifth texture array (OK)
    // -Uncompressed RGB8 data
    // -Fully mipmapped (3 levels)
    // -Levels allocated and then subloaded
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[4]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, 4, 4, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 1, GL_RGB8, 2, 2, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 0, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 1, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 2, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 2, GL_RGB8, 1, 1, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 1, 1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 2, 1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);
     
    // Sixth texture array (NOT OK)
    // -Uncompressed RGB8 data
    // -Partially mipmapped (2 levels)
    // -Levels allocated and then subloaded
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[5]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, 4, 4, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 1, GL_RGB8, 2, 2, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 0, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Red4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 1, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Green4x4);
    glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 2, 2, 2, 1, GL_RGB, GL_UNSIGNED_BYTE, Blue4x4);

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Sep 2004
    Location
    Prombaatu
    Posts
    1,386

    Re: Corrupt compressed 2D texture array texture on NV

    Quote Originally Posted by bertgp
    Has anybody managed to use texture arrays with 2D DXT textures?
    No problemo on NV G80. Don't forget to alloc mipmap chain.

    glTexImage3D(..., NULL);
    glGenerateMipmaps(...);
    foreach image {
    foreach image mip level {
    glCompressedTexSubImage3D(..., level, ...)
    }
    }

  3. #3
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    121

    Re: Corrupt compressed 2D texture array texture on NV

    Quote Originally Posted by modus
    No problemo on NV G80. Don't forget to alloc mipmap chain.
    Thanks for your reply. Adding calls to glGenerateMipmap does seem to work. However, I am still confused by something.

    One of my examples does the mipmap generation, but with explicit calls to glTexImage3D instead of using glGenerateMipmap. Somehow, doing only the first glTexImage3D followed by a call to glGenerateMipmap works... What's wrong with the explicit version?

    Code :
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid[1]);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
     
    if( ExplicitMethod )
    {
    	glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 2, 2, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    	glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 1, 1, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    }
    else
    {
    	glGenerateMipmapEXT( GL_TEXTURE_2D_ARRAY_EXT );
    }
     
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 0, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 1, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, 2, 4, 4, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 0, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 1, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 1, 0, 0, 2, 2, 2, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 0, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTRedBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 1, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTGreenBlock);
    glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 2, 0, 0, 2, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, DXTBlueBlock);

  4. #4
    Senior Member OpenGL Pro dletozeun's Avatar
    Join Date
    Jan 2006
    Location
    FRANCE
    Posts
    1,367

    Re: Corrupt compressed 2D texture array texture on NV

    IMO, it works in the two cases because:

    1) In the explicit method you allocate memory for the two next mipmap levels and you indeed, set data for the mipmap levels from 0 to 2

    2) In the implicit method, all possible mipmap levels are allocated even if the levels 3 to N may not be used then.

    Actually it depends on what you need to do, the explicit method could be dangerous if during rendering mipmap levels higher than 2 are needed and the result would be undefined.

  5. #5
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    121

    Re: Corrupt compressed 2D texture array texture on NV

    Re-reading my post, I see that I could have been clearer.

    Indeed, I agree that both should work! However, the explicit method does not work; it uses whatever was left in memory at some unknown location.

    Ideally, I don't want to pay the extra processing time of glGenerateMipmap since all the mipmaps are already built and I just want to upload their content.

  6. #6
    Senior Member OpenGL Pro dletozeun's Avatar
    Join Date
    Jan 2006
    Location
    FRANCE
    Posts
    1,367

    Re: Corrupt compressed 2D texture array texture on NV

    Ah ok, I see. I have never tested it myself, but I agree with you that allocating only levels from 0 to 2 make sense. I will look in the opengl specification if there is any reason that would work; maybe it is an implementation limit.

    But, could you be clearer about what fails and in which cases using your explicit method?

  7. #7
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    121

    Re: Corrupt compressed 2D texture array texture on NV

    Quote Originally Posted by dletozeun
    Ah ok, I see. I have never tested it myself, but I agree with you that allocating only levels from 0 to 2 make sense. I will look in the opengl specification if there is any reason that would work; maybe it is an implementation limit.

    But, could you be clearer about what fails and in which cases using your explicit method?
    I looked at the specification myself and could not find anything. glGenerateMipmap is not even mentioned in the texture_array spec. Maybe I missed something though.

    My rendering loop is a screen-aligned quad using only the texture array's content to compute the shading. When all is ok, I get 3 vertical bars, each using one of the texture in the texture array. When it is not, the output varies between executions. I could not locate any pattern which could reflect the memory arrangement of the mipmap chain.

    Following the suggestion from Modus, I am now systematically calling glGenerateMipmap after creating the level 0 mipmap. This sure looks to me like a driver bug, but at least it works. For now, I only allocate 1 or 2 texture arrays when the application starts so it's not that big of a deal.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •