Jump to content
  • Advertisement
Sign in to follow this  
Shigeo.K

D3d12 fence value

This topic is 675 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
Advertisement

OK, thanks.

But from where did you find the information?

I think there is no clear information about this in the document.

Share this post


Link to post
Share on other sites

If I'm not mistaken Jesse Natalie works for MS and might have access to information not publicly available.

 

@[member='Jesse Natalie'],  Was wondering whether fences exist in CPU or GPU memory? 

Share this post


Link to post
Share on other sites

It's located in system memory, but at the end of the day, does it really matter? As long as writes and reads are coherent between the two, its location should be irrelevant.

Share this post


Link to post
Share on other sites

All is clear now.

As you guys say, where the value lies does not matter.

However, It's better to know than not to know.

In fact it indeed helped me understand.

 

Thank you Jesse and Infinisearch.

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!