Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add VKD3D profiles to express vulkan requirements #1210

Closed

Conversation

christophe-lunarg
Copy link

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: doitsujin/dxvk#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!

@doitsujin
Copy link
Collaborator

doitsujin commented Sep 3, 2022

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.

@christophe-lunarg
Copy link
Author

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 !

@HansKristian-Work
Copy link
Owner

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

@christophe-lunarg
Copy link
Author

christophe-lunarg commented Sep 13, 2022

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

@linyaa-kiwi
Copy link

linyaa-kiwi commented Jan 31, 2023

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).

@christophe-lunarg
Copy link
Author

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

@HansKristian-Work
Copy link
Owner

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

@doitsujin
Copy link
Collaborator

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

@christophe-lunarg
Copy link
Author

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

@HansKristian-Work
Copy link
Owner

Vulkan 1.3 cleanup has been merged now.

@christophe-lunarg
Copy link
Author

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

"vulkan11requirements": {
"features": {
"VkPhysicalDeviceVulkan11Features": {
"multiview": true

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we use multiview?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vulkanXXrequirements section list the requirements of each Vulkan version. We can disable each capabilities if you want be we can expect that all Vulkan 1.3 drivers will have these capabilities.

"features": {
"VkPhysicalDeviceVulkan12Features": {
"uniformBufferStandardLayout": true,
"subgroupBroadcastDynamicId": true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused.

"VkPhysicalDeviceVulkan12Features": {
"uniformBufferStandardLayout": true,
"subgroupBroadcastDynamicId": true,
"imagelessFramebuffer": true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused.

"profiles": {
"VP_VKD3D_d3d12_level_11_0_baseline": {
"version": 1,
"api-version": "1.3.204",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 204 in particular? I figure this should just be 1.3 core.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because api-version refers to a specific Vulkan Header version, it indicates what's the minimum Vulkan API revision the Vulkan drivers must supports for the necessary to be potentially exposed and supported.

204 is the first Vulkan 1.3 Vulkan Header version and this profile only requires Vulkan 1.3 and not additional extensions or capabilities added in following Vulkan Header revision.

This said, you can decide that you want to require new Vulkan API version if you want just to explicitly claim that you don't want to support Vulkan drivers that old.

I used the Profiles JSON schemas here https://schema.khronos.org/vulkan/ to figure out these api-version for each profile.

"properties": {
"VkPhysicalDeviceProperties": {
"limits": {
"maxPerStageDescriptorStorageBuffers": 64,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat redundant since we rely on update-after-bind.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes from here:

static void d3d12_device_caps_init_feature_level(struct d3d12_device *device)
{
    const VkPhysicalDeviceFeatures *features = &device->device_info.features2.features;
    const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
    struct d3d12_caps *caps = &device->d3d12_caps;

    caps->max_feature_level = D3D_FEATURE_LEVEL_11_0;

    if (caps->options.OutputMergerLogicOp && features->vertexPipelineStoresAndAtomics &&
            vk_info->device_limits.maxPerStageDescriptorStorageBuffers >= D3D12_UAV_SLOT_COUNT &&
            vk_info->device_limits.maxPerStageDescriptorStorageImages >= D3D12_UAV_SLOT_COUNT)
        caps->max_feature_level = D3D_FEATURE_LEVEL_11_1;

So I am wondering, if this code is correct but it's hard for me to really know.

"limits": {
"maxPerStageDescriptorStorageBuffers": 64,
"maxPerStageDescriptorStorageImages": 64,
"minStorageBufferOffsetAlignment": 4

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an exact requirement or "must be less-or-equal to 4"?

@HansKristian-Work
Copy link
Owner

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.

@christophe-lunarg
Copy link
Author

christophe-lunarg commented Mar 20, 2023

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.

@HansKristian-Work
Copy link
Owner

HansKristian-Work commented Mar 20, 2023

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.

@christophe-lunarg
Copy link
Author

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...

@HansKristian-Work
Copy link
Owner

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.

@christophe-lunarg
Copy link
Author

Ok! let me know how it goes!

@christophe-lunarg
Copy link
Author

christophe-lunarg commented Mar 21, 2023

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. ^_^

@HansKristian-Work
Copy link
Owner

HansKristian-Work commented Mar 30, 2023

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

Filed two bugs:

@HansKristian-Work
Copy link
Owner

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. Themaister/Granite#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
Copy link
Owner

HansKristian-Work commented May 23, 2023

@christophe-lunarg #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.

@christophe-lunarg
Copy link
Author

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!

@HansKristian-Work
Copy link
Owner

Superseded by master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants