LukasBanana / LLGL

Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal
BSD 3-Clause "New" or "Revised" License
2.05k stars 139 forks source link

Question: LLGL_OpenGL , WriteTexture #64

Closed EvanderWang closed 3 years ago

EvanderWang commented 3 years ago

Hi. I found that when write compressed texture to Cubemap texture with extension GL_ARB_direct_state_access you call glCompressedTextureSubImage3D function just like when it is not compressed you call glTextureSubImage3D function. And I checked that why you call this function in page : https://www.khronos.org/opengl/wiki/Cubemap_Texture. It says : "Uploading pixel data for cubemaps is somewhat complicated. If OpenGL 4.5 or ARB_direct_state_access is available, then glTexSubImage3D can be used to upload face data for a particular mipmap level. The third dimension values for glTexSubImage3D represents which face(s) to upload data to. The faces are indexed in the following order: ..."

But when I use the compressed type write function it seems write nothing to the texture(all is black). So I want to know whether the glCompressedTextureSubImage3D function can use for cubemap texture just as same as the glTextureSubImage3D function ?

LukasBanana commented 3 years ago

Let me ask a few questions to better understand your situation:

  1. Can you create a RenderDoc trace and see what is coming through with the call to glCompressedTextureSubImage3D?
  2. Did you create the texture with a MIP-map chain or only a single MIP level?
  3. How many MIP levels did you upload with WriteTexture; in other words: how does your call to that function look like?
  4. Are you using a compressed format that your host GL implementation actually supports? You can get the actual format the texture uses internally by calling GetFormat() on that texture.
  5. Did you try the same without the GL_ARB_direct_state_access extension? I.e. disable CMake option LLGL_GL_ENABLE_DSA_EXT.
EvanderWang commented 3 years ago

1.Sorry I have not check in renderdoc and I do not sure how to capture the first frame. It’s very glad if you can teach me. 2.I’ve tried both. I made two dds with one has full mipmaped and the other has not.

  1. 2048x2048 full . 12 mipmap level. I write only 1 level 1 cube face per api call. Called 6 x 12 times. I also tried call 1 cube face all level and all cube face all level before. 4.dxt1 5.Yes ,I try the same code without DSA. That worked ,and this is why I submit this question.

sorry for reply delay. This is my first leave message on github

LukasBanana commented 3 years ago

If it works for the time being, I recommend to disable DSA in that case. OpenGL does not even guarantee a performance improvement when DSA is used. It is more of a set of functions for convenience. I will take a look over the next days. I would also appreciate if you could provide a code snippet of how you invoke the WriteTexture calls.

EvanderWang commented 3 years ago

`LLGL::TextureDescriptor tDesc; tDesc.type = LLGL::TextureType::TextureCube; tDesc.format = curCompressType; tDesc.extent = { (uint32_t)header.width, (uint32_t)header.height, 1 }; tDesc.arrayLayers = 6; tDesc.miscFlags = LLGL::MiscFlags::NoInitialData; tDesc.mipLevels = header.mipMapCount; tDesc.bindFlags = LLGL::BindFlags::Sampled;

                rtValue = rs.CreateTexture(tDesc, nullptr);

                for (uint32_t side = 0; side < 6; side++)
                {
                    int32_t curWidth = header.width;
                    int32_t curHeight = header.height;

                    for (uint32_t mip = 0; mip < (uint32_t)header.mipMapCount; mip++)
                    {
                        uint32_t blockWidth = (curWidth + 3) / 4;
                        uint32_t blockHeight = (curHeight + 3) / 4;
                        uint32_t blockCount = blockWidth * blockHeight;
                        uint32_t bufferSize = blockCount * curBlockSize;

                        ReadValue(file, data_compressed, bufferSize);

                        LLGL::TextureRegion region;
                        region.subresource.baseArrayLayer = side;
                        region.subresource.numArrayLayers = 1;
                        region.subresource.baseMipLevel = mip;
                        region.subresource.numMipLevels = 1;
                        region.offset = { 0,0,0 };
                        region.extent = { (uint32_t)curWidth , (uint32_t)curHeight, 1 };

                        LLGL::SrcImageDescriptor siDesc;
                        siDesc.format = curImageType;
                        siDesc.data = &data_compressed[0];
                        siDesc.dataSize = data_compressed.size();

                        rs.WriteTexture(*rtValue, region, siDesc);

                        curWidth = std::max(curWidth / 2, 1);
                        curHeight = std::max(curHeight / 2, 1);
                    }
                }`

Here is my code snippet , worked without DSA , maybe I have a mistake for api using , hope it could be help.

LukasBanana commented 3 years ago

Thanks for pointing out this issue. The wrong function was invoked to query the internal texture format which is required for compressed texture updates only. This is fixed with 6164994.