read write buffer use in PixelShader and VertexShader: how to synchronize access

Started by
2 comments, last by Styves 6 years, 5 months ago

Hello,

until now i am using structured buffers in my vertexShader to calculate the morph offsets of my animated characters. And it works fine.

But until now i only read from this kind of buffers. ( i use 4 of them )

Now i had in mind to do other things, where i have to use a readwrite buffer that i can write to.

But i cant get in my head how to sync write acceses.

when i read  a value from the buffer at a adress that coresponds to e.g. a pixel coordinate and want to add a value  another thread could have read the same value overrides the value that i had written.

How is this done typically ?

 

 

 

 

Advertisement

I dont know the "official" way of doing it (as I am just a hobbyist), however I do it in several different ways depending on the situation:

1. From the pixel shader if you are writing to another texture you can use the standard depth stencil mechanics to ensure the closest "wins".

 

2. When writing to a RWStructuredBuffer from a compute shader, I make different threads write to different elements in the buffer. The easy way is to use the threadnumber as the element number. A slightly more complex way is to have a thread "grab" an element number by interlocked incrementing a counter and having that thread use the previous value of the counter.

 

3. From the pixel shader I send back to the cpu the object number of the object i clicked on.

Basically I need the closest texel at a certain screen position (eg where i clicked the mouse) write information to element one of a RWStructuredBuffer. After checking the pixel is at the correct position,  I construct a uint value where the high 16 bits are the depth ( ((uint)(input.Pos.z * 65535.0)) << 16 ) and the low 16 bits are my information eg my object number.

Then use the InterlockedMin function to send the uint value to the buffer. This causes the texel with the lowest depth to "win" which means it comes from the object which was closest to the camera at that point on the screen.

 

So in summary - you either write to different elements or use the interlocked functions to give you better control.

11 hours ago, evelyn4you said:

when i read  a value from the buffer at a adress that coresponds to e.g. a pixel coordinate and want to add a value  another thread could have read the same value overrides the value that i had written.

What you're describing is called a "race condition", where two threads race to write to the same memory. The normal approach to dealing with this is to avoid needing to do it at all or to use atomic functions (in D3D those would be Interlocked functions).

So if you just want to add values, just call InterlockedAdd(buffer, value, oldValue).

This topic is closed to new replies.

Advertisement