PacktPublishing / Vulkan-Cookbook

Code repository for Vulkan Cookbook by Packt
MIT License
816 stars 109 forks source link

Some confused about:18 Creating a logical device with geometry shaders and graphics queue #7

Closed xwc2021 closed 6 years ago

xwc2021 commented 6 years ago

There is a picture in 1.15 (Vulkan-Cookbook). It illustrates that one queue family may has several queues .

So why we can confirm these 2 queue family both have only one queue ? GetDeviceQueue( logical_device, graphics_queue_family_index, 0, graphics_queue ); GetDeviceQueue( logical_device, compute_queue_family_index, 0, compute_queue );

Ekzuzy commented 6 years ago

When we create a logical device, we specify how many queues we want to use and from which families they should be created. We can specify many queues from many families.

In the example about create a logical device with geometry shaders and graphics and compute queues we want to use one queue that supports graphics operations and one queue that supports compute operations. We check which queue family supports graphics operations and if it has at least one queue. We do the same for a family that supports compute operations. Next we create a logical device and specify that we need one queue from a family that supports graphics operations. We also need one queue for compute operations. But if the same family supports compute operations, we are done here. If not, we specify additional queue from additional family.

After logical device is created, we need to get handles of both queues (queues from both families). We requested one queue from both families so we can get them. Maybe there are more queues in these families, we don't know. But we can't get more queues because during logical device creation we specified that we need only one queue from each family. What's more - if queue families that support graphics and compute operations are different, we will get two different handles. But if they are the same, we will get the same handle in both function calls.

I hope this answers Your question. ;-)

xwc2021 commented 6 years ago

Thanks for your help ! But I still do not fully understand.

"if queue families that support graphics and compute operations are different, we will get two different handles. But if they are the same, we will get the same handle in both function calls." Is this meaning that the command we submit will dispatch to the correct queue behinds queue family automatically,instead of specifying a sub-index referring to the queue manually?

Ekzuzy commented 6 years ago

Is this meaning that the command we submit will dispatch to the correct queue behinds queue family automatically

No. In Vulkan there nothing is done automatically or implicitly. If You want to submit work, it is Your responsibility to submit it to a proper queue. If You have more queues from a single family, all of them are independent (have distinct handles) and You select which queue the job should be executed on.

What's more - command buffers are allocated from command pools. When You create a command pool, You specify queue family index given pool is associated with. So if You allocate command buffers from that pool, You can submit them only to queues from the associated family.

xwc2021 commented 6 years ago

If in the situation "graphics_queue_family_index" is equal to "compute_queue_family_index", it is meaning that we use the same queue family. Is it ?

Then after call GetDeviceQueue( logical_device, graphics_queue_family_index, 0, graphics_queue ); GetDeviceQueue( logical_device, compute_queue_family_index, 0, compute_queue );

Because They use the same "family_index" and the same "queue_index" to retrive queue,so Is "graphics_queue" the same as "compute_queue" ?

Ekzuzy commented 6 years ago

First: Queue families are identified by their indices. Different indices mean different families. So when graphics_queue_family_index == compute_queue_family_index then we use the same family. Yes.

Second: after the following calls

GetDeviceQueue( logical_device, graphics_queue_family_index, 0, graphics_queue );
GetDeviceQueue( logical_device, compute_queue_family_index, 0, compute_queue );

if graphics_queue_family_index == compute_queue_family_index then graphics_queue and compute_queue handles will also be the same because we acquire queue of the same index from the same family.

xwc2021 commented 6 years ago

graphics_queue and compute_queue "handles" are the same.

Is it referring that graphics queue and compute_queue are using the same queue on this family?

sorry for my poor English , I draw My question below. picture

xwc2021 commented 6 years ago

I know I am wrong in what point. I misunderstood the meaning of the image. When flag of the queue family has capacity of doing graphic operation and compute operation, It means that each queue within the queue family can execute both 2 opration. Is it right ? 😅

xwc2021 commented 6 years ago

Previously I think "G+C+T" means that there are 3 queue in this family ,first queue can put "G" command ,2nd queue can put "C" command, 3rd queue can put "T" command .

Ekzuzy commented 6 years ago

Yup, now You got it right ;-). Queue family exposes set of capabilities. And all queues from a given family must support all the operations given family exposes. So if there are 3 queues in a family that supports G+C+T, then all of these queues must also support G+C+T.

Vulkan specification requires all vendors to support at least one general queue family with at least one queue. This family must support G+C+T. Intel has only one family with one queue. AMD for example, with their async compute, exposes additional family with C+T support. Nvidia has more queues as far as I know.

And don't forget that image presentation (when You want to create a swapchain and display images on screen) is also a property of a queue family.

xwc2021 commented 6 years ago

Thank for giving more detail.I know deeperly now.