Sign in to follow this  

Pass array of textures with different dimensions to shader

This topic is 419 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi.

I am working with DirectX 11 and I need to pass to shader an array of textures with different dimensions and have access to it by index.

So, seems Texture2DArray type is not what I need.

 

Does anyone already did such thing?

 

What is the correct way of doing this?

Share this post


Link to post
Share on other sites

Maybe I wrote my problem wrong.

Under dimensions I mean that each texture can have different width/height, but they all of the same type (texture2D).

This is also not possible in DX 11?

Edited by BlackJoker

Share this post


Link to post
Share on other sites

Creating an ID3D11Texture2D with an ArraySize of > 1, all array slices end up with the same width/height. In theory, you could do what you want in D3D11 by allocating the texture with dimensions of the largest slice, and doing a manual border on the ones that are smaller, and passing additional data per-slice so you can scale texture coordinates appropriately.

 

In D3D12, you can have an array of Texture2Ds in the shader, and dynamically index into that array. Each Texture2D can have its own dimensions.

Share this post


Link to post
Share on other sites
An approach sometimes used to emulate D3D12 bindless model is to pick a subset of valid texture sizes and then bind each of those sizes as an array. Your individual textures are then bucketed into the approach array and given an index. A few more tricks let you efficiently pass around a texture handle which is a combination of the array to use and the index.

This isn't _quite_ the same, but it works.

It does require bucketing textures to a small handful of fixed sizes, but you should be doing that anyway (arbitrary texture sizes are not hardware-friendly - keep the majority of your textures in nice power-of-two buckets).

You can emulate things further by abusing mip levels (e.g., storing an entirely different texture in mip 0 and mip 1, since mip 0 will be twice the size). This of course means that you can't actually use mips for their intended purpose, but that may not be a big problem for your use case.

Lastly, there's always texture atlasing.

Share this post


Link to post
Share on other sites

An approach sometimes used to emulate D3D12 bindless model is to pick a subset of valid texture sizes and then bind each of those sizes as an array. Your individual textures are then bucketed into the approach array and given an index.
 

 

Can you, please, give some examples how to implement this?

Share this post


Link to post
Share on other sites

I just thought that I can create a Texture3D and fill it with different 2d textures at each slice and load them by depth, correct?

This could be a solution to my problem. The only issue I see - it would consume more memory.

 

Btw, I suppose it is not possible to use different slices in texture 3d? They all should be align to the same size, correct?

Edited by BlackJoker

Share this post


Link to post
Share on other sites

I just thought that I can create a Texture3D and fill it with different 2d textures at each slice and load them by depth, correct?


That's the gist, yes.

This could be a solution to my problem. The only issue I see - it would consume more memory.


Determine how many textures you need and set the array depth accordingly. In other words, pre-allocate the GPU memory you need.

You can also perhaps use texture residency controls from 11.2 to assist with ememory, but I've never tried that and don't know if anyone else has off the top of my head.
 

Btw, I suppose it is not possible to use different slices in texture 3d? They all should be align to the same size, correct?


The problem there is that 3D textures have mipping between slices. That is, mip levels in 2D are just halved 2d planes while mip levels in 3d are quartered boxes.

I don't see why you think the 3d approach would improve on the 2d array approach in any case. It's preallocated either way.

Share this post


Link to post
Share on other sites

I would be surprised if DX does not support arrays of samplers. I know in OpenGL this is supported, the only limitation is that you have to use static indexing to access the array, this may have changed in later version but its possible to have an array of 2D textures of different size and sample them in a shader.

Share this post


Link to post
Share on other sites

Correct, D3D11 allows you to have up to 128 unique textures in a shader, and it can be declared as an array of Texture2Ds, but requires static indexing. Alternatively, you can have a single texture binding declares as a Texture2DArray, which has all of the dimension restrictions we've been discussing.

 

D3D12 with SM5.1 enables the former, with an unlimited array size and dynamic indexing.

Share this post


Link to post
Share on other sites

This topic is 419 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this