1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-02 16:48:55 +00:00

Implement XR_META_foveation_eye_tracked

This commit is contained in:
dhoverb
2025-11-07 18:50:39 +00:00
committed by David Hover
parent 68410acc61
commit 53e1ea184a
8 changed files with 144 additions and 19 deletions

View File

@@ -523,6 +523,7 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
_register_requested_device_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME, false);
_register_requested_device_extension(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, false);
_register_requested_device_extension(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, false);
_register_requested_device_extension(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME, false);
_register_requested_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, false);
_register_requested_device_extension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
_register_requested_device_extension(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, false);
@@ -760,6 +761,7 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkan_memory_model_features = {};
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_features = {};
VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM fdmo_features_qcom = {};
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {};
VkPhysicalDeviceMultiviewFeatures multiview_features = {};
VkPhysicalDevicePipelineCreationCacheControlFeatures pipeline_cache_control_features = {};
@@ -799,6 +801,12 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
next_features = &fdm_features;
}
if (enabled_device_extension_names.has(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME)) {
fdmo_features_qcom.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM;
fdmo_features_qcom.pNext = next_features;
next_features = &fdmo_features_qcom;
}
if (enabled_device_extension_names.has(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
storage_feature.pNext = next_features;
@@ -863,6 +871,10 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
fdm_capabilities.non_subsampled_images_supported = fdm_features.fragmentDensityMapNonSubsampledImages;
}
if (enabled_device_extension_names.has(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME)) {
fdm_capabilities.offset_supported = fdmo_features_qcom.fragmentDensityMapOffset;
}
// Multiple VRS techniques can't co-exist during the existence of one device, so we must
// choose one at creation time and only report one of them as available.
_choose_vrs_capabilities();
@@ -898,6 +910,7 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
void *next_properties = nullptr;
VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = {};
VkPhysicalDeviceFragmentDensityMapPropertiesEXT fdm_properties = {};
VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM fdmo_properties = {};
VkPhysicalDeviceMultiviewProperties multiview_properties = {};
VkPhysicalDeviceSubgroupProperties subgroup_properties = {};
VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control_properties = {};
@@ -935,6 +948,12 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
next_properties = &fdm_properties;
}
if (fdm_capabilities.offset_supported) {
fdmo_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM;
fdmo_properties.pNext = next_properties;
next_properties = &fdmo_properties;
}
physical_device_properties_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
physical_device_properties_2.pNext = next_properties;
functions.GetPhysicalDeviceProperties2(physical_device, &physical_device_properties_2);
@@ -1002,6 +1021,17 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
print_verbose("- Vulkan Fragment Density Map not supported");
}
if (fdm_capabilities.offset_supported) {
print_verbose("- Vulkan Fragment Density Map Offset supported");
fdm_capabilities.offset_granularity.x = fdmo_properties.fragmentDensityOffsetGranularity.width;
fdm_capabilities.offset_granularity.y = fdmo_properties.fragmentDensityOffsetGranularity.height;
print_verbose(vformat(" Offset granularity: (%d, %d)", fdm_capabilities.offset_granularity.x, fdm_capabilities.offset_granularity.y));
} else {
print_verbose("- Vulkan Fragment Density Map Offset not supported");
}
if (multiview_capabilities.is_supported) {
multiview_capabilities.max_view_count = multiview_properties.maxMultiviewViewCount;
multiview_capabilities.max_instance_count = multiview_properties.maxMultiviewInstanceIndex;
@@ -3708,11 +3738,6 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID
for (uint32_t i = 0; i < p_attachments.size(); i++) {
const TextureInfo *texture = (const TextureInfo *)p_attachments[i].id;
vk_img_views[i] = texture->vk_view;
if (render_pass->uses_fragment_density_map_offsets && (texture->vk_create_info.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT)) {
// If the render pass uses the FDM and the usage fits, we store the amount of layers to use it later on the render pass's end.
fragment_density_map_offsets_layers = texture->vk_create_info.arrayLayers;
}
}
VkFramebufferCreateInfo framebuffer_create_info = {};
@@ -4921,6 +4946,7 @@ RDD::RenderPassID RenderingDeviceDriverVulkan::render_pass_create(VectorView<Att
RenderPassInfo *render_pass = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
render_pass->vk_render_pass = vk_render_pass;
render_pass->uses_fragment_density_map = uses_fragment_density_map;
return RenderPassID(render_pass);
}
@@ -4982,7 +5008,25 @@ void RenderingDeviceDriverVulkan::command_end_render_pass(CommandBufferID p_cmd_
DEV_ASSERT(command_buffer->active_framebuffer != nullptr && "A framebuffer must be active.");
DEV_ASSERT(command_buffer->active_render_pass != nullptr && "A render pass must be active.");
vkCmdEndRenderPass(command_buffer->vk_command_buffer);
if (device_functions.EndRenderPass2KHR != nullptr && fdm_capabilities.offset_supported && command_buffer->active_render_pass->uses_fragment_density_map) {
LocalVector<VkOffset2D> fragment_density_offsets;
if (VulkanHooks::get_singleton() != nullptr) {
fragment_density_offsets = VulkanHooks::get_singleton()->get_fragment_density_offsets();
}
VkSubpassFragmentDensityMapOffsetEndInfoQCOM offset_info = {};
offset_info.sType = VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM;
offset_info.pFragmentDensityOffsets = fragment_density_offsets.is_empty() ? nullptr : fragment_density_offsets.ptr();
offset_info.fragmentDensityOffsetCount = fragment_density_offsets.size();
VkSubpassEndInfo subpass_end_info = {};
subpass_end_info.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
subpass_end_info.pNext = &offset_info;
device_functions.EndRenderPass2KHR(command_buffer->vk_command_buffer, &subpass_end_info);
} else {
vkCmdEndRenderPass(command_buffer->vk_command_buffer);
}
command_buffer->active_render_pass = nullptr;
command_buffer->active_framebuffer = nullptr;