Sign in to follow this  

D3d12 fence value

This topic is 366 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a question.

As for Direcdt3d12,

1.  do CPU and GPU have their own Fence value respectively?

2.  Or, only one fence value is exists in the system, CPU and GPU share that same value?

3.  Or, does only GPU have the Fence value?

Which one is correct? (or none of them are correct?)

 

1      CPU                                           GPU

          |                                                  |

 cpu fence value                       gpu fence value        can be different.

 

ID3D12Fence::Signal() changes 'cpu fence value' while  ID3D12CommandQueue::Signal() changes 'qpu fence value'?

 

2      CPU                                                     GPU

            \---------->  fence value  <---------------/           can't be different.

This doesn't make sense..I realize while writing this...

 

 

3      CPU                                   GPU

            \------------------>      gpu fence vaue            can't be different.

 

This doesn't make sense..I realize while writing this...

 

application can copy and hold the fence value in the own memory,I don't mean those copy. I mean the fence values in the Inside of D3d12 system is only 1?  Or there are 2 fence value for CPU and GPU?

Share this post


Link to post
Share on other sites

A fence is accessible by both CPU and GPU.

 

Scenario 1 -- GPU produces and CPU consumes

 

1. ID3D12CommandQueue::Signal inserts a command into the queue. This command will be executed by the GPU command processor LATER (in order, with other (draw) commands) and at that point, GPU will change the fence value.

2. CPU will use ID3D12Fence::GetCompletedValue (it returns immediately the current value) + busy waiting or SetEventOnCompletion.

This is good for reclaiming/reusing/recycling/destroying resources used by the GPU. Once GPU actually signals, CPU can be sure that GPU is done with what it's been doing and can do whatever with the resources.

 

Scenario 2 -- CPU produces and GPU consumes

 

1. ID3D12CommandQueue::Wait inserts a command to into the queue. This command will be later executed by GPU and will cause its command processor to stall (and not launch any draws/dispatches) until the fence has the specified value.

2. ID3D12Fence::Signal immediately sets the fence value from the CPU and 'unblocks' the GPU.

This is might be good for async loading of stuff - GPU is running on its own, CPU is producing stuff. The wait ensures that GPU won't run ahead of CPU.

 

I agree, that the docs aren't very clear :)

Edited by pcmaster

Share this post


Link to post
Share on other sites

Also just want to mention so it's clear. Even though the fence is one value, you have to explicitly get the value and compare the value you got from the gpu with what you expected to get. So actually there's sort of at least two (ore more) fence values, one that the gpu has and one  that the cpu expects the GPU to have at a certain point (Scenario 1 in pcmaster's post). So even though there's really only one fence value, there can be more values that go into dealing with the fence.

UINT64 fenceValue;  // cpu side fence value to compare gpu fence value with

ID3D12Fence* fence; // actual fence

HANDLE fenceEvent;  // a handle to an event the gpu will signal when it sets the fence
                    // to what we expect

// compare the current value of the fence on the gpu with what you expect. If the value is greater than or equal to what
// you expect, you know it has finished everything up to that point. Otherwise you can block your thread until the gpu
// does finish with what you need (You don't HAVE to block, maybe you can do something else while your waiting)
if (fence->GetCompletedValue() < fenceValue)
{
    // The gpu has not yet finished what you expected it to be done with
    // have the gpu send an event when it finishes what you expect it to
    // (in which case it will set the fence value to what you expect)
    fence->SetEventOnCompletion(fenceValue, fenceEvent);

    // wait for the event to be signaled
    // this will block until the gpu sets it's fence value to what you gave to SetEventOnCompletion
    WaitForSingleObject(fenceEvent, INFINITE);
}

fenceValue++; // increment fence value for next time

There's more to that of course, error checking and setting up

 

You may already know how to use a fence, but i thought this might help

Edited by iedoc

Share this post


Link to post
Share on other sites

I would like to bounce of the discussion in regards to the original first question "do the gpu and cpu have their own fence value ?", because the answer is : "we do not know". We can only trust the Fence interface has defined by d3d12, providing a service to synchronize cpu and gpu, but nothing here explain or enforce a specific implementation. By concept, CPU and GPU share the fence to communicate, in practice, as long as the implementation follow the behavior, it can do many things under the hood, and not having a shared a single memory address visible from both xPU is possible. 

Share this post


Link to post
Share on other sites

Agreed. I guess the original answer should've been phrased "the fence behaves as though there is a single value." The actual implementation may or may not have more, as long as the appearance of one is maintained, since that's the the behavior this interface exposes.

Share this post


Link to post
Share on other sites

This topic is 366 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this