So, I have come to the point with my engine where most of the infrastructure is in place
and I can slowly start looking at actual performance. Only now did I notice how big the gap
in time needed is between allocating normal and render textures (I am using render textures
all over the place, so this
really shows).
As a first step, I let
this code run to get some first numbers. Here are my results on
my laptop's "Mobility Radeon HD 3650" (all times in microseconds):
Creating 4 512x512 RENDER textures
0 : 348745
1 : 74412
2 : 77889
3 : 73580
Freeing took: 45563
Creating 4 512x512 textures
0 : 174984
1 : 17
2 : 17
3 : 16
Freeing took: 12156
Creating 4 512x512 textures AND render textures, interleaved
tex 0 : 171275
rtex 0 : 75883
tex 1 : 52
rtex 1 : 79667
tex 2 : 51
rtex 2 : 73639
tex 3 : 49
rtex 3 : 76513
Freeing took: 40397
Creating 4 512x512 textures with immediate free
0 : 173745
1 : 170852
2 : 170081
3 : 167905
Uploading 512x512 image data 4 times
0 : 3977
1 : 741
2 : 681
3 : 464
Downloading 512x512 image data 4 times
0 : 6717
1 : 2428
2 : 2327
3 : 2374
This showed me a couple things, namely:
- When allocating normal textures in series, all allocations after the first one are very fast
- Allocating render textures in series bears no speedup
- Allocating render textures in between normal texture allocation doesn't reset the speedup
- However, freeing normal textures seems to reset the speedup
- Using an image/texture pair over a render texture
(ie. render locally and upload on each update) is actually viable
The reason I say image+texture might be viable is because the upload times aren't big enough
to cause frame drops if only a handful are being updated each frame (at 40-60 FPS), while the render texture
would induce a massive frame drop on creation, something that image+texture wouldn't suffer from (I think).
Still there are parts where I absolutely need render textures.
Due to the high cost of render textures, and the convenient fact that although they will be
allocated and freed pretty often, the allocations mostly happen with the same repeated sizes
(ie. same sized render texture will be requested repeatedly) in my engine, I decided to implement
a sort of render texture cache/pool mechanism where an x amount of last "released" render textures
are retained for reuse by the next call that requests an rtexture with the same size.
So now a couple questions both in relation to normal and render textures arise,
as I have had no previous experience with graphics
programming prior to SFML (except software vector graphics with cairo/Qt),
and am therefore pretty oblivious to the intrinsic parts of openGL:
- What are other "speedup blockers" that I should be aware of, which slow down texture allocation?
- Are the numbers I am getting actually valid (ie. when the texture 'create()' call returns,
has it really been created), or is there some "command buffer" that only gets flushed on certain events (eg. first access)? - Regarding VRAM, how big is the memory usage of normal and render textures?
How many would approximately fit into, let's say, 256MB? - Is memory usage of textures directly proportional to their pixel count?
Ie., is the space a 200x200 texture occupies in VRAM exactly 4 times the amount a 100x100 texture uses?
And how about render textures?
Those last questions are important to me so I can make an estimate on how many render textures
to pool.
Thanks! ^^