4

Let's say I have nbFramesAnimation * 3 float4 Texture2D that I want to pass to my GPU, and:

  • I don't need to interpolate between the textures;
  • The textures have all the same size;
  • I don't know if it's relevant, but I don't have any mip-maps;

I use those textures as G-buffer on which I apply some post-effect. As such, I may have to access them with a non-literal expression for the index. Furthermore, because I use them as G-Buffers I have to load them very often. They give me positions and normals Infos, that need to be precise, and UV+IndexObject (so effectively only 3 out of the 4 floats are used).

As for now, at each frame render, I load the three textures individually with SetResource. It is very slow and far from real-time.

I wanted to know if:

  • It is more efficient to have an array of Texture2DArrays, each Texture2dArray having three textures (in my case), and to pass one Texture2DArray at each frame;
  • Or is it the same as passing 3 individual Texture2D ?;
  • Would it be more efficient to do several Texture2DArrays of nbFramesAnimation / X * 3 textures, and to load one of them each X frames?

I would also appreciate any insight on how I could further optimize this transfer.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Yauda
  • 159
  • 2
  • 10
  • 1
    A texture array might be faster than three individual textures, but it's highly unlikely this is your bottleneck, especially if the rest of your rendering is indeed "far from real time". If there is any difference, I would expect it to be on the order of a few microseconds per bind. Ultimately your best bet is to experiment with each option and profile to see if there is a difference. – MooseBoys Aug 29 '14 at 22:23

2 Answers2

8

Texture2DArrays were introduced to simplify the binding of multiple textures with a similar purpose that go together, but do not represent a whole like a volume (in other words, there is no need for trilinear interpolation). The depth indexing is used to access the different parts of the array.

Just like the notion of an array in C++ (or any other language under the sky), the intent is to allow dynamic indexing which is not possible with multiple separate ones. Performance considerations do not go beyond the cost of binding the elements to the pipeline, it's a matter of convenience and not hogging the bind points.

With DirectX 12, the last consideration has been removed, with the introduction of the bindless model and stuff like descriptor heaps where one can swap a metric ton of pretty much any resource around mapped to the shaders via precomputed root signatures. Further still with "infinite" descriptor ranges and dynamic indexing introduced with HLSL Shader Model 5.1. Fun stuff.

Anyways, don't worry too much about performance between the two. Worry about the elegance of your work. If stuff goes together and your design requires sampling all of them at some time, group them inside a Texture2DArray.

Elim Garak
  • 321
  • 1
  • 4
  • 9
  • "Anyways, don't worry too much about performance between the two." Do worry about performance if you are for example using reflection probes and would be binding reflections probes every time you render an object, instead of a whole array of reflection probes once for all objects. The overhead reduction is on the CPU side, not the GPU side. "Performance considerations do not go beyond the cost of binding the elements to the pipeline" which is exactly one of the most most expensive OpenGL operations and therefore can be a massive gain. – Tara Nov 10 '20 at 20:55
-2

In my experience Texture2DArray has a huge disadvantage - 30ms per frame vs 12ms without them. For VR it is very important. Just made some tests. Shaders are very similar but one uses texture2d, another - arrays (albedo + pbr maps in array of two DXT1 textures). Very bad. Why use them then?

Tertium
  • 6,049
  • 3
  • 30
  • 51
  • I don't think anyone is up voting. They're down voting. The reason likely being: Your answer neither states what your shader does nor what hardware you're targeting. I am experiencing massive CPU overhead reductions by switching to texture arrays. Your use case seems a bit esoteric though, since your arrays only seem to be two layers deep and likely change per object. The general idea of texture arrays is to bind them once and render all your objects by indexing the array. – Tara Nov 10 '20 at 20:49
  • switched to Unreal and changed the whole shader paradigm, so can't argue anymore – Tertium Nov 18 '20 at 00:03
  • Not sure what to do with that information. Feel free to delete your answer if you don't have confidence in it anymore. – Tara Nov 18 '20 at 11:23
  • If in your case it works, glad for you. Just have checked old project, nothing changed. Yes y I don't have 32 tex per shader. I remember I've spend a lot of time of making custom packer for texarrays and then rewrote all my shaders, but all in vain. I had to try them because the lack of texture samplers, but was experiencing this huge ovehead. So no, answer is still valid. I wanted to use one sampler per pbr set – Tertium Nov 18 '20 at 12:33
  • You are still providing almost no information about binding and sampling patterns, as well as what hardware and drivers you are running on. – Tara Nov 21 '20 at 04:46