SSBO vs. Texture

Started by
1 comment, last by Kepakiano 11 years, 2 months ago

Hey there,

I am writing a fragment shader, which needs two float values with some additional information for every fragment it calculates. These values will be calculated at the beginning of the program and won't change any time, so they could be stored in a 2D or 1D lookup table/array.

My first two choices for this would be:

1. rendering the values in a separate fragment shader to a 2D GL_RG32F texture or

2. calculating the values in a compute shader and store them in a vec2 array in a shader storage buffer object (the size of table is not known at compile time!).

What is the best/fastest way to store them and look them up? Is there another fast method?

Thank you for your help.

Advertisement

There is a long term trend in GPUs for calculation to become faster relative to texture lookups and GPU programmers often use lookup tables unnecessarily as an optimisation technique (don't take my word for it http://diaryofagraphicsprogrammer.blogspot.co.uk/2011/07/no-look-up-tables-rules-for-designing.html).

Of course, it all depends on your exact situation, but are you sure that it is worth precalculating and storing the values at all rather than just calculating them on the fly per fragment?

I'm afraid that if you do store a lookup table, then I don't know which is the better option, my hunch would be a texture, but that's not much more than a guess.

needs two float values with some additional information for every fragment

If this means "two float values (and something else, blah blah)", then the best way is to compute the two values on the CPU and set them as uniforms. Use an UBO if you will.

If this means "two float values that depend on something else which varies for every fragment" then the best way remains a lookup texture, for two reasons: First, SSBO has functionality that you do not need (writeable, atomic ops, etc.). Second, SSBO is not yet widely supported (not everyone has latest-generation hardware!). Which means by using SSBO, you lock out potential customers for a reason that doesn't make sense to you.

Note that an uniform buffer object will (assuming it's not huge) likely be in dedicated read-only memory on some architectures (e.g. Kepler), which is equivalent to being permanently in L1 cache without using up L1 cache.

Thank you for your answers.

"Of course, it all depends on your exact situation, but are you sure that it is worth precalculating and storing the values at all rather than just calculating them on the fly per fragment?"

My 'boss' asked the same question :D

Okay, this is what I'm doing: http://pastebin.com/YXP6j9vN

Short description: "grid" defines a distorted 2D grid of points like this one:


(-1.0 1.0) (0.0 1.0) (1.0 1.0)
(-1.0 0.0) (-0.2 0.0) (1.0 0.0)
(-1.0 -1.0) (0.0 -1.0) (1.0 -1.0)

Note: These four quads are not enough, I need at least 16x16, maybe even 24x24 or 32x32.

So, for every fragment, I need to find out in which one of the quads the current fragment lies (lines 88 - 105, pretty naive implementation with linear complexity) by dividing the current quad into two triangles and calculating the point's barycentric coordinates in this triangle (lines 19 - 30). If the correct quad is found, the point will be bilinearly interpolated and the value will be returned.

The resulting vec2 is what I want to store for every fragment.

I'm pretty sure a texture/SSBO lookup would be faster than 1-16 (assuming I come up with a faster way to find the correct quad) point-in-triangle checks and one bilinear interpolation, but I have no experience in that matter. What do you think?

@samoth: The second is the case. I chose the SSBO, because of its ability to store arrays of arbitrary length, which would be nice. My target platform (a virtual reality lab) fully supports OpenGL 4.3 :) But you are probably right: The drawbacks outweigh the benefits compared to a texture.

The lab's projectors have a resolution of 1400x1050 pixels, so the buffer would need 1400*1050*8 Bytes (two floats per pixel) = 11,760,000 Bytes = 11.21 MiB of space which is probably too much for the L1 cache of a GTX 460 :/

So, (assuming I really precalculate) you think I should go for a texture?

This topic is closed to new replies.

Advertisement