Skip 2D rendering if stereo enabled and fix MSAA2D with 3D issue.
This commit is contained in:
parent
f8818f85e6
commit
425e943576
3 changed files with 52 additions and 26 deletions
|
@ -235,7 +235,7 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||
RID render_target = render_buffers->get_render_target();
|
||||
ERR_FAIL_COND_V(render_target.is_null(), RID());
|
||||
RID target_buffer;
|
||||
if (texture_storage->render_target_get_msaa(render_target) == RS::VIEWPORT_MSAA_DISABLED) {
|
||||
if (view_count > 1 || texture_storage->render_target_get_msaa(render_target) == RS::VIEWPORT_MSAA_DISABLED) {
|
||||
target_buffer = texture_storage->render_target_get_rd_texture(render_target);
|
||||
} else {
|
||||
target_buffer = texture_storage->render_target_get_rd_texture_msaa(render_target);
|
||||
|
|
|
@ -351,6 +351,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
RID color_texture = use_upscaled_texture ? rb->get_upscaled_texture() : rb->get_internal_texture();
|
||||
Size2i color_size = use_upscaled_texture ? target_size : rb->get_internal_size();
|
||||
|
||||
bool dest_is_msaa_2d = rb->get_view_count() == 1 && texture_storage->render_target_get_msaa(render_target) != RS::VIEWPORT_MSAA_DISABLED;
|
||||
|
||||
if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes)) {
|
||||
RENDER_TIMESTAMP("Depth of Field");
|
||||
RD::get_singleton()->draw_command_begin_label("DOF");
|
||||
|
@ -567,7 +569,12 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
// If we do a bilinear upscale we just render into our render target and our shader will upscale automatically.
|
||||
// Target size in this case is lying as we never get our real target size communicated.
|
||||
// Bit nasty but...
|
||||
dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target);
|
||||
|
||||
if (dest_is_msaa_2d) {
|
||||
dest_fb = FramebufferCacheRD::get_singleton()->get_cache(texture_storage->render_target_get_rd_texture_msaa(render_target));
|
||||
} else {
|
||||
dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target);
|
||||
}
|
||||
}
|
||||
|
||||
tone_mapper->tonemapper(color_texture, dest_fb, tonemap);
|
||||
|
@ -585,6 +592,13 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
fsr->fsr_upscale(rb, source_texture, dest_texture);
|
||||
}
|
||||
|
||||
if (dest_is_msaa_2d) {
|
||||
// We can't upscale directly into our MSAA buffer so we need to do a copy
|
||||
RID source_texture = texture_storage->render_target_get_rd_texture(render_target);
|
||||
RID dest_fb = FramebufferCacheRD::get_singleton()->get_cache(texture_storage->render_target_get_rd_texture_msaa(render_target));
|
||||
copy_effects->copy_to_fb_rect(source_texture, dest_fb, Rect2i(Point2i(), rb->get_target_size()));
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
||||
|
|
|
@ -116,19 +116,30 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
|
|||
if (p_viewport->size.width == 0 || p_viewport->size.height == 0) {
|
||||
p_viewport->render_buffers.unref();
|
||||
} else {
|
||||
const float EPSILON = 0.0001;
|
||||
float scaling_3d_scale = p_viewport->scaling_3d_scale;
|
||||
RS::ViewportScaling3DMode scaling_3d_mode = p_viewport->scaling_3d_mode;
|
||||
bool upscaler_available = p_viewport->fsr_enabled;
|
||||
|
||||
if ((!upscaler_available || scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_BILINEAR || scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) && scaling_3d_scale >= (1.0 - EPSILON) && scaling_3d_scale <= (1.0 + EPSILON)) {
|
||||
// No 3D scaling on bilinear or FSR? Ignore scaling mode, this just introduces overhead.
|
||||
// - Mobile can't perform optimal path
|
||||
// - FSR does an extra pass (or 2 extra passes if 2D-MSAA is enabled)
|
||||
// Scaling = 1.0 on FSR2 has benefits
|
||||
scaling_3d_scale = 1.0;
|
||||
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
|
||||
}
|
||||
|
||||
bool scaling_3d_is_fsr = (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) || (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2);
|
||||
bool use_taa = p_viewport->use_taa;
|
||||
|
||||
if (scaling_3d_is_fsr && (scaling_3d_scale > 1.0)) {
|
||||
if (scaling_3d_is_fsr && (scaling_3d_scale >= (1.0 + EPSILON))) {
|
||||
// FSR is not designed for downsampling.
|
||||
// Fall back to bilinear scaling.
|
||||
WARN_PRINT_ONCE("FSR 3D resolution scaling is not designed for downsampling. Falling back to bilinear 3D resolution scaling.");
|
||||
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
|
||||
}
|
||||
|
||||
bool upscaler_available = p_viewport->fsr_enabled;
|
||||
if (scaling_3d_is_fsr && !upscaler_available) {
|
||||
// FSR is not actually available.
|
||||
// Fall back to bilinear scaling.
|
||||
|
@ -143,8 +154,8 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
|
|||
use_taa = false;
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int target_width;
|
||||
int target_height;
|
||||
int render_width;
|
||||
int render_height;
|
||||
|
||||
|
@ -152,40 +163,40 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
|
|||
case RS::VIEWPORT_SCALING_3D_MODE_BILINEAR:
|
||||
// Clamp 3D rendering resolution to reasonable values supported on most hardware.
|
||||
// This prevents freezing the engine or outright crashing on lower-end GPUs.
|
||||
width = CLAMP(p_viewport->size.width * scaling_3d_scale, 1, 16384);
|
||||
height = CLAMP(p_viewport->size.height * scaling_3d_scale, 1, 16384);
|
||||
render_width = width;
|
||||
render_height = height;
|
||||
target_width = p_viewport->size.width;
|
||||
target_height = p_viewport->size.height;
|
||||
render_width = CLAMP(target_width * scaling_3d_scale, 1, 16384);
|
||||
render_height = CLAMP(target_height * scaling_3d_scale, 1, 16384);
|
||||
break;
|
||||
case RS::VIEWPORT_SCALING_3D_MODE_FSR:
|
||||
case RS::VIEWPORT_SCALING_3D_MODE_FSR2:
|
||||
width = p_viewport->size.width;
|
||||
height = p_viewport->size.height;
|
||||
render_width = MAX(width * scaling_3d_scale, 1.0); // width / (width * scaling)
|
||||
render_height = MAX(height * scaling_3d_scale, 1.0);
|
||||
target_width = p_viewport->size.width;
|
||||
target_height = p_viewport->size.height;
|
||||
render_width = MAX(target_width * scaling_3d_scale, 1.0); // target_width / (target_width * scaling)
|
||||
render_height = MAX(target_height * scaling_3d_scale, 1.0);
|
||||
break;
|
||||
case RS::VIEWPORT_SCALING_3D_MODE_OFF:
|
||||
width = p_viewport->size.width;
|
||||
height = p_viewport->size.height;
|
||||
render_width = width;
|
||||
render_height = height;
|
||||
target_width = p_viewport->size.width;
|
||||
target_height = p_viewport->size.height;
|
||||
render_width = target_width;
|
||||
render_height = target_height;
|
||||
break;
|
||||
default:
|
||||
// This is an unknown mode.
|
||||
WARN_PRINT_ONCE(vformat("Unknown scaling mode: %d. Disabling 3D resolution scaling.", scaling_3d_mode));
|
||||
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
|
||||
scaling_3d_scale = 1.0;
|
||||
width = p_viewport->size.width;
|
||||
height = p_viewport->size.height;
|
||||
render_width = width;
|
||||
render_height = height;
|
||||
target_width = p_viewport->size.width;
|
||||
target_height = p_viewport->size.height;
|
||||
render_width = target_width;
|
||||
render_height = target_height;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t jitter_phase_count = 0;
|
||||
if (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2) {
|
||||
// Implementation has been copied from ffxFsr2GetJitterPhaseCount.
|
||||
jitter_phase_count = uint32_t(8.0f * pow(float(width) / render_width, 2.0f));
|
||||
jitter_phase_count = uint32_t(8.0f * pow(float(target_width) / render_width, 2.0f));
|
||||
} else if (use_taa) {
|
||||
// Default jitter count for TAA.
|
||||
jitter_phase_count = 16;
|
||||
|
@ -201,7 +212,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
|
|||
RenderSceneBuffersConfiguration rb_config;
|
||||
rb_config.set_render_target(p_viewport->render_target);
|
||||
rb_config.set_internal_size(Size2i(render_width, render_height));
|
||||
rb_config.set_target_size(Size2(width, height));
|
||||
rb_config.set_target_size(Size2(target_width, target_height));
|
||||
rb_config.set_view_count(p_viewport->view_count);
|
||||
rb_config.set_scaling_3d_mode(scaling_3d_mode);
|
||||
rb_config.set_msaa_3d(p_viewport->msaa_3d);
|
||||
|
@ -259,6 +270,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
|
||||
/* Camera should always be BEFORE any other 3D */
|
||||
|
||||
bool can_draw_2d = !p_viewport->disable_2d && p_viewport->view_count == 1; // Stereo rendering does not support 2D, no depth data
|
||||
bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
|
||||
int scenario_canvas_max_layer = 0;
|
||||
bool force_clear_render_target = false;
|
||||
|
@ -272,7 +284,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
if (RSG::scene->is_scenario(p_viewport->scenario)) {
|
||||
RID environment = RSG::scene->scenario_get_environment(p_viewport->scenario);
|
||||
if (RSG::scene->is_environment(environment)) {
|
||||
if (!p_viewport->disable_2d && !viewport_is_environment_disabled(p_viewport)) {
|
||||
if (can_draw_2d && !viewport_is_environment_disabled(p_viewport)) {
|
||||
scenario_draw_canvas_bg = RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS;
|
||||
scenario_canvas_max_layer = RSG::scene->environment_get_canvas_max_layer(environment);
|
||||
} else if (RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS) {
|
||||
|
@ -307,7 +319,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
_draw_3d(p_viewport);
|
||||
}
|
||||
|
||||
if (!p_viewport->disable_2d) {
|
||||
if (can_draw_2d) {
|
||||
RBMap<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map;
|
||||
|
||||
Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y);
|
||||
|
|
Loading…
Reference in a new issue