2

In glBindImageTexture(), access can be GL_READ_ONLY, GL_WRITE_ONLY, or GL_READ_WRITE. I assume that these should match the readonly and writeonly qualifiers on image units (eg. image2D or imageBuffer) in GLSL.

I haven't noticed any difference when setting readonly or writeonly (2013, NVIDIA 319.49 drivers). Granted, I might not be doing anything that would otherwise cause a slowdown and hence don't see any improvement. These qualifiers may also simply be ignored by current GL implementations.

  • In what cases could a GL implementation make use of readonly/writeonly, why do they exist?

Cache coherency comes to mind, but don't the coherent/volatile qualifiers cover this already? I've used these and they appear to work.

  • Has anyone experienced a difference in performance or results when using readonly/writeonly, how important are they?

Don't be afraid to reply if it's been years, I'm interested to know and I'm sure others are too.

jozxyqk
  • 16,424
  • 12
  • 91
  • 180

2 Answers2

2

It only tells a hint to the driver of how the memory is supposed to be used. It's up to the driver to do optimizations or not. I have not seen any difference on NVidia drivers. One thing is certain, if you write in a read only image, the result is undefined. Same for reading a write only image. But even if it does not make a difference on today's drivers, you should still use them coherently with what you are actually doing with these images: future drivers may use these hints to optimize the memory access.

  • 1
    Yes, but I'm more interested in what the driver might do with this information. I don't like the idea of using a feature without knowing. A little related, `restrict` was not implemented and now it's a handy keyword to [crash](http://www.opengl.org/discussion_boards/showthread.php/179751-NVIDIA-310-*-crashes-when-compiling-GLSL-using-restrict-keyword-on-image-unit) your app. – jozxyqk Oct 29 '13 at 15:48
  • @jozxyqk : I was about to answer then I read the comment Andon wrote in his answer : "If you can guarantee that a particular buffer will never be written to, you can make more aggressive optimizations that might otherwise create Read-After-Write data hazards.". That is, if you write to an image then read it, you have to wait for the OpenGL queue to be empty before making any coherent reading. Now if you tell the driver that you won't write anything in the image, the driver can skip any synchronization it might do to prevent you to read partially written images. – Jean-Simon Brochu Oct 30 '13 at 12:41
2

See, the thing is there is no actual enforcement of these access policies. OpenGL intentionally leaves the behavior of writing to a read-only image undefined for reasons that will be explained below. Among other things, this allows a lot of flexibility on the end of the implementation to use the read-only attribute for a number of different optimization strategies (think of it more like a hint than a strict rule). Because the behavior is undefined, you are right, they could be ignored by the implementation, but should not be ignored by the application developer. Invoking undefined behavior is a ticking time bomb.

To that end, there exists no mechanism in GLSL (or shaders in general) to emit an error when you try to store something in a read-only image, making enforcing this policy significantly more difficult. The best you could hope for is some kind of static analysis at compile-time that is later verified against the access policies of the bound image texture at runtime. That is not to say it may not happen in the future, but at present no such feature exists. The only thing that GLSL provides is a compile-time guarantee that readonly variables cannot be used in conjunction with imageStore (...) in the shader. In short, the GLSL qualifier is enforced at compile-time, but the access policy of the bound image is not at run-time.

The fact that you are not seeing any performance improvement is not surprising. This is a pretty new feature, you will have to give it years before drivers do anything profound with the access policy. It does not hurt anything to provide the hint, so long as you yourself do not violate it.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Thanks for the response! I'm not incorrectly using these qualifiers, I was purely interested in the possibility of enabling optimizations. In particular, interested what these optimizations might be (how would they differ from the cache control gained with `coherent`/`volatile`). I'm sure someone had something in mind for an optimization when including these in the specs. – jozxyqk Oct 30 '13 at 08:27
  • @jozxyqk: Ah, I was focused on addressing the first part of your question and the only non-implementation specific part. As for what sort of optimizations might occur, think of instruction-level scheduling (which is a huge part of GPU shader optimization, keeping the scalar ALUs fully utilized). If you can guarantee that a particular buffer will never be written to, you can make more aggressive optimizations that might otherwise create Read-After-Write data hazards. Effectively, the qualifier in your GLSL shader is the determining factor for these sorts of optimizations being applied. – Andon M. Coleman Oct 30 '13 at 12:10
  • OK, I think I kind of get where this is going. However, currently I believe there are no guarantees that a read after a write on an image unit will actually return the thing written anyway, and I assume vice-versa. Unless of course `coherent` is specified. Also in GL we don't know which other threads are being executed in the same SM/SMX (sorry, I don't know the correct non-CUDA terminology here), so it doesn't make much difference if operation order is guaranteed within the SM/SMX or not. What conditions are left to be relaxed? – jozxyqk Oct 30 '13 at 13:01