From 79f5a4d9fe966af0f0686e9d1cc36e819e8ace74 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Wed, 27 Nov 2024 10:34:48 -0600 Subject: [PATCH] OpenXR: Use the `XR_FB_foveation_vulkan` extension to get the density map for VRS --- doc/classes/ProjectSettings.xml | 3 +- doc/classes/XRInterface.xml | 9 ++++ doc/classes/XRInterfaceExtension.xml | 6 +++ .../extensions/openxr_extension_wrapper.h | 1 + .../openxr_fb_foveation_extension.cpp | 23 +++++--- .../openxr_fb_foveation_extension.h | 6 +-- .../platform/openxr_metal_extension.h | 1 + .../platform/openxr_opengl_extension.h | 1 + .../platform/openxr_vulkan_extension.cpp | 54 ++++++++++++++++++- .../platform/openxr_vulkan_extension.h | 2 + modules/openxr/openxr_api.cpp | 21 ++++++++ modules/openxr/openxr_api.h | 2 + modules/openxr/openxr_interface.cpp | 18 +++++++ modules/openxr/openxr_interface.h | 1 + servers/rendering/renderer_rd/effects/vrs.cpp | 2 +- .../forward_mobile/render_forward_mobile.cpp | 10 +++- .../storage_rd/render_scene_buffers_rd.cpp | 3 +- .../storage_rd/render_scene_buffers_rd.h | 2 + servers/rendering/rendering_device.cpp | 4 ++ servers/rendering/rendering_device.h | 4 +- servers/xr/xr_interface.cpp | 4 ++ servers/xr/xr_interface.h | 8 +++ servers/xr/xr_interface_extension.cpp | 9 ++++ servers/xr/xr_interface_extension.h | 2 + 24 files changed, 178 insertions(+), 18 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index c1083de9ecc..8f95c31034f 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -3257,11 +3257,10 @@ If [code]true[/code] and foveation is supported, will automatically adjust foveation level based on framerate up to the level set on [member xr/openxr/foveation_level]. - [b]Note:[/b] Only works on the Compatibility rendering method. Applied foveation level if supported: 0 = off, 1 = low, 2 = medium, 3 = high. - [b]Note:[/b] Only works on the Compatibility rendering method. On platforms other than Android, if [member rendering/anti_aliasing/quality/msaa_3d] is enabled, this feature will be disabled. + [b]Note:[/b] On platforms other than Android, if [member rendering/anti_aliasing/quality/msaa_3d] is enabled, this feature will be disabled. Specify the default reference space. diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index 13eb3c67e06..b3f307929a2 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -275,5 +275,14 @@ Alpha blend mode. This is typically used for AR or VR devices with passthrough capabilities. The alpha channel controls how much of the passthrough is visible. Alpha of 0.0 means the passthrough is visible and this pixel works in ADDITIVE mode. Alpha of 1.0 means that the passthrough is not visible and this pixel works in OPAQUE mode. + + The texture format is the same as returned by [method XRVRS.make_vrs_texture]. + + + The texture format is the same as expected by the Vulkan [code]VK_KHR_fragment_shading_rate[/code] extension. + + + The texture format is the same as expected by the Vulkan [code]VK_EXT_fragment_density_map[/code] extension. + diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml index b11c4cbb26a..7ea98ad3981 100644 --- a/doc/classes/XRInterfaceExtension.xml +++ b/doc/classes/XRInterfaceExtension.xml @@ -136,6 +136,12 @@ + + + + Returns the format of the texture returned by [method _get_vrs_texture]. + + diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 0119c89c430..72b7a607aed 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -192,4 +192,5 @@ public: virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) = 0; // `cleanup_swapchain_graphics_data` cleans up the data held in our implementation dependent data structure and should free up its memory. virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) = 0; // `create_projection_fov` creates a proper projection matrix based on asymmetric FOV data provided by OpenXR. virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) = 0; // `get_texture` returns a Godot texture RID for the current active texture in our swapchain. + virtual RID get_density_map(void *p_swapchain_graphics_data, int p_image_index) = 0; // `get_density_map` returns a Godot texture RID for the current active density map in our swapchain (if any). }; diff --git a/modules/openxr/extensions/openxr_fb_foveation_extension.cpp b/modules/openxr/extensions/openxr_fb_foveation_extension.cpp index 8ce808dd3c9..90d67260987 100644 --- a/modules/openxr/extensions/openxr_fb_foveation_extension.cpp +++ b/modules/openxr/extensions/openxr_fb_foveation_extension.cpp @@ -31,6 +31,8 @@ #include "openxr_fb_foveation_extension.h" #include "core/config/project_settings.h" +#include "../openxr_platform_inc.h" + OpenXRFBFoveationExtension *OpenXRFBFoveationExtension::singleton = nullptr; OpenXRFBFoveationExtension *OpenXRFBFoveationExtension::get_singleton() { @@ -51,6 +53,12 @@ OpenXRFBFoveationExtension::OpenXRFBFoveationExtension(const String &p_rendering swapchain_create_info_foveation_fb.type = XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB; swapchain_create_info_foveation_fb.next = nullptr; swapchain_create_info_foveation_fb.flags = 0; + + if (rendering_driver == "opengl3") { + swapchain_create_info_foveation_fb.flags = XR_SWAPCHAIN_CREATE_FOVEATION_SCALED_BIN_BIT_FB; + } else if (rendering_driver == "vulkan") { + swapchain_create_info_foveation_fb.flags = XR_SWAPCHAIN_CREATE_FOVEATION_FRAGMENT_DENSITY_MAP_BIT_FB; + } } OpenXRFBFoveationExtension::~OpenXRFBFoveationExtension() { @@ -61,12 +69,11 @@ OpenXRFBFoveationExtension::~OpenXRFBFoveationExtension() { HashMap OpenXRFBFoveationExtension::get_requested_extensions() { HashMap request_extensions; - if (rendering_driver == "vulkan") { - // This is currently only supported on OpenGL, but we may add Vulkan support in the future... + request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext; + request_extensions[XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME] = &fb_foveation_configuration_ext; - } else if (rendering_driver == "opengl3") { - request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext; - request_extensions[XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME] = &fb_foveation_configuration_ext; + if (rendering_driver == "vulkan") { + request_extensions[XR_FB_FOVEATION_VULKAN_EXTENSION_NAME] = &fb_foveation_vulkan_ext; } return request_extensions; @@ -89,7 +96,11 @@ void OpenXRFBFoveationExtension::on_instance_destroyed() { } bool OpenXRFBFoveationExtension::is_enabled() const { - return swapchain_update_state_ext != nullptr && swapchain_update_state_ext->is_enabled() && fb_foveation_ext && fb_foveation_configuration_ext; + bool enabled = swapchain_update_state_ext != nullptr && swapchain_update_state_ext->is_enabled() && fb_foveation_ext && fb_foveation_configuration_ext; + if (rendering_driver == "vulkan") { + enabled = enabled && fb_foveation_vulkan_ext; + } + return enabled; } void *OpenXRFBFoveationExtension::set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) { diff --git a/modules/openxr/extensions/openxr_fb_foveation_extension.h b/modules/openxr/extensions/openxr_fb_foveation_extension.h index a40061a6761..08552ef848a 100644 --- a/modules/openxr/extensions/openxr_fb_foveation_extension.h +++ b/modules/openxr/extensions/openxr_fb_foveation_extension.h @@ -35,11 +35,6 @@ // Other Android based devices are implementing this as well, see: // https://github.khronos.org/OpenXR-Inventory/extension_support.html#XR_FB_foveation -// Note: Currently we only support this for OpenGL. -// This extension works on enabling foveated rendering on the swapchain. -// Vulkan does not render 3D content directly to the swapchain image -// hence this extension can't be used. - #include "../openxr_api.h" #include "../util.h" #include "openxr_extension_wrapper.h" @@ -81,6 +76,7 @@ private: String rendering_driver; bool fb_foveation_ext = false; bool fb_foveation_configuration_ext = false; + bool fb_foveation_vulkan_ext = false; // Configuration XrFoveationLevelFB foveation_level = XR_FOVEATION_LEVEL_NONE_FB; diff --git a/modules/openxr/extensions/platform/openxr_metal_extension.h b/modules/openxr/extensions/platform/openxr_metal_extension.h index 75cf0ee0695..8654a2be776 100644 --- a/modules/openxr/extensions/platform/openxr_metal_extension.h +++ b/modules/openxr/extensions/platform/openxr_metal_extension.h @@ -53,6 +53,7 @@ public: virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override; + virtual RID get_density_map(void *p_swapchain_graphics_data, int p_image_index) override { return RID(); } private: static XrGraphicsBindingMetalKHR graphics_binding_metal; diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.h b/modules/openxr/extensions/platform/openxr_opengl_extension.h index 6da813d5272..8c6a29b8238 100644 --- a/modules/openxr/extensions/platform/openxr_opengl_extension.h +++ b/modules/openxr/extensions/platform/openxr_opengl_extension.h @@ -55,6 +55,7 @@ public: virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override; + virtual RID get_density_map(void *p_swapchain_graphics_data, int p_image_index) override { return RID(); } private: static OpenXROpenGLExtension *singleton; diff --git a/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp b/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp index 5b184d3bdfd..9599afb5784 100644 --- a/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp @@ -31,6 +31,7 @@ #include "openxr_vulkan_extension.h" #include "../../openxr_util.h" +#include "../openxr_fb_foveation_extension.h" #include "core/string/print_string.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" @@ -240,6 +241,7 @@ void OpenXRVulkanExtension::get_usable_depth_formats(Vector &p_usable_s bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) { LocalVector images; + LocalVector density_images; RenderingServer *rendering_server = RenderingServer::get_singleton(); ERR_FAIL_NULL_V(rendering_server, false); @@ -261,6 +263,20 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in image.image = VK_NULL_HANDLE; } + if (OpenXRFBFoveationExtension::get_singleton()->is_enabled()) { + density_images.resize(swapchain_length); + + for (uint64_t i = 0; i < swapchain_length; i++) { + density_images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB; + density_images[i].next = nullptr; + density_images[i].image = VK_NULL_HANDLE; + density_images[i].width = 0; + density_images[i].height = 0; + + images[i].next = &density_images[i]; + } + } + result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr()); if (XR_FAILED(result)) { print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); @@ -351,9 +367,12 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in } Vector texture_rids; + Vector density_map_rids; // create Godot texture objects for each entry in our swapchain - for (const XrSwapchainImageVulkanKHR &swapchain_image : images) { + for (uint32_t i = 0; i < swapchain_length; i++) { + const XrSwapchainImageVulkanKHR &swapchain_image = images[i]; + RID image_rid = rendering_device->texture_create_from_extension( p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY, format, @@ -366,9 +385,27 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in p_array_size); texture_rids.push_back(image_rid); + + if (OpenXRFBFoveationExtension::get_singleton()->is_enabled() && density_images[i].image != VK_NULL_HANDLE) { + RID density_map_rid = rendering_device->texture_create_from_extension( + p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY, + RD::DATA_FORMAT_R8G8_UNORM, + RenderingDevice::TEXTURE_SAMPLES_1, + RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT, + (uint64_t)density_images[i].image, + density_images[i].width, + density_images[i].height, + 1, + p_array_size); + + density_map_rids.push_back(density_map_rid); + } else { + density_map_rids.push_back(RID()); + } } data->texture_rids = texture_rids; + data->density_map_rids = density_map_rids; return true; } @@ -395,6 +432,14 @@ RID OpenXRVulkanExtension::get_texture(void *p_swapchain_graphics_data, int p_im return data->texture_rids[p_image_index]; } +RID OpenXRVulkanExtension::get_density_map(void *p_swapchain_graphics_data, int p_image_index) { + SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data; + ERR_FAIL_NULL_V(data, RID()); + + ERR_FAIL_INDEX_V(p_image_index, data->density_map_rids.size(), RID()); + return data->density_map_rids[p_image_index]; +} + void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) { if (*p_swapchain_graphics_data == nullptr) { return; @@ -413,6 +458,13 @@ void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_g } data->texture_rids.clear(); + for (int i = 0; i < data->density_map_rids.size(); i++) { + if (data->density_map_rids[i].is_valid()) { + rendering_device->free(data->density_map_rids[i]); + } + } + data->density_map_rids.clear(); + memdelete(data); *p_swapchain_graphics_data = nullptr; } diff --git a/modules/openxr/extensions/platform/openxr_vulkan_extension.h b/modules/openxr/extensions/platform/openxr_vulkan_extension.h index 06777b35e23..fe7f7a96fd1 100644 --- a/modules/openxr/extensions/platform/openxr_vulkan_extension.h +++ b/modules/openxr/extensions/platform/openxr_vulkan_extension.h @@ -62,6 +62,7 @@ public: virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override; + virtual RID get_density_map(void *p_swapchain_graphics_data, int p_image_index) override; private: static OpenXRVulkanExtension *singleton; @@ -70,6 +71,7 @@ private: struct SwapchainGraphicsData { bool is_multiview; Vector texture_rids; + Vector density_map_rids; }; bool check_graphics_api_support(XrVersion p_desired_version); diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index c7314864641..ed269dcc101 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -267,6 +267,16 @@ RID OpenXRAPI::OpenXRSwapChainInfo::get_image() { } } +RID OpenXRAPI::OpenXRSwapChainInfo::get_density_map() { + OpenXRAPI *openxr_api = OpenXRAPI::get_singleton(); + + if (image_acquired && openxr_api && openxr_api->get_graphics_extension()) { + return openxr_api->get_graphics_extension()->get_density_map(swapchain_graphics_data, image_index); + } else { + return RID(); + } +} + //////////////////////////////////// // OpenXRAPI @@ -2370,6 +2380,17 @@ RID OpenXRAPI::get_depth_texture() { } } +RID OpenXRAPI::get_density_map_texture() { + ERR_NOT_ON_RENDER_THREAD_V(RID()); + + OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton(); + if (fov_ext && fov_ext->is_enabled()) { + return render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].get_density_map(); + } + + return RID(); +} + void OpenXRAPI::set_velocity_texture(RID p_render_target) { velocity_texture = p_render_target; } diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index 05ac215153a..0ee9d8e9cdc 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -73,6 +73,7 @@ public: bool acquire(bool &p_should_render); bool release(); RID get_image(); + RID get_density_map(); }; private: @@ -501,6 +502,7 @@ public: XrSwapchain get_color_swapchain(); RID get_color_texture(); RID get_depth_texture(); + RID get_density_map_texture(); void set_velocity_texture(RID p_render_target); RID get_velocity_texture(); void set_velocity_depth_texture(RID p_render_target); diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 0e9e4f41fc6..57fac33b918 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -1546,6 +1546,11 @@ RID OpenXRInterface::get_vrs_texture() { return RID(); } + RID density_map = openxr_api->get_density_map_texture(); + if (density_map.is_valid()) { + return density_map; + } + PackedVector2Array eye_foci; Size2 target_size = get_render_target_size(); @@ -1561,6 +1566,19 @@ RID OpenXRInterface::get_vrs_texture() { return xr_vrs.make_vrs_texture(target_size, eye_foci); } +XRInterface::VRSTextureFormat OpenXRInterface::get_vrs_texture_format() { + if (!openxr_api) { + return XR_VRS_TEXTURE_FORMAT_UNIFIED; + } + + RID density_map = openxr_api->get_density_map_texture(); + if (density_map.is_valid()) { + return XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP; + } + + return XR_VRS_TEXTURE_FORMAT_UNIFIED; +} + void OpenXRInterface::set_cpu_level(PerfSettingsLevel p_level) { OpenXRPerformanceSettingsExtension *performance_settings_ext = OpenXRPerformanceSettingsExtension::get_singleton(); if (performance_settings_ext && performance_settings_ext->is_available()) { diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index 19e4c30292a..8705e796e90 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -290,6 +290,7 @@ public: Vector3 get_hand_joint_angular_velocity(Hand p_hand, HandJoints p_joint) const; virtual RID get_vrs_texture() override; + virtual VRSTextureFormat get_vrs_texture_format() override; // Performance settings. enum PerfSettingsLevel { diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 4730b5db045..1f963730c36 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -132,7 +132,7 @@ void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) { #ifndef XR_DISABLED } else if (vrs_mode == RS::VIEWPORT_VRS_XR) { Ref interface = XRServer::get_singleton()->get_primary_interface(); - if (interface.is_valid()) { + if (interface.is_valid() && interface->get_vrs_texture_format() == XRInterface::XR_VRS_TEXTURE_FORMAT_UNIFIED) { RID vrs_texture = interface->get_vrs_texture(); if (vrs_texture.is_valid()) { RID rd_texture = texture_storage->texture_get_rd_texture(vrs_texture); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 19db630df25..cdb1705fa47 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -183,7 +183,15 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe uint32_t view_count = render_buffers->get_view_count(); RID vrs_texture; - if (render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE)) { +#ifndef XR_DISABLED + if (render_buffers->get_vrs_mode() == RS::VIEWPORT_VRS_XR) { + Ref interface = XRServer::get_singleton()->get_primary_interface(); + if (interface.is_valid() && RD::get_singleton()->vrs_get_method() == RD::VRS_METHOD_FRAGMENT_DENSITY_MAP && interface->get_vrs_texture_format() == XRInterface::XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP) { + vrs_texture = interface->get_vrs_texture(); + } + } +#endif // XR_DISABLED + if (vrs_texture.is_null() && render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE)) { vrs_texture = render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE); } diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index a286af91db3..2b3b287c569 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -168,6 +168,8 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co ERR_FAIL_COND_MSG(view_count == 0, "Must have at least 1 view"); + vrs_mode = texture_storage->render_target_get_vrs_mode(render_target); + update_samplers(); // cleanout any old buffers we had. @@ -194,7 +196,6 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co // VRS (note, our vrs object will only be set if VRS is supported) RID vrs_texture; - RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(render_target); if (vrs && vrs_mode != RS::VIEWPORT_VRS_DISABLED) { vrs_texture = create_texture(RB_SCOPE_VRS, RB_TEXTURE, get_vrs_format(), get_vrs_usage_bits(), RD::TEXTURE_SAMPLES_1, vrs->get_vrs_texture_size(internal_size)); } diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h index 2df43c28f2f..ba42970a5d7 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h @@ -69,6 +69,7 @@ private: RD::DataFormat base_data_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; RendererRD::VRS *vrs = nullptr; uint64_t auto_exposure_version = 1; + RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED; // Our render target represents our final destination that we display on screen. RID render_target; @@ -188,6 +189,7 @@ public: void set_base_data_format(const RD::DataFormat p_base_data_format) { base_data_format = p_base_data_format; } RD::DataFormat get_base_data_format() const { return base_data_format; } void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; } + RS::ViewportVRSMode get_vrs_mode() { return vrs_mode; } void cleanup(); virtual void configure(const RenderSceneBuffersConfiguration *p_config) override; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 1d52eae7923..95206a56fc8 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -2761,6 +2761,10 @@ void RenderingDevice::_vrs_detect_method() { } } +RD::VRSMethod RenderingDevice::vrs_get_method() const { + return vrs_method; +} + RD::DataFormat RenderingDevice::vrs_get_format() const { return vrs_format; } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 61089ab592e..29e444ae9dc 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -429,7 +429,7 @@ public: void texture_set_discardable(RID p_texture, bool p_discardable); bool texture_is_discardable(RID p_texture); -private: +public: /*************/ /**** VRS ****/ /*************/ @@ -440,6 +440,7 @@ private: VRS_METHOD_FRAGMENT_DENSITY_MAP, }; +private: VRSMethod vrs_method = VRS_METHOD_NONE; DataFormat vrs_format = DATA_FORMAT_MAX; Size2i vrs_texel_size; @@ -450,6 +451,7 @@ private: void _vrs_detect_method(); public: + VRSMethod vrs_get_method() const; DataFormat vrs_get_format() const; Size2i vrs_get_texel_size() const; diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index c3a4188a6c3..dc01363bdfa 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -108,6 +108,10 @@ void XRInterface::_bind_methods() { BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_OPAQUE); BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ADDITIVE); BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ALPHA_BLEND); + + BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_UNIFIED); + BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_FRAGMENT_SHADING_RATE); + BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP); } bool XRInterface::is_primary() { diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index b669f6ebcfd..53d6e9567ba 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -85,6 +85,12 @@ public: XR_ENV_BLEND_MODE_ALPHA_BLEND, /* Real world is passed through where alpha channel is 0.0 and gradually blends to opaque for value 1.0. */ }; + enum VRSTextureFormat { + XR_VRS_TEXTURE_FORMAT_UNIFIED, + XR_VRS_TEXTURE_FORMAT_FRAGMENT_SHADING_RATE, + XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP, + }; + protected: _THREAD_SAFE_CLASS_ @@ -159,6 +165,7 @@ public: /** VRS **/ virtual RID get_vrs_texture(); /* obtain VRS texture */ + virtual VRSTextureFormat get_vrs_texture_format() { return XR_VRS_TEXTURE_FORMAT_UNIFIED; } XRInterface(); ~XRInterface(); @@ -168,3 +175,4 @@ VARIANT_ENUM_CAST(XRInterface::Capabilities); VARIANT_ENUM_CAST(XRInterface::TrackingStatus); VARIANT_ENUM_CAST(XRInterface::PlayAreaMode); VARIANT_ENUM_CAST(XRInterface::EnvironmentBlendMode); +VARIANT_ENUM_CAST(XRInterface::VRSTextureFormat); diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index eab8726dc3f..782c358f615 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -51,6 +51,7 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_get_transform_for_view, "view", "cam_transform"); GDVIRTUAL_BIND(_get_projection_for_view, "view", "aspect", "z_near", "z_far"); GDVIRTUAL_BIND(_get_vrs_texture); + GDVIRTUAL_BIND(_get_vrs_texture_format); GDVIRTUAL_BIND(_process); GDVIRTUAL_BIND(_pre_render); @@ -242,6 +243,14 @@ RID XRInterfaceExtension::get_vrs_texture() { } } +XRInterface::VRSTextureFormat XRInterfaceExtension::get_vrs_texture_format() { + VRSTextureFormat vrs_texture_format = XR_VRS_TEXTURE_FORMAT_UNIFIED; + if (GDVIRTUAL_CALL(_get_vrs_texture_format, vrs_texture_format)) { + return vrs_texture_format; + } + return vrs_texture_format; +} + RID XRInterfaceExtension::get_color_texture() { RID texture; GDVIRTUAL_CALL(_get_color_texture, texture); diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h index ebf98c8fb1b..fd427ff68f5 100644 --- a/servers/xr/xr_interface_extension.h +++ b/servers/xr/xr_interface_extension.h @@ -103,6 +103,7 @@ public: virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual RID get_vrs_texture() override; + virtual VRSTextureFormat get_vrs_texture_format() override; virtual RID get_color_texture() override; virtual RID get_depth_texture() override; virtual RID get_velocity_texture() override; @@ -113,6 +114,7 @@ public: GDVIRTUAL2R(Transform3D, _get_transform_for_view, uint32_t, const Transform3D &); GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double); GDVIRTUAL0R(RID, _get_vrs_texture); + GDVIRTUAL0R(VRSTextureFormat, _get_vrs_texture_format); GDVIRTUAL0R(RID, _get_color_texture); GDVIRTUAL0R(RID, _get_depth_texture); GDVIRTUAL0R(RID, _get_velocity_texture);