Copy unaligned mipmaps of a compressed texture to another compressed texture

Started by
7 comments, last by Jordy 6 years, 9 months ago

I'm copying mipmaps of a BC3 compressed texture region to a new (and bigger) BC3 compressed texture with ID3D11DeviceContext::CopySubresourceRegion.

Unfortunately the new texture contains incorrect mipmaps when the width or height of a mipmap level are unaligned to the block size, which is 4 in the case of BC3.

I think this has to do with the virtual and physical size of a mipmap level for block compressed textures: https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#Virtual_Size

There is also a warning:

Quote

In summary, be careful to use aligned memory blocks when copying regions that contain block-compressed data. To do this in an application that gets a memory pointer, make sure that the pointer uses the surface pitch to account for the physical memory size.

I don't know how to account for the physical memory size and if that's possible when using ID3D11DeviceContext::CopySubresourceRegion.

Is it possible, and if so, how?

Advertisement

What error are you getting?

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

You should be able to provide a null source box, which is equivalent to applying the whole source subresource to the specified offset in the dest (which should be (0, 0, 0) if you're copying the whole mip).

In general, you should always round up the size of the copy to block dimensions, even if the texture doesn't have the logical dimensions to support it. So a 1x1 BC3 mip would be copied as if it was 4x4.

15 hours ago, SoldierOfLight said:

In general, you should always round up the size of the copy to block dimensions, even if the texture doesn't have the logical dimensions to support it. So a 1x1 BC3 mip would be copied as if it was 4x4.

That's what I'm currently doing, my source box has the aligned coordinates corresponding to the mipmap level dimensions of the texture. Even when I provide a null sourcebox I still get artifacts on the edges. I've attached two images showing a copied mipmap level in the new texture. (also for showing the artifacts to @ajmiles). The first one is correct and the second one is incorrect. The first one was built beforehand and the second texture was built at run-time with ID3D11DeviceContext::CopySubresourceRegion.

 

5950dca69f38a_moon_correct_padding-Copy.png.eadd6a1d55d2921061f4f25de79d4a55.png5950dca727999_moon_wrong_padding-Copy.png.02410df57da8a30a35db532dbb8884f9.png

I would try running this on WARP, just to be sure. The stretch marks at the edge of the copy I have no explanation for, and so it may well be a bug in a particular hardware vendor's driver / implementation.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

I just ran it in WARP and it doesn't make any difference unfortunately. Thanks for suggesting WARP though!

So to get this straight, you're copying from an unaligned mip to a larger mip? I misinterpreted the question, and assumed you were going from a mip in one texture to a same-sized mip of a different texture.

According to the D3D spec, unaligned textures still have all 4 texels present in the physical data, but as far as I can tell, it doesn't specify what their contents have to be. What you're seeing here appears to be copying the full 4x4 region into the larger texture and seeing the results. I'm not sure what you'd expect to happen in this case - are you expecting black around the border?

I'm copying from an unaligned mip to another mip at a destination in a larger texture. I expect the unaligned mip at the destination in the larger texture to be exactly the same as the original and I expect the border, that exists because of the unalignment, to be transparent (black, Intel GPA texture viewer uses black for transparent). Can I enforce this in any way?

Thanks for your help!

This topic is closed to new replies.

Advertisement