2

I am trying to implement a depth peel algorithm using integer textures for shader mutexes. As suggested in this question, I suspect one can use imageAtomicCompSwap(...).

Looking in the documentation for that function, and selecting the overload for an unsigned integer:

uint imageAtomicCompSwap(gimage2D image, ivec2 P, uint data);

However, it's unclear how this can be used. The documentation reads:

imageAtomicCompSwap atomically compares the value of data with that of the texel at coordinate P . . . . If the values are equal, data is stored into the texel, otherwise it is discarded. It returns the new value of the texel.

This sounds to me like the function compares the data to the already existing value in the texel. If the values are equal, effectively nothing happens ("data is stored into the texel", but they compared equal so there's no change). If the values are unequal, nothing happens ("otherwise it is discarded"). The function then returns the new value of the texel (which, because nothing happened either way, is just the original value of the texel to begin with). Clearly I am missing something.

Complicating matters, I also haven't been able to get this function to even show up. Writing:

//img2D_0 is declared "layout(r32ui) coherent restrict uniform uimage2D img2D_0"
imageAtomicCompSwap(img2D_0,coord,1u);

. . . gives:

0(14) : error C1115: unable to find compatible overloaded function "imageAtomicCompSwap(struct uimage2D1x32, ivec2, uint)"

It's worth mentioning that if I pass two numbers:

imageAtomicCompSwap(img2D_0,coord,1u,1u);

It compiles fine--I understand this should only work for multisampling, though; did I somehow declare a multisampled image? So, A: what does the documentation mean, B: why doesn't the function I need work? I'm confused.

Community
  • 1
  • 1
geometrian
  • 14,775
  • 10
  • 56
  • 132

1 Answers1

2

Looking in the documentation for that function

Man, those pages cause more problems than they solve...

In short, the docs are broken. The specification (ie: the docs that matter) states the function is defined as:

uint imageAtomicCompSwap(IMAGE_PARAMS, uint compare, uint data)

Where IMAGE_PARAMS are the image uniform and the texture coordinate appropriate to that image uniform. For a 1D image, it takes an image1D and an int; for a 2D image, it takes an image2D and an ivec2; etc.

It works by comparing the value in the image with compare. If they are equal, then data is stored at this location (swapped in); otherwise, no swapping is done. The return value will be whatever value is stored at this location before the conditional swap is done.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Note: I filed a bug report on this, but considering how terrible the ARB is at responding to bug reports, I wouldn't hold my breath. – Nicol Bolas Aug 04 '12 at 12:28
  • Thanks. I'm not sure how spinlocking would work. It seems to me like setting compare to 0 and data to 1 as you suggested would always return 1 (if the value in the texture is 0, you swap, returning the new value, 1; if the value in the texture is 1, you don't swap, returning the original value, 1)? – geometrian Aug 04 '12 at 12:37
  • 1
    According to the spec "Atomic memory operations read a value from the selected texel, compute a new value using one of the operations described below, write the new value to the selected texel, and return the original value read." -- NOT the value after the swap. See p155 – Chris Dodd Aug 04 '12 at 19:55