powervr-graphics / Native_SDK

C++ cross-platform 3D graphics SDK. Includes demos & helper code (resource loading etc.) to speed up development of Vulkan, OpenGL ES 2.0 & 3.x applications
https://docs.imgtec.com/sdk-documentation/html/introduction.html
MIT License
710 stars 202 forks source link

iOS iPhone6 fails to create GL_TEXTURE_2D_ARRAY #16

Closed sasmaster closed 7 years ago

sasmaster commented 7 years ago

Hi again,I am working on integration of 2D array textures. Using PVR to load the array texture it work on Windows with PVR SDK GL ES3.0 emulator. However,when I launch debug on iPhone 6 device it fails on

glCompressedTexSubImage3D with INVALID_ENUM error.I trippled checked all the data and enums I pass into the function and found nothing wrong there.The GL docs say that INVALID enum can be cause by a wrong target or internal format.Both seem to be fine ,at least in debugger.

Here is the whole chunk of code that tries to load array texture.

`

GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, mHeader.u32MIPMapCount, internalFormatOut, mHeader.u32Width, mHeader.u32Height, mHeader.u32NumSurfaces));

            for (uint32_t uiMIPLevel = 0; uiMIPLevel < mHeader.u32MIPMapCount; ++uiMIPLevel)
            {
                for (uint32_t uiSurface = 0; uiSurface < mHeader.u32NumSurfaces; ++uiSurface)
                {
                    auto mipWidth    = getWidth (uiMIPLevel);
                    auto mipHeight   = getWidth (uiMIPLevel);
                    auto dataSize    = getDataSize (uiMIPLevel, false, false);
                    auto dataAddress = getDataPointer (texData, uiMIPLevel, uiSurface, 0);

                    /*
                    GL_CHECK (glCompressedTexImage3D (targetOut ,
                                                      uiMIPLevel,
                                                      internalFormatOut,
                                                      mipWidth,
                                                      mipHeight,
                                                      mHeader.u32NumSurfaces,
                                                      0,
                                                       dataSize ,
                                                       dataAddress ));
                     */
                   GL_CHECK(glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, uiMIPLevel, 0, 0,
                                                      uiSurface, mipWidth, mipHeight, 1, GL_RGBA, dataSize, dataAddress));

                   }
            }

`

The internal format is GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG getDataSzie() and getDataPointer() are the methods I borrowed from the SDK

I also attach the texture itself.It has 4 equal sized textures inside.Baked with PVRTexTool.

Thanks. PS:rename .zip to .pvr. What a shame on Github they don't support PVR upload ;)

rustmetal_array.zip

sasmaster commented 7 years ago

glCompressedTexImage3D also throws the same error,btw

PVRDevTech commented 7 years ago

Hi

PVRTC compressed image format (e.g. GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) is only accepted by the <internalformat> parameter of glCompressedTexImage2D and the <format> parameter of glCompressedTexSubImage2D.

Thanks, Shaun

sasmaster commented 7 years ago

Correct.But none of those work.I have also realized just now that I can not use gl Storage API because it demands valid FORMAT.But as I see ,in case of compressed textures,the tex format is always zero.You can uncomment the glCompressedTexImage2D and try to load the file I supplied.It should fail.Thanks.

sasmaster commented 7 years ago

Well,that fast fast.Had to replace the inner loops and add 'uiSurface' as a third param to getDataPointer() method. ` GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, mHeader.u32MIPMapCount, internalFormatOut, mHeader.u32Width, mHeader.u32Height, mHeader.u32NumSurfaces));

           for (uint32_t uiSurface = 0; uiSurface < mHeader.u32NumSurfaces; ++uiSurface)
           {
            for (uint32_t uiMIPLevel = 0; uiMIPLevel < mHeader.u32MIPMapCount; ++uiMIPLevel)
            {

                    auto mipWidth    = getWidth (uiMIPLevel);
                    auto mipHeight   = getWidth (uiMIPLevel);
                    auto dataSize    = getDataSize (uiMIPLevel, false, false);
                    auto dataAddress = getDataPointer (texData, uiMIPLevel, uiSurface, 0);

                 GL_CHECK(glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, uiMIPLevel, 0, 0,
                                                      uiSurface, mipWidth, mipHeight, 1, internalFormatOut, dataSize, dataAddress));

                   }
            }

`

Now it works.

sasmaster commented 7 years ago

But it doesn't work with

GL_CHECK (glCompressedTexImage3D (targetOut , uiMIPLevel, internalFormatOut, mipWidth, mipHeight, mHeader.u32NumSurfaces, 0, dataSize , dataAddress ));

Can you point out to what params should be set for

                auto dataSize    = getDataSize (uiMIPLevel, false, false);
                auto dataAddress = getDataPointer (texData, uiMIPLevel, uiSurface, 0);

In this case? Thanks!

PVRDevTech commented 7 years ago

Hi,

As I stated before the extension is not designed to work with glCompressedTexImage3D, the spec states that the pvrtc compression format should only be passed into the 2D variant of texture image and texture sub-image functions, please refer to the spec here: https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt

Regards, Shaun

sasmaster commented 7 years ago

Oh!Had no idea about that.But from the other side I see it works fine with glTexStorage3D .I don't see on that page anything about it.Though I also see the specs of the extension are quite old... Thanks for help, man!