1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Metal: Add MetalFX upscaling support

Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
This commit is contained in:
Stuart Carnie
2024-11-24 09:11:43 +11:00
parent bdf625bd54
commit 11dc4f2e5e
36 changed files with 1180 additions and 48 deletions

View File

@@ -429,8 +429,18 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
can_use_effects &= _debug_draw_can_use_effects(debug_draw);
bool can_use_storage = _render_buffers_can_be_storage();
bool use_fsr = fsr && can_use_effects && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR;
bool use_upscaled_texture = rb->has_upscaled_texture() && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR2;
RS::ViewportScaling3DMode scale_mode = rb->get_scaling_3d_mode();
bool use_upscaled_texture = rb->has_upscaled_texture() && (scale_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2 || scale_mode == RS::VIEWPORT_SCALING_3D_MODE_METALFX_TEMPORAL);
SpatialUpscaler *spatial_upscaler = nullptr;
if (can_use_effects) {
if (scale_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) {
spatial_upscaler = fsr;
} else if (scale_mode == RS::VIEWPORT_SCALING_3D_MODE_METALFX_SPATIAL) {
#if METAL_ENABLED
spatial_upscaler = mfx_spatial;
#endif
}
}
RID render_target = rb->get_render_target();
RID color_texture = use_upscaled_texture ? rb->get_upscaled_texture() : rb->get_internal_texture();
@@ -644,9 +654,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(render_target);
RID dest_fb;
bool use_intermediate_fb = use_fsr;
if (use_intermediate_fb) {
// If we use FSR to upscale we need to write our result into an intermediate buffer.
if (spatial_upscaler != nullptr) {
// If we use a spatial upscaler to upscale we need to write our result into an intermediate buffer.
// Note that this is cached so we only create the texture the first time.
RID dest_texture = rb->create_texture(SNAME("Tonemapper"), SNAME("destination"), _render_buffers_get_color_format(), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true);
dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture);
@@ -668,14 +677,16 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
RD::get_singleton()->draw_command_end_label();
}
if (use_fsr) {
RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale");
if (rb.is_valid() && spatial_upscaler) {
spatial_upscaler->ensure_context(rb);
RD::get_singleton()->draw_command_begin_label(spatial_upscaler->get_label());
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RID source_texture = rb->get_texture_slice(SNAME("Tonemapper"), SNAME("destination"), v, 0);
RID dest_texture = texture_storage->render_target_get_rd_texture_slice(render_target, v);
fsr->fsr_upscale(rb, source_texture, dest_texture);
spatial_upscaler->process(rb, source_texture, dest_texture);
}
if (dest_is_msaa_2d) {
@@ -1520,6 +1531,9 @@ void RendererSceneRenderRD::init() {
if (can_use_storage) {
fsr = memnew(RendererRD::FSR);
}
#ifdef METAL_ENABLED
mfx_spatial = memnew(RendererRD::MFXSpatialEffect);
#endif
}
RendererSceneRenderRD::~RendererSceneRenderRD() {
@@ -1548,6 +1562,11 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
if (fsr) {
memdelete(fsr);
}
#ifdef METAL_ENABLED
if (mfx_spatial) {
memdelete(mfx_spatial);
}
#endif
if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) {
RD::get_singleton()->free(sky.sky_scene_state.uniform_set);