The mobile hardware spec :
Galaxy S6 (SM-G920s)
Android OS : 7.0 Nougat
GPU : Mali-T760
GL_VERSION : OpenGL ES 3.2
Vulkan Version : 1.0.26
Hi I'm developing on my galaxy S6 and S8
But I think there is a problem on Mail-T760 Vulkan driver.
I made a feature that I can make a mipmap chain on texture cube.
I mean in the code
VkImageCreateInfo imageInfo{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; imageInfo.imageType = VK_IMAGE_TYPE_2D; imageInfo.format = TexCubeFormat; imageInfo.mipLevels = calculatedMipLevels; imageInfo.arrayLayers = 6; // because It's Texture Cube ... // make VkImage VkImageViewCreateInfo view{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; view.viewType = VK_IMAGE_VIEW_TYPE_CUBE; view.format = TexCubeFormat; view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; view.subresourceRange.aspectMask = aspectMask; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.levelCount = info.mipLevels; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.layerCount = 6; // because It's Texture Cube view.image = image; ... // make ImageView // and then copy buffer to texture only in mipmip 0 std::vector<VkBufferImageCopy> bufferCopyRegions; for (uint32_t face = 0; face < 6; face++) { VkBufferImageCopy bufferCopyRegion = {}; bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; bufferCopyRegion.imageSubresource.mipLevel = 0; bufferCopyRegion.imageSubresource.baseArrayLayer = face; bufferCopyRegion.imageSubresource.layerCount = 1; bufferCopyRegion.imageExtent.width = info.extent.width; bufferCopyRegion.imageExtent.height = info.extent.height; bufferCopyRegion.imageExtent.depth = info.extent.depth; bufferCopyRegion.bufferOffset = offset; bufferCopyRegions.Add(bufferCopyRegion); // Increase offset into staging buffer for next face offset += OneTextureSize; } vkCmdCopyBufferToImage( copyCmd, stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<uint32_t>(bufferCopyRegions.Length()), bufferCopyRegions.data()); // and then build mipmap on each layer(+X, -X, +Y, -Y, +Z, -Z) of Texture Cube VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.image = image; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.subresourceRange.aspectMask = subresourceRange.aspectMask; barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = 6; VkImageBlit imageBlit{}; imageBlit.srcSubresource.aspectMask = subresourceRange.aspectMask; imageBlit.srcSubresource.baseArrayLayer = 0; imageBlit.srcSubresource.layerCount = 6; // because It's Texture Cube imageBlit.srcOffsets[0] = { 0, 0, 0 }; imageBlit.srcOffsets[1].z = 1; imageBlit.dstSubresource.aspectMask = subresourceRange.aspectMask; imageBlit.dstSubresource.baseArrayLayer = 0; imageBlit.dstSubresource.layerCount = 6; // because It's Texture Cube imageBlit.dstOffsets[0] = { 0, 0, 0 }; imageBlit.dstOffsets[1].z = 1; for (uint32 level = 1; level < info.mipLevels; ++level) { barrier.subresourceRange.baseMipLevel = level - 1; barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; vkCmdPipelineBarrier(flyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); // Source imageBlit.srcSubresource.mipLevel = level - 1; imageBlit.srcOffsets[1].x = MAX(int32_t(info.extent.width >> (level - 1)), 1); imageBlit.srcOffsets[1].y = MAX(int32_t(info.extent.height >> (level - 1)), 1); // Destination imageBlit.dstSubresource.mipLevel = level; imageBlit.dstOffsets[1].x = MAX(int32_t(info.extent.width >> level), 1); imageBlit.dstOffsets[1].y = MAX(int32_t(info.extent.height >> level), 1); // Blit from previous level vkCmdBlitImage( flyCmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, mipmapFilter ); // convert the previous layout into the final layout barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier.newLayout = imageLayout; barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier(flyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); } // convert the layout into the finaly layout on the final mipmap chain barrier.subresourceRange.baseMipLevel = info.mipLevels - 1; barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier.newLayout = imageLayout; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier(flyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
I made a mipmap for all array layers of texture2D. Because It's texture cube, I used the array layer count 6.
With this code, The code works with what I think on the Desktop, and other Galaxy S8 with Mali-G71.
But It does not work on Galaxy S6 with Mali-T760.
I checked it with RenderDoc. It shows that There are only black pixels from second mipmaps to last mipmaps on every mipmap chain except for the X+ layer.
X+ layer has all perfect mipmap pixels. But others have definitely mipmap chains, but only have black colors.
So the result is..
and the renderdoc result is
What part of the question didn't you understand?