Sparse image miplevels copying help

Hi all,

I have a sparse image (BC3 format) with a full miplevel, which I filled only the base level (0) with my texture images (BC3 format), and rendered it with no complaints (sampling using sparseTextureLodARB at Lod 0). The problem arises when I try to copy the other miplevels of my images into the sparse image’s respective miplevels. To fulfill the requirement of VkBufferImageCopy that imageOffset has to be a multiple of my compressed block texel (4x4), I added a small value to the offset, which caused my rendered textures to be shifted at those miplevels which I don’t want. So is there a way to copy my compressed textures mips into the sparse image mips at the correct offset where it will be sampled precisely?

Also I may not have understood the concept of miptails which are suppose to store perhaps these smaller-than-a-sparse-block sized miplevels?

Appreciate any help.

1 Like

To fulfill the requirement of VkBufferImageCopy that imageOffset has to be a multiple of my compressed block texel (4x4), I added a small value to the offset

Where did the “offset” you’re using come from? If you computed that offset based on the information Vulkan provides, the offset ought to already be block-aligned.

What I am trying to do is to pack my texture images tightly inside the sparse image. The offset is the location within the sparse image where I copy my texture images to, right next to the previously inserted texture image for example. This works fine for the base miplevel as all my textures are powers of 2 in both dimensions and therefore aligned with multiples of 4, but not for subsequent miplevels, which I shift the copy offset location artificially to the next multiple of 4.

Do you mean the sparse image blocks offset and extent Vulkan provides? On my system, each block is 256x256 and I do want to pack multiple textures within them to maximum memory usage. Basically what I want is a megatexture which I bind once for most of my objects.

OK, so allow me to restate what you’re doing.

You are building a mipmapped texture atlas, and you want to know how to position the mipmaps for the different sub-images within the texture so that they’re correctly positioned relative to the higher mip-map levels. But the texture is block-compressed.

Well, that’s only going to work if all of the sub-images are powers-of-two in size. Or more specifically, all of your copies have to use pixel offsets and sub-image sizes which are powers-of-two. Otherwise, you would have to be able to copy into part of a block. And you can’t shift which mipmap texels get fetched from.

And even if you stick to the power-of-two thing, you need to stop your mipmap pyramid before the point where blocks have to start merging. To understand that, here’s a concrete example.

The point where a mipmap level becomes smaller than a block is the point where either dimension of the image is less than 4. So if you have a subimage that is 64x64, that subimage could have 7 mipmap levels total. However, the 1x1 and 2x2 mipmap levels are unusable, because they’re smaller than a block in size. So the number of useable mipmap levels is 5.

The minimum mipmap level in your overall image pyramid is defined by the smallest subimage in your atlas. If some of your subimages are 1024x1024 (which would have 9 useable levels), but one of them is 32x32, then the number of usable levels is 4: the number of usable levels in a 32x32 image.

So your minimum mipmap level for the overall image needs to be defined by the smallest subimage you intend to use.