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
I didn't understand your question!
What part of the question didn't you understand?