0
\$\begingroup\$

I've been developing a game targeted at android. I know not to think about program optimization until the project is finished, but I have to wonder how many textures most phones can handle safely without melting or murdering battery. I've seen that the max SIZE of a texture should be 1024 or 2048 pixels squared (I've been combining sprite-sheets into 1024x1024 atlas's) but I can't help but wonder if there is a limit to how many of these I can use at runtime. I understand it should depend on the GPU but what spec determines it?

\$\endgroup\$
  • \$\begingroup\$ You're only limited by memory as far as I'm aware. \$\endgroup\$ – Luke Briggs Nov 20 '16 at 3:37
  • \$\begingroup\$ GPU or RAM memory? \$\endgroup\$ – Codiush Nov 20 '16 at 3:38
  • \$\begingroup\$ On mobile devices, it'll almost always be the RAM size - VRAM is included in system memory. Wherever it isn't included in RAM, it doesn't particularly matter as it'll be a high end device with dedicated VRAM (and lots of it). \$\endgroup\$ – Luke Briggs Nov 20 '16 at 3:43
  • \$\begingroup\$ Typical source of confusion are texture units which are something else entirely. I'd be happy to add this as an answer if that would help. \$\endgroup\$ – Luke Briggs Nov 20 '16 at 3:45
  • \$\begingroup\$ please do. So I should be able to load several 1080x1080 textures at once without a problem, assuming there's adequate memory? \$\endgroup\$ – Codiush Nov 20 '16 at 3:47
0
\$\begingroup\$

The only limit on texture count is memory

The vast majority of mobile devices (and desktops with integrated graphics rather than a dedicated graphics card) use a shared memory architecture where VRAM - that's RAM reserved for video - is part of system RAM. Textures used by graphics APIs are simply pointers to a block of VRAM; there's no artificial limits imposed by the APIs themselves.

A typical source of confusion here is there's a very limited number of texture units. These are circuits in the GPU hardware which can 'bind' to a particular texture and perform the sampling for us. Importantly though, the limit only applies to a single shader. In effect if a system has, for example, 32 texture units, then a single shader can use at most 32 textures simultaneously. Note that there is also another similar limit that affects how many textures a particular stage of the shader can use simultaneously (the textures per stage limit).

Quick aside note: A simple way to improve memory usage is to use texture compression. Most mobiles support some form of texture compression nowadays and many engines enable it by default (those texture units can sample straight from compressed data).

Texture size

Those texture units are dedicated pieces of hardware and as a result are physically restricted on the size of textures they can deal with. The circuits that perform sampling are designed to operate on images with a power-of-2 size. This is why devices have limited texture sizes, ranging from around 512 up, and they're always a power of 2. 1080 is an awkward size for an atlas as it's not a power of 2 (so the hardware might decide to upscale it all the way to 2048).

\$\endgroup\$
0
\$\begingroup\$

The limit depends on:

  • the phone's memory bandwidth
  • the GPU's cache size
  • how large (in bytes) the textures are
  • the phone's memory size accessible to the GPU
  • how much of the texture you're using per frame
  • what mipmap level is being used (if any)
  • how well ordered your draw calls are so the GPU cache can work effectively
  • how much opaque draws you have vs blend or alpha test (hidden surface removal)
  • what the screen resolution is
  • how complex the shaders are (bottlenecks?)
  • how busy the CPU is

It's not a question of how many. It's not a question of how large. It's a question of all those factors combined.

You could have 4000 16x16 textures displayed and a phone could probably handle that faster than four 1024x1024 textures drawn over the screen.

Both CPU and GPU share the same memory bus on most mobile platforms which means if one is using the bus to read or write memory the other has to wait it's turn.

So you can run a test and see that the GPU is fine drawing N triangles with AxB textures at a certain frame rate, and run a test for CPU speed, but when you combine both GPU (drawing) and CPU processing (audio, loading/decompression, physics, particles & 3D model animations) suddenly the GPU performance drops. Or it could be the other way around where the GPU has priority over the CPU to access memory, or a mix of both depending on the system.

GPU and CPU usually run in parallel but they still have to "fight" over memory access on a shared memory system.

\$\endgroup\$
  • \$\begingroup\$ The GPU cache generally contains shader code rather than textures so it doesn't come in here. It's worth mentioning that most of the above are performance based limitations rather than a hard limit. E.g. even if it has low bandwidth, you can still max out the VRAM's capacity with textures. \$\endgroup\$ – Luke Briggs Nov 20 '16 at 4:38
  • \$\begingroup\$ Also "4000 textures ..could probably handle that faster" is false; it would require lots of draw calls (+lots of bus stalls) as it would have to keep reusing the texture units. \$\endgroup\$ – Luke Briggs Nov 20 '16 at 4:42
  • \$\begingroup\$ The GPU cache contains both textures and shader code.It needs to have texture cached to handle compressed textures. Mobile GPUs use tiled rendering which means the GPU first does hidden surface removal then process all the individual pixels. Every pixel in a tile having their own attributes, shader and texture pointer, and can end up having a different texture on every pixel. Before this happens every triangle is put in their tile bucket, often by the CPU itself. There's no "bus stalls" like on desktop. While the GPU renders the previous frame the CPU builds the next complete tile bucket list \$\endgroup\$ – Stephane Hockenhull Nov 20 '16 at 14:14
  • \$\begingroup\$ You've referenced bus stalls in your answer ("wait it's turn"); Lots of individual images from main memory => lots of waiting. Tiled rendering doesn't come in either, as the GPU still has to bind its texture units, and it only has a small number of those (no way near 4000). \$\endgroup\$ – Luke Briggs Nov 20 '16 at 18:46
  • \$\begingroup\$ I'm talking about the total number of textures used, not simultaneously bound textures. \$\endgroup\$ – Stephane Hockenhull Nov 20 '16 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.