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

Unable to control the setting of enabled Features in a Device #30

Open
johnhutch111 opened this issue Sep 21, 2023 · 4 comments
Open

Unable to control the setting of enabled Features in a Device #30

johnhutch111 opened this issue Sep 21, 2023 · 4 comments

Comments

@johnhutch111
Copy link

The fFeatures record is filled during the TpvVulkanPhysicalDevice create. This record is copied to the fEnabledFeatures record in the TpvVulkanDevice. The pointer to the fEnabledFeatures record is passed in the DeviceCreateInfo. This will enable all Features from the Physical device. I want to control which features are enabled. Is this logic correct? I would suggest access to the fEnabledFeatures via a Property to adjust the values before Initialize is called.

@BeRo1985
Copy link
Owner

BeRo1985 commented Nov 10, 2023

I have now added TpvVulkanDevice.OnBeforeDeviceCreate as TpvVulkanDeviceOnBeforeDeviceCreate=procedure(const aDevice:TpvVulkanDevice;const aDeviceCreateInfo:PVkDeviceCreateInfo) of object;. This means that one can now modify the pNext chain oneself.

But by default, PasVulkan has the idea that all "standard features" are always activated for ready-to-go-usage, as long as they do not cost anything on the vast majority of GPUs, or as long as they are not features that must not be activated at the same time. e.g. robustImageAccess is no longer activated by default, as it is not free of performance costs, since robust access features do pollute userdata SGPRs.

And one must not forget that parts of PasVulkan itself are now dependent on many features, e.g. PasVulkan.Scene3D now absolutely needs descriptorIndexing, bufferDeviceAddress, and the like.

But I will continue to try to minimize the set of pre-enabled features further, regarding the features that may cost something or may not be enabled on some GPUs at the same time.

@johnhutch111
Copy link
Author

Thanks for the reply and change. This will give me extra flexibility.

@johnhutch111
Copy link
Author

I note in the latest version of PasVulkan.Framework.pas that you test for version using the Instance API Version using the following code : "(fInstance.APIVersion and VK_API_VERSION_WITHOUT_PATCH_MASK)>=VK_API_VERSION_1_3". I use a notebook with two devices on board ( an Intel Vulkan v1_2 and a NVIDIA Vulkan v1_3) Should the test use the version of the device rather than the version of the Instance?

@BeRo1985
Copy link
Owner

BeRo1985 commented Dec 2, 2023

I note in the latest version of PasVulkan.Framework.pas that you test for version using the Instance API Version using the following code : "(fInstance.APIVersion and VK_API_VERSION_WITHOUT_PATCH_MASK)>=VK_API_VERSION_1_3". I use a notebook with two devices on board ( an Intel Vulkan v1_2 and a NVIDIA Vulkan v1_3) Should the test use the version of the device rather than the version of the Instance?

The logic in PasVulkan.Framework.pas, which tests the Instance API version, is accurate according to the Vulkan specification. The Vulkan specification mandates that a Vulkan instance must be initialized before any device instances, which requires a specific API version already to be defined when the instance is created. One can request a version manually over VkApplicationInfo.apiVersion (see the aAPIVersion argument at TpvVulkanInstance.Create), but this value serves just as a rough guideline for PasVulkan's Vulkan API Version choice. The fInstance.apiVersion is derived from VkApplicationInfo.apiVersion, but it is then restrained through vkEnumerateInstanceVersion. This means that the Instance API version is not solely determined by the VkApplicationInfo.apiVersion, but also by the constraints set by vkEnumerateInstanceVersion. The API version specified during instance creation influences also the availability and functionality of device-level "core commands", aligning with the principle that device-specific considerations in Vulkan are contingent on the instance already being established. And for the sake of simplicity, PasVulkan also respects it for non-core functionality, because I want to avoid an even more extreme case differentiation hell here (at least for now), even if the specification would actually allow it.

The Vulkan API's approach to device-level core commands and API versions is articulated in the Vulkan documentation. Specifically, device-level commands that are part of the core version specified by VkApplicationInfo.apiVersion during the creation of the instance will always return a valid function pointer. However, if the maintenance5 feature is enabled, core commands beyond the specified version that are supported by the implementation will return NULL. In cases where the implementation may either return NULL or a function pointer for these commands, the function pointer must not be called if returned​​ (see https://docs.vulkan.org/spec/latest/chapters/initialization.html ).

And PasVulkan's logic is here:

 // Assign the provided API version to fApplicationInfo.apiVersion
 fApplicationInfo.apiVersion:=aAPIVersion;

 if ApplicationInfo.apiVersion=0 then begin

  // If the apiVersion is not specified (0), set default and check for available versions

  fApplicationInfo.apiVersion:=VK_API_VERSION_1_0; // Default to Vulkan API version 1.0

   // Get the highest available instance version
  if assigned(fVulkan.Commands.EnumerateInstanceVersion) and
     (fVulkan.EnumerateInstanceVersion(@fApplicationInfo.apiVersion)<>VK_SUCCESS) then begin
   // If unsuccessful in getting a higher version, stick to Vulkan API version 1.0
   fApplicationInfo.apiVersion:=VK_API_VERSION_1_0;
  end;

 end;

 // Ensure the API version is at least Vulkan 1.0, without considering patch version, and
 // if the API version exceeds Vulkan 1.3, cap the version to Vulkan 1.3 (for now)
 if (fApplicationInfo.apiVersion and VK_API_VERSION_WITHOUT_PATCH_MASK)<VK_API_VERSION_1_0 then begin
  fApplicationInfo.apiVersion:=VK_API_VERSION_1_0;
 end else if (fApplicationInfo.apiVersion and VK_API_VERSION_WITHOUT_PATCH_MASK)>VK_API_VERSION_1_3 then begin
  fApplicationInfo.apiVersion:=VK_API_VERSION_1_3;
 end;

image

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

No branches or pull requests

2 participants