Windows : VK_EXT_global_priority

Hello devs,

I am writing something that ressembles a XR compositor; using Vulkan to be cross-platform.
I had success using VkDisplay’s and and the platform specific AcquireDisplay to connect to my headset prototype.

However, I am now trying to bump the priority of my composition jobs using VK_EXT_global_priority.
While this works very well on linux once the executable was setcaped correctly, I struggle to give the rights to increase scheduling priorities on my application/exe on Windows.

I read on this page that the extension is available on windows when using Hardware Scheduling and that :

I run my app as an administrator user, and also tried to “Run as admin” but if I try to add the global queue priority pnext extension at device creation, device creation fails (with our without validation layers) :

validation layer RUNTIME: terminator_CreateDevice: Failed in ICD C:\Windows\System32\DriverStore\FileRepository\nvmii.inf_amd64_b32ce94116e244cf\.\nvoglv64.dll vkCreateDevicecall
validation layer RUNTIME: vkCreateDevice:  Failed to create device chain.

Questions :

  1. What is the correct way to enable SeIncreaseBasePriorityPrivilege for my built exe and have the driver accept to bump the priority of my queues ?

  2. My composition jobs only consists of compute pipelines, should I choose the Compute Only queue family or graphics family ? Would I gain more “asyncness” using Compute Only ?

  3. My compositor can act both In-Process or Out-of-Process. When operating in process (as a thread in the application process), will the global-priority extension work for only the (application-hidden) compositor vulkan instance on which I enable the extension ?

Thanks in advance,

Greg

Hello Greg,

Sorry it took a while to get a response here. Since your question is Vulkan related I will reach out to some experts who might be able to help and give advice to your questions.

You could also consider moving this topic to the Vulkan forums, but I leave that to you.

Thanks a lot for you answer. For the record : In the meantime I figured out a programatic way to acquire privilege for the processs, (given the running user has them).

  BOOL SetPrivilege(
      HANDLE hToken,          // access token handle
      LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
      BOOL bEnablePrivilege   // to enable or disable privilege
      )
  {
      TOKEN_PRIVILEGES tp;
      LUID luid;

      if ( !LookupPrivilegeValue(
              NULL,            // lookup privilege on local system
              lpszPrivilege,   // privilege to lookup
              &luid ) )        // receives LUID of privilege
      {
          //printf("LookupPrivilegeValue error: %u\n", GetLastError() );
          return FALSE;
      }

      tp.PrivilegeCount = 1;
      tp.Privileges[0].Luid = luid;
      if (bEnablePrivilege)
          tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      else
          tp.Privileges[0].Attributes = 0;

      // Enable the privilege or disable all privileges.

      if ( !AdjustTokenPrivileges(
             hToken,
             FALSE,
             &tp,
             sizeof(TOKEN_PRIVILEGES),
             (PTOKEN_PRIVILEGES) NULL,
             (PDWORD) NULL) )
      {
            //printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
            return FALSE;
      }

      if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

      {
            //printf("The token does not have the specified privilege. \n");
            return FALSE;
      }

      return TRUE;
  }

  bool setupRTPrivileges(){
    HANDLE process = GetCurrentProcess();
    HANDLE token;
    if(!OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES, &token)){
      return false;
    }

    auto ret = SetPrivilege(token, SE_INC_BASE_PRIORITY_NAME, TRUE);
    CloseHandle(process);
    CloseHandle(token);
    return ret;
  }

I still wonder if there isn’t a cleaner way using some app manifest or something.
The other questions about vulkan async can wait for someone to notice me here.

Greg

Hello Greg,
Yes, that is the correct way to set the SeIncreaseBasePriorityPrivilege. Only a process that is running as an administrator will be able to grant itself this privilege and the privilege is needed to achieve scheduling priorities greater than “medium”.

Regarding 2: A compute only queue executes asynchronously with the work on a graphics queue. If there is no graphics workload in your application, there isn’t any significant advantage of using one type of queue over the other.

Regarding 3: If the compositor is in process, you would need to require the user to launch the application as an administrator. And when you grant the SeIncreaseBasePriorityPrivilege to the process, any Vulkan Instance on the process will be able to request increased global priorities. This is probably not a good idea.

Hope this helps,
Kedar.

Hello,

Thank you a lot for your responses.
If I still have you at hand I have few more details I’d like to know about :

For 2 : I am interested in knowing if having realtime priority (and be out of process) would allow my compute jobs to preempt the application workloads (say it is a XR app that fail to deliver the frames on time because it is GPU-bound). What would be the best configuration to permit the compositor to still compose previous frame (with new tracking / warping data) on time ? My compositor render loop is deciding to pick new or previous frame submitted by application based on VkFences that I just peek on.
I then quickly record a very short command buffer containing a wait for a “late latch” event (for my tracking data uniforms). I obtain good results there as long as client application is CPU-bound but it starts to fell apart if the app swallows GPU time.
What would be the right way to achieve something closest to preemptive composition in vulkan ?

For 3 : Yes out-of-process composition is the default. In-process is reserved for specific uses so it should be ok.

Best,
Greg