Merge pull request #99407 from devloglogan/rec-resolution
Allow using custom `Rect2i` for rendering with OpenXR
This commit is contained in:
commit
3014eec40d
25 changed files with 215 additions and 19 deletions
|
|
@ -82,6 +82,13 @@
|
|||
Returns the predicted display timing for the current frame.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_projection_layer">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns a pointer to the render state's [code]XrCompositionLayerProjection[/code] struct.
|
||||
[b]Note:[/b] This method should only be called from the rendering thread.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_render_state_z_far">
|
||||
<return type="float" />
|
||||
<description>
|
||||
|
|
@ -231,6 +238,13 @@
|
|||
Set the object name of an OpenXR object, used for debug output. [param object_type] must be a valid OpenXR [code]XrObjectType[/code] enum and [param object_handle] must be a valid OpenXR object handle.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_render_region">
|
||||
<return type="void" />
|
||||
<param index="0" name="render_region" type="Rect2i" />
|
||||
<description>
|
||||
Sets the render region to [param render_region], overriding the normal render target's rect.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_velocity_depth_texture">
|
||||
<return type="void" />
|
||||
<param index="0" name="render_target" type="RID" />
|
||||
|
|
|
|||
|
|
@ -2167,6 +2167,14 @@ void OpenXRAPI::_set_render_state_multiplier(double p_render_target_size_multipl
|
|||
openxr_api->render_state.render_target_size_multiplier = p_render_target_size_multiplier;
|
||||
}
|
||||
|
||||
void OpenXRAPI::_set_render_state_render_region(const Rect2i &p_render_region) {
|
||||
ERR_NOT_ON_RENDER_THREAD;
|
||||
|
||||
OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
|
||||
ERR_FAIL_NULL(openxr_api);
|
||||
openxr_api->render_state.render_region = p_render_region;
|
||||
}
|
||||
|
||||
bool OpenXRAPI::process() {
|
||||
ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
|
||||
|
||||
|
|
@ -2399,6 +2407,12 @@ Size2i OpenXRAPI::get_velocity_target_size() {
|
|||
return velocity_target_size;
|
||||
}
|
||||
|
||||
const XrCompositionLayerProjection *OpenXRAPI::get_projection_layer() const {
|
||||
ERR_NOT_ON_RENDER_THREAD_V(nullptr);
|
||||
|
||||
return &render_state.projection_layer;
|
||||
}
|
||||
|
||||
void OpenXRAPI::post_draw_viewport(RID p_render_target) {
|
||||
// Must be called from rendering thread!
|
||||
ERR_NOT_ON_RENDER_THREAD;
|
||||
|
|
@ -2432,6 +2446,23 @@ void OpenXRAPI::end_frame() {
|
|||
}
|
||||
}
|
||||
|
||||
Rect2i new_render_region = (render_state.render_region != Rect2i()) ? render_state.render_region : Rect2i(Point2i(0, 0), render_state.main_swapchain_size);
|
||||
|
||||
for (uint32_t i = 0; i < render_state.view_count; i++) {
|
||||
render_state.projection_views[i].subImage.imageRect.offset.x = new_render_region.position.x;
|
||||
render_state.projection_views[i].subImage.imageRect.offset.y = new_render_region.position.y;
|
||||
render_state.projection_views[i].subImage.imageRect.extent.width = new_render_region.size.width;
|
||||
render_state.projection_views[i].subImage.imageRect.extent.height = new_render_region.size.height;
|
||||
}
|
||||
if (render_state.submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && render_state.depth_views) {
|
||||
for (uint32_t i = 0; i < render_state.view_count; i++) {
|
||||
render_state.depth_views[i].subImage.imageRect.offset.x = new_render_region.position.x;
|
||||
render_state.depth_views[i].subImage.imageRect.offset.y = new_render_region.position.y;
|
||||
render_state.depth_views[i].subImage.imageRect.extent.width = new_render_region.size.width;
|
||||
render_state.depth_views[i].subImage.imageRect.extent.height = new_render_region.size.height;
|
||||
}
|
||||
}
|
||||
|
||||
// must have:
|
||||
// - should_render set to true
|
||||
// - a valid view pose for projection_views[eye].pose to submit layer
|
||||
|
|
@ -2496,14 +2527,10 @@ void OpenXRAPI::end_frame() {
|
|||
layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
}
|
||||
|
||||
XrCompositionLayerProjection projection_layer = {
|
||||
XR_TYPE_COMPOSITION_LAYER_PROJECTION, // type
|
||||
nullptr, // next
|
||||
layer_flags, // layerFlags
|
||||
render_state.play_space, // space
|
||||
render_state.view_count, // viewCount
|
||||
render_state.projection_views, // views
|
||||
};
|
||||
render_state.projection_layer.layerFlags = layer_flags;
|
||||
render_state.projection_layer.space = render_state.play_space;
|
||||
render_state.projection_layer.viewCount = render_state.view_count;
|
||||
render_state.projection_layer.views = render_state.projection_views;
|
||||
|
||||
if (projection_views_extensions.size() > 0) {
|
||||
for (uint32_t v = 0; v < render_state.view_count; v++) {
|
||||
|
|
@ -2518,7 +2545,7 @@ void OpenXRAPI::end_frame() {
|
|||
}
|
||||
}
|
||||
|
||||
ordered_layers_list.push_back({ (const XrCompositionLayerBaseHeader *)&projection_layer, 0 });
|
||||
ordered_layers_list.push_back({ (const XrCompositionLayerBaseHeader *)&render_state.projection_layer, 0 });
|
||||
|
||||
// Sort our layers.
|
||||
ordered_layers_list.sort_custom<OrderedCompositionLayer>();
|
||||
|
|
@ -2580,6 +2607,15 @@ void OpenXRAPI::set_render_target_size_multiplier(double multiplier) {
|
|||
set_render_state_multiplier(multiplier);
|
||||
}
|
||||
|
||||
Rect2i OpenXRAPI::get_render_region() const {
|
||||
return render_region;
|
||||
}
|
||||
|
||||
void OpenXRAPI::set_render_region(const Rect2i &p_render_region) {
|
||||
render_region = p_render_region;
|
||||
set_render_state_render_region(p_render_region);
|
||||
}
|
||||
|
||||
bool OpenXRAPI::is_foveation_supported() const {
|
||||
OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
|
||||
return fov_ext != nullptr && fov_ext->is_enabled();
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ private:
|
|||
bool running = false;
|
||||
XrFrameState frame_state = { XR_TYPE_FRAME_STATE, nullptr, 0, 0, false };
|
||||
double render_target_size_multiplier = 1.0;
|
||||
Rect2i render_region;
|
||||
|
||||
OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr;
|
||||
XrSystemGraphicsProperties graphics_properties;
|
||||
|
|
@ -341,6 +342,7 @@ private:
|
|||
XrSpace play_space = XR_NULL_HANDLE;
|
||||
double render_target_size_multiplier = 1.0;
|
||||
uint64_t frame = 0;
|
||||
Rect2i render_region;
|
||||
|
||||
uint32_t view_count = 0;
|
||||
XrView *views = nullptr;
|
||||
|
|
@ -352,6 +354,15 @@ private:
|
|||
double z_near = 0.0;
|
||||
double z_far = 0.0;
|
||||
|
||||
XrCompositionLayerProjection projection_layer = {
|
||||
XR_TYPE_COMPOSITION_LAYER_PROJECTION, // type
|
||||
nullptr, // next
|
||||
0, // layerFlags
|
||||
XR_NULL_HANDLE, // space
|
||||
0, // viewCount
|
||||
nullptr // views
|
||||
};
|
||||
|
||||
Size2i main_swapchain_size;
|
||||
OpenXRSwapChainInfo main_swapchains[OPENXR_SWAPCHAIN_MAX];
|
||||
} render_state;
|
||||
|
|
@ -361,6 +372,7 @@ private:
|
|||
static void _set_render_display_info(XrTime p_predicted_display_time, bool p_should_render);
|
||||
static void _set_render_play_space(uint64_t p_play_space);
|
||||
static void _set_render_state_multiplier(double p_render_target_size_multiplier);
|
||||
static void _set_render_state_render_region(const Rect2i &p_render_region);
|
||||
|
||||
_FORCE_INLINE_ void allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer) {
|
||||
// If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
|
||||
|
|
@ -402,6 +414,13 @@ private:
|
|||
rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_multiplier).bind(p_render_target_size_multiplier));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_render_state_render_region(const Rect2i &p_render_region) {
|
||||
RenderingServer *rendering_server = RenderingServer::get_singleton();
|
||||
ERR_FAIL_NULL(rendering_server);
|
||||
|
||||
rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_render_region).bind(p_render_region));
|
||||
}
|
||||
|
||||
public:
|
||||
XrInstance get_instance() const { return instance; }
|
||||
XrSystemId get_system_id() const { return system_id; }
|
||||
|
|
@ -491,6 +510,7 @@ public:
|
|||
RID get_velocity_depth_texture();
|
||||
void set_velocity_target_size(const Size2i &p_target_size);
|
||||
Size2i get_velocity_target_size();
|
||||
const XrCompositionLayerProjection *get_projection_layer() const;
|
||||
void post_draw_viewport(RID p_render_target);
|
||||
void end_frame();
|
||||
|
||||
|
|
@ -503,6 +523,9 @@ public:
|
|||
double get_render_target_size_multiplier() const;
|
||||
void set_render_target_size_multiplier(double multiplier);
|
||||
|
||||
Rect2i get_render_region() const;
|
||||
void set_render_region(const Rect2i &p_render_region);
|
||||
|
||||
// Foveation settings
|
||||
bool is_foveation_supported() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ void OpenXRAPIExtension::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("openxr_swapchain_get_image", "swapchain"), &OpenXRAPIExtension::openxr_swapchain_get_image);
|
||||
ClassDB::bind_method(D_METHOD("openxr_swapchain_release", "swapchain"), &OpenXRAPIExtension::openxr_swapchain_release);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_projection_layer"), &OpenXRAPIExtension::get_projection_layer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_render_region", "render_region"), &OpenXRAPIExtension::set_render_region);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_emulate_environment_blend_mode_alpha_blend", "enabled"), &OpenXRAPIExtension::set_emulate_environment_blend_mode_alpha_blend);
|
||||
ClassDB::bind_method(D_METHOD("is_environment_blend_mode_alpha_supported"), &OpenXRAPIExtension::is_environment_blend_mode_alpha_blend_supported);
|
||||
|
||||
|
|
@ -300,6 +304,16 @@ void OpenXRAPIExtension::openxr_swapchain_release(uint64_t p_swapchain_info) {
|
|||
swapchain_info->release();
|
||||
}
|
||||
|
||||
uint64_t OpenXRAPIExtension::get_projection_layer() {
|
||||
ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
|
||||
return (uint64_t)OpenXRAPI::get_singleton()->get_projection_layer();
|
||||
}
|
||||
|
||||
void OpenXRAPIExtension::set_render_region(const Rect2i &p_render_region) {
|
||||
ERR_FAIL_NULL(OpenXRAPI::get_singleton());
|
||||
OpenXRAPI::get_singleton()->set_render_region(p_render_region);
|
||||
}
|
||||
|
||||
void OpenXRAPIExtension::set_emulate_environment_blend_mode_alpha_blend(bool p_enabled) {
|
||||
ERR_FAIL_NULL(OpenXRAPI::get_singleton());
|
||||
OpenXRAPI::get_singleton()->set_emulate_environment_blend_mode_alpha_blend(p_enabled);
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ public:
|
|||
RID openxr_swapchain_get_image(uint64_t p_swapchain_info);
|
||||
void openxr_swapchain_release(uint64_t p_swapchain_info);
|
||||
|
||||
uint64_t get_projection_layer();
|
||||
|
||||
void set_render_region(const Rect2i &p_render_region);
|
||||
|
||||
enum OpenXRAlphaBlendModeSupport {
|
||||
OPENXR_ALPHA_BLEND_MODE_SUPPORT_NONE = 0,
|
||||
OPENXR_ALPHA_BLEND_MODE_SUPPORT_REAL = 1,
|
||||
|
|
|
|||
|
|
@ -1055,6 +1055,14 @@ Projection OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_as
|
|||
return cm;
|
||||
}
|
||||
|
||||
Rect2i OpenXRInterface::get_render_region() {
|
||||
if (openxr_api) {
|
||||
return openxr_api->get_render_region();
|
||||
} else {
|
||||
return Rect2i();
|
||||
}
|
||||
}
|
||||
|
||||
RID OpenXRInterface::get_color_texture() {
|
||||
if (openxr_api) {
|
||||
return openxr_api->get_color_texture();
|
||||
|
|
@ -1528,6 +1536,8 @@ RID OpenXRInterface::get_vrs_texture() {
|
|||
eye_foci.push_back(openxr_api->get_eye_focus(v, aspect_ratio));
|
||||
}
|
||||
|
||||
xr_vrs.set_vrs_render_region(get_render_region());
|
||||
|
||||
return xr_vrs.make_vrs_texture(target_size, eye_foci);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,6 +183,8 @@ 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 Rect2i get_render_region() override;
|
||||
|
||||
virtual RID get_color_texture() override;
|
||||
virtual RID get_depth_texture() override;
|
||||
virtual RID get_velocity_texture() override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue