vkd3d-proton icon indicating copy to clipboard operation
vkd3d-proton copied to clipboard

[WIP] Add VKD3D profiles to express vulkan requirements

Open christophe-lunarg opened this issue 1 year ago • 4 comments

I created a Vulkan profiles JSON file to express VKD3D minimum requirements for each D3D level. This JSON files are defined by Vulkan Profiles schemas avaiable here and can be used as part of the Vulkan SDK Profiles Toolset. (PDF, Presentation)

I based myself on the repository source code as the main page requirements seem pretty sparsed.

This is an equivalent work from what we did for DXVK with this PR: https://github.com/doitsujin/dxvk/pull/2826

This PR is really for discussion purposes at this point so that I understand if you would be interested in such idea and the direction you would like it to take.

A couple of caveats :

  • I had to create a new construct to express a "OR" of capability checks which I still need to . This is something we were pushing to avoid in the profiles concept because depending who produces and consumes a profile it can make things very hard for Vulkan application developers: "How to know what APIs to use when a profile is reported supported on a platform but has multiple variants to claim it reported?" The issue doesn't happen here because because it's VKD3D that creates the VkDevice instance.

Eg:

            "capabilities": [
                "vulkan10requirements",
                "vulkan11requirements",
                "d3d12_level_11_0",
                ["d3d12_level_11_0_bindless_uniform", "d3d12_level_11_0_bindless_storage"]
            ]

Means VP_VKD3D_d3d12_level_11_0_baseline requires "vulkan10requirements" AND "vulkan11requirements" AND "d3d12_level_11_0" AND ("d3d12_level_11_0_bindless_uniform" OR "d3d12_level_11_0_bindless_storage")

  • VKD3D is a LOT more complex with capabilities checking than DXVK, at least partly due to D3D12 handling of features compared with D3D11. I am not quite sure it's really tracktable...
  • I only created "baseline" profiles and no "optimal", "exhaustive" or "max" because it looks like VKD3D enables a lot of things my default based on the user system Vulkan capabilities and explicitly disable things it doesn't want (we can express disabled features actually). So it's not obvious to figure out what's actually used or not, I would have to do a very long investigation.

Looking forward your inputs!

christophe-lunarg avatar Sep 01 '22 17:09 christophe-lunarg

VKD3D is a LOT more complex with capabilities checking than DXVK, at least partly due to D3D12 handling of features compared with D3D11. I am not quite sure it's really tracktable...

I think the main problem here is that we need multiple code paths to implement various features, and therefore end up doing different things based on the driver we're running on, primarily because D3D12 has requirements that Vulkan drivers don't necessaril fulfill. D3D12 is also a moving target, so optional features that we'll use will constantly change (see mesh shaders).

I'm also expecting that we move to Vulkan 1.3 in the near-ish future to clean up the whole extension mess a bit and hard-require some features that are semi-optional right now (esp. BDA), so I'm not sure how useful it is to do the whole profile thing right now. Maybe we should gather baseline requirements for Feature Level 12_0 (in practice this is what new D3D12 games require to run at all) and start from there - "optimal" profiles are probably not useful here at all since we'll basically take what we can get, and vendor support for some features, especially regarding the binding model (i.e. descriptor indexing properties etc), is unlikely to converge. There are some fairly major differences even on the Windows D3D12 side of things.

doitsujin avatar Sep 03 '22 11:09 doitsujin

Hi, It's ok with me regarding :

  • Waiting for the Vulkan 1.3 requirement bump.
  • Starting with baseline level 12_0. This said, I think exposing level 11_0 is pretty trivial
  • Only creating baseline profiles.

Thanks for you feedback !

christophe-lunarg avatar Sep 08 '22 14:09 christophe-lunarg

Where would this profile be hosted? Is it intended that it's pulled automatically from our repo?

HansKristian-Work avatar Sep 08 '22 15:09 HansKristian-Work

Hi @HansKristian-Work ! This profiles file would be hosted in this repository and kept in sync with VKD3D implementation. Unless you have another suggestion?

christophe-lunarg avatar Sep 13 '22 15:09 christophe-lunarg

Hi, any update on this MR? I'm asking because having a checked-in, maintained profile file would simplify the task of gathering Vulkan requirements for Chrome OS. (I'm Chad Versace in Khronos).

versalinyaa avatar Jan 31 '23 23:01 versalinyaa

I haven't seen any which to Vulkan 1.3 at the moment. Should we more forward with Vulkan 1.1 + extensions?

christophe-lunarg avatar Feb 07 '23 11:02 christophe-lunarg

@christophe-lunarg Things have been hectic and this never bubbled up. @doitsujin I suppose we should just do the transition to 1.3 now?

HansKristian-Work avatar Feb 07 '23 12:02 HansKristian-Work

Yeah, we should be able to do this now without too many problems.

doitsujin avatar Feb 23 '23 15:02 doitsujin

Great! I'll be happy to follow this and work on profiles proposals. :)

christophe-lunarg avatar Feb 24 '23 10:02 christophe-lunarg

Vulkan 1.3 cleanup has been merged now.

HansKristian-Work avatar Mar 06 '23 13:03 HansKristian-Work

I started to update the file, you should have something soon!

christophe-lunarg avatar Mar 06 '23 16:03 christophe-lunarg

Some overall comments:

  • Which strategies do we have available to ensure the JSON is correct?
    • I can see the profiles layer which we could use to restrict a driver to 11.0/11.1/12.0/12.1 feature sets. We could then test D3D12CreateDevice with those feature levels and verify the device is created successfully.
    • Is there a JSON validator to ensure the syntax is correct? Given there is a schema linked, I suppose a general purpose validator would do?
    • Is there a way to inspect and load a profile in some tool and see what a given ICD supports and does not support? Just to ensure that relevant drivers report the feature sets that are expected.
    • Running against validation should ensure that we've enumerated relevant features if we use the profiles layer. Is there a way to ensure that we don't enable too much in the profile by accident? I can imagine if there is a way to dump a profile JSON based on our vkCreateDevice calls, and then compare that somehow to the profile JSON would help. It should be possible to observe any features that we have not accounted for.

Fixing all issues that comes up will likely take 20+ roundtrips to sort out all micro details, so finding a way to hand this over seems like a good idea.

HansKristian-Work avatar Mar 20 '23 15:03 HansKristian-Work

Some overall comments:

  • Which strategies do we have available to ensure the JSON is correct?

    • I can see the profiles layer which we could use to restrict a driver to 11.0/11.1/12.0/12.1 feature sets. We could then test D3D12CreateDevice with those feature levels and verify the device is created successfully.

Yes, that's exactly the idea with the Profiles layer, running together with the validation layer to get error reports for Vulkan capabilities infringement.

  • Is there a JSON validator to ensure the syntax is correct? Given there is a schema linked, I suppose a general purpose validator would do?

Yes, I am using the Profiles schemas here https://schema.khronos.org/vulkan/ that we (LunarG) keep updating for each Vulkan Header revisions. It's validated with any generic JSON schema validator. I am using this one online https://www.jsonschemavalidator.net/ and https://github.com/tristanpenman/valijson in C++ typically.

  • Is there a way to inspect and load a profile in some tool and see what a given ICD supports and does not support? Just to ensure that relevant drivers report the feature sets that are expected.

You can use vulkaninfo JSON export or Vulkan Hardware Capability Viewer and download a device profile JSON file on each reports: https://vulkan.gpuinfo.org/displayreport.php?id=19738

  • Running against validation should ensure that we've enumerated relevant features if we use the profiles layer. Is there a way to ensure that we don't enable too much in the profile by accident? I can imagine if there is a way to dump a profile JSON based on our vkCreateDevice calls, and then compare that somehow to the profile JSON would help. It should be possible to observe any features that we have not accounted for.

Unfortunately, we don't have a script at the moment to check if all the capabilities in one profile is present in another profile. I agree this could be useful.

Fixing all issues that comes up will likely take 20+ roundtrips to sort out all micro details, so finding a way to hand this over seems like a good idea.

I agree, digging into VKD3D-Proton to really understand the feature requirements is not trivial. Part of the way capabilities are handle is by considering the features are available by default and disabling features the project is not using. I am happy to hand this over and review changes to ensure things remain correct or to resolve specific issues.

christophe-lunarg avatar Mar 20 '23 16:03 christophe-lunarg

You can use vulkaninfo JSON export or Vulkan Hardware Capability Viewer and download a device profile JSON file on each reports: https://vulkan.gpuinfo.org/displayreport.php?id=19738

I think I need the opposite thing here kind of? For example, if a profile declares various tiers, I should be able to do something like get a report for every feature level and see if it's supported or not, and if not supported, which features are missing to make it supported.

I assume this is a normal use case for an IHV going "do I support the profile this app declares, what are we missing?"

Maybe some intersection tool would work here? Profile JSON and Profile JSON from a device/vulkaninfo could be analyzed.

HansKristian-Work avatar Mar 20 '23 17:03 HansKristian-Work

Vulkan Hardware Capability Viewer but also IHVs typically used the Vulkan Profiles API library (C++) for this use case.

This is how this table is populated: https://vulkan.gpuinfo.org/listprofiles.php

The Vulkan Profiles API library that ship in the Vulkan SDK is using the following profiles that you certainly don't care about:

  • VP_ANDROID_baseline_2021,
  • VP_ANDROID_baseline_2022,
  • VP_KHR_roadmap_2022,
  • VP_LUNARG_desktop_baseline_2022,
  • VP_LUNARG_desktop_portability_2022

But the Vulkan Profiles API library is generated from a Python script (part of the Vulkan SDK) and available here with the following command:

gen_profiles_solution.py
		--registry ${VULKAN_HEADERS_REGISTRY_DIRECTORY}/vk.xml
		--input ${PROFILES_DIR}
		--output-library-inc ${PROJECT_SOURCE_DIR}/library/include/vulkan
		--output-library-src ${PROJECT_SOURCE_DIR}/library/source
		--debug

Then the library is used to check whether the profiles are supported using this API, eg:

    VpProfileProperties profile{ VP_ANDROID_BASELINE_2021_NAME, VP_ANDROID_BASELINE_2021_SPEC_VERSION };

    VkBool32 supported = VK_FALSE;
    VkResult result = vpGetPhysicalDeviceProfileSupport(mock.vkInstance, mock.vkPhysicalDevice, &profile, &supported);

--debug generates a version of the library that supports message which will reports the unsupported capabilities into stderr but you can also create a callback function by defining a function called: void VP_DEBUG_MESSAGE_CALLBACK(const char*);

This is probably not ideal in your scenario... I expect this is how IHVs do it because they asked for that a library...

christophe-lunarg avatar Mar 21 '23 15:03 christophe-lunarg

Thanks, that is helpful. I'll experiment with this in some simpler projects first to make sure the flow works.

This is probably not ideal in your scenario... I expect this is how IHVs do it because they asked for that a library...

Running custom code for this is fine, sounds like it would work for my purposes.

HansKristian-Work avatar Mar 21 '23 16:03 HansKristian-Work

Ok! let me know how it goes!

christophe-lunarg avatar Mar 21 '23 16:03 christophe-lunarg

Feathermore, you may want to automatically document your profiles in a human friendly matter and we do have such a tool.

You can find an instance of result here: https://vulkan.lunarg.com/doc/sdk/1.3.239.0/windows/profiles_definitions.html

This is done using the gen_profiles_solution.py script that ships in the Vulkan SDK and that is available in the Profiles repository: https://github.com/KhronosGroup/Vulkan-Profiles/tree/main/scripts

This is how the script is used:

gen_profiles_solution.py
  --registry vk.xml
  --input ./profiles/
  --output-doc ./PROFILES.md

This was ask by DXVK, interestingly, it looks like you have very similar use cases. ^_^

christophe-lunarg avatar Mar 21 '23 16:03 christophe-lunarg

Got around to experimenting with this finally. Hit some stumbling blocks while adding profiles to a simpler project.

Filed two bugs:

  • https://github.com/KhronosGroup/Vulkan-Loader/issues/1168
  • https://github.com/KhronosGroup/Vulkan-Profiles/issues/393

HansKristian-Work avatar Mar 30 '23 12:03 HansKristian-Work

Got through the self-study session now.

Added profiles support to Granite so that if a program using Granite wants to use profiles to initialize stuff, it can. Used the generate_solution scripts for that. https://github.com/Themaister/Granite/pull/112.

Added a profile to parallel-rdp as well. https://github.com/Themaister/parallel-rdp/tree/vulkan-profile

Verified that I can use the profile layer to restrict feature sets (using the new default=false env-variable), and combine that with validation worked well enough to ensure the profile is sound.

I think the next step is to start making vkd3d-proton profiles and test them against the profile layer.

HansKristian-Work avatar Apr 12 '23 19:04 HansKristian-Work

@christophe-lunarg https://github.com/HansKristian-Work/vkd3d-proton/pull/1567.

There were some issues in the profile layer:

  • Overriding sparse properties does not work.
  • The negative property "residencyAlignedMipSize" does not validate that the property is actually false it seems ...
  • Overriding VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT does not work. It's forced to false despite profile forcing it to true.
  • Profile override layer fails to handle multiple capabilities that use a property struct. I had to separate it out so that each unique combination of a property struct got its own capability.

Using alternative caps ["foo", "bar"] is broken. The script fails to run with an undefined variable error and the generated profile solution does not understand any of this.

HansKristian-Work avatar May 23 '23 13:05 HansKristian-Work

What version of the script are you using? The Using alternative caps ["foo", "bar"] should work if you are using the "main" branch version.

I'll have at your profiles look tomorrow and investigate these issues, thanks!

christophe-lunarg avatar May 23 '23 16:05 christophe-lunarg

Superseded by master.

HansKristian-Work avatar May 25 '23 11:05 HansKristian-Work